Skip to content

Commit fd9e484

Browse files
committed
[X86] Fix incorrect NOP insertion between fused instructions that breaks macro fusion
Fixes #155045
1 parent c0f7091 commit fd9e484

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,16 @@ void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
485485
if (!CanPadInst)
486486
return;
487487

488-
if (PendingBA && PendingBA->getNext() == OS.getCurrentFragment()) {
488+
if (PendingBA) {
489+
auto *NextFragment = PendingBA->getNext();
490+
assert(NextFragment && "NextFragment should not be null");
491+
if (NextFragment == OS.getCurrentFragment())
492+
return;
493+
// We eagerly create an empty fragment when inserting a fragment
494+
// with a variable-size tail.
495+
if (NextFragment->getKind() == MCFragment::FT_Relaxable)
496+
return;
497+
489498
// Macro fusion actually happens and there is no other fragment inserted
490499
// after the previous instruction.
491500
//

llvm/test/MC/X86/align-branch-fused.s

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
# RUN: llvm-mc -filetype=obj -triple x86_64 --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc %s | llvm-objdump -d --no-show-raw-insn - | FileCheck %s
1+
# RUN: rm -rf %t && split-file %s %t && cd %t
2+
# RUN: llvm-mc -filetype=obj -triple x86_64 --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc foo.s | llvm-objdump -d --no-show-raw-insn - | FileCheck foo.s
3+
# RUN: llvm-mc -filetype=obj -triple x86_64 --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc -x86-pad-max-prefix-size=1 bar.s | llvm-objdump -d --no-show-raw-insn - | FileCheck bar.s
24

35
# Exercise cases where fused instructions need to be aligned.
46

7+
#--- foo.s
58
.text
69
.globl foo
710
foo:
@@ -40,3 +43,18 @@ foo:
4043
cmp %rax, %rbp
4144
jne foo
4245
int3
46+
47+
# Exercise the case where fused instructions need to be aligned,
48+
# ensuring fusion is not broken by a NOP
49+
50+
#--- bar.s
51+
.text
52+
.globl bar
53+
bar:
54+
.nops 27
55+
# CHECK: 20: testq %rcx, %rcx
56+
# CHECK: 23: je
57+
testq %rcx, %rcx
58+
je .EXIT
59+
.EXIT:
60+
ret

0 commit comments

Comments
 (0)