Skip to content

Commit e6f1dd4

Browse files
committed
[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
1 parent bf0cc6b commit e6f1dd4

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII) {
332332
return (BaseReg == X86::RIP);
333333
}
334334

335+
/// Check if the instruction is a prefix.
336+
static bool isPrefix(const MCInst &MI, const MCInstrInfo &MCII) {
337+
return X86II::isPrefix(MCII.get(MI.getOpcode()).TSFlags);
338+
}
339+
335340
/// Check if the instruction is valid as the first instruction in macro fusion.
336341
static bool isFirstMacroFusibleInst(const MCInst &Inst,
337342
const MCInstrInfo &MCII) {
@@ -505,6 +510,11 @@ void X86AsmBackend::alignBranchesBegin(MCObjectStreamer &OS,
505510
// instruction delay, inserting a nop would change behavior.
506511
return;
507512

513+
if (isPrefix(PrevInst, *MCII))
514+
// If this instruction follows a prefix, inserting a nop would change
515+
// semantic.
516+
return;
517+
508518
if (!isMacroFused(PrevInst, Inst))
509519
// Macro fusion doesn't happen indeed, clear the pending.
510520
PendingBoundaryAlign = nullptr;
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# 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
2+
3+
# Exercise cases where prefixes are specified for instructions to be aligned
4+
# and thus can't add a nop in between without changing semantic.
5+
6+
.text
7+
8+
# CHECK: 1d: int3
9+
# CHECK: 1e: jmp
10+
# CHECK: 24: int3
11+
.p2align 5
12+
.rept 30
13+
int3
14+
.endr
15+
CS
16+
jmp baz
17+
int3
18+
19+
# CHECK: 5d: int3
20+
# CHECK: 5e: jmp
21+
# CHECK: 64: int3
22+
.p2align 5
23+
.rept 30
24+
int3
25+
.endr
26+
GS
27+
jmp baz
28+
int3
29+
30+
# CHECK: 9d: int3
31+
# CHECK: 9e: call
32+
# CHECK: a6: int3
33+
.p2align 5
34+
.rept 30
35+
int3
36+
.endr
37+
data16
38+
call *___tls_get_addr@GOT(%ecx)
39+
int3
40+
41+
# CHECK: de: lock
42+
# CHECK: df: jmp
43+
# CHECK: e4: int3
44+
.p2align 5
45+
.rept 30
46+
int3
47+
.endr
48+
lock
49+
jmp baz
50+
int3
51+
52+
# CHECK: 11d: int3
53+
# CHECK: 11e: jmp
54+
# CHECK: 124: int3
55+
.p2align 5
56+
.rept 30
57+
int3
58+
.endr
59+
rex64
60+
jmp baz
61+
int3
62+
63+
# CHECK: 15d: int3
64+
# CHECK: 15e: {{.*}} jmp
65+
# CHECK: 164: int3
66+
.p2align 5
67+
.rept 30
68+
int3
69+
.endr
70+
xacquire
71+
jmp baz
72+
int3
73+
74+
.section ".text.other"
75+
bar:
76+
retq

0 commit comments

Comments
 (0)