From 4b036bee4a35778ce79fc77c4b7a5e7b28e36031 Mon Sep 17 00:00:00 2001 From: Shengchen Kan Date: Thu, 12 Mar 2020 17:13:09 +0800 Subject: [PATCH] [X86] Disable nop padding before instruction following a prefix Reviewers: reames, MaskRay, craig.topper, LuoYuanke, jyknight Reviewed By: LuoYuanke Subscribers: hiraditya, llvm-commits, annita.zhang Tags: #llvm Differential Revision: https://reviews.llvm.org/D76052 --- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 10 +++ test/MC/X86/align-branch-64-prefix.s | 76 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 test/MC/X86/align-branch-64-prefix.s diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 0498f3f2473..b4a86ea65fa 100644 --- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -332,6 +332,11 @@ static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII) { return (BaseReg == X86::RIP); } +/// Check if the instruction is a prefix. +static bool isPrefix(const MCInst &MI, const MCInstrInfo &MCII) { + return X86II::isPrefix(MCII.get(MI.getOpcode()).TSFlags); +} + /// Check if the instruction is valid as the first instruction in macro fusion. static bool isFirstMacroFusibleInst(const MCInst &Inst, const MCInstrInfo &MCII) { @@ -505,6 +510,11 @@ void X86AsmBackend::alignBranchesBegin(MCObjectStreamer &OS, // instruction delay, inserting a nop would change behavior. return; + if (isPrefix(PrevInst, *MCII)) + // If this instruction follows a prefix, inserting a nop would change + // semantic. + return; + if (!isMacroFused(PrevInst, Inst)) // Macro fusion doesn't happen indeed, clear the pending. PendingBoundaryAlign = nullptr; diff --git a/test/MC/X86/align-branch-64-prefix.s b/test/MC/X86/align-branch-64-prefix.s new file mode 100644 index 00000000000..70efefeeb37 --- /dev/null +++ b/test/MC/X86/align-branch-64-prefix.s @@ -0,0 +1,76 @@ + # RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu --x86-align-branch-boundary=32 --x86-align-branch=jmp+call %s | llvm-objdump -d --no-show-raw-insn - | FileCheck %s + + # Exercise cases where prefixes are specified for instructions to be aligned + # and thus can't add a nop in between without changing semantic. + + .text + + # CHECK: 1d: int3 + # CHECK: 1e: jmp + # CHECK: 24: int3 + .p2align 5 + .rept 30 + int3 + .endr + CS + jmp baz + int3 + + # CHECK: 5d: int3 + # CHECK: 5e: jmp + # CHECK: 64: int3 + .p2align 5 + .rept 30 + int3 + .endr + GS + jmp baz + int3 + + # CHECK: 9d: int3 + # CHECK: 9e: call + # CHECK: a6: int3 + .p2align 5 + .rept 30 + int3 + .endr + data16 + call *___tls_get_addr@GOT(%ecx) + int3 + + # CHECK: de: lock + # CHECK: df: jmp + # CHECK: e4: int3 + .p2align 5 + .rept 30 + int3 + .endr + lock + jmp baz + int3 + + # CHECK: 11d: int3 + # CHECK: 11e: jmp + # CHECK: 124: int3 + .p2align 5 + .rept 30 + int3 + .endr + rex64 + jmp baz + int3 + + # CHECK: 15d: int3 + # CHECK: 15e: {{.*}} jmp + # CHECK: 164: int3 + .p2align 5 + .rept 30 + int3 + .endr + xacquire + jmp baz + int3 + + .section ".text.other" +bar: + retq