[llvm] [X86] Fix incorrect NOP insertion between fused instructions that breaks macro fusion (PR #155316)
Aleksandr Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 27 02:12:14 PDT 2025
https://github.com/aleks-tmb updated https://github.com/llvm/llvm-project/pull/155316
>From d18a854d72aeea1a8ea0d1bb63aa497f15fcc65a Mon Sep 17 00:00:00 2001
From: Aleksander Popov <a.popov.tmb at gmail.com>
Date: Mon, 25 Aug 2025 23:50:49 +0200
Subject: [PATCH] [X86] Fix incorrect NOP insertion between fused instructions
that breaks macro fusion
Fixes #155045
---
.../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 12 ++++++++++-
llvm/test/MC/X86/align-branch-fused.s | 20 ++++++++++++++++++-
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 56a4cc3d65c2e..ce2ff75a8f77d 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -485,7 +485,17 @@ void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
if (!CanPadInst)
return;
- if (PendingBA && PendingBA->getNext() == OS.getCurrentFragment()) {
+ if (PendingBA) {
+ auto *NextFragment = PendingBA->getNext();
+ assert(NextFragment && "NextFragment should not be null");
+ if (NextFragment == OS.getCurrentFragment())
+ return;
+ // We eagerly create an empty fragment when inserting a fragment
+ // with a variable-size tail.
+ if (NextFragment->getKind() == MCFragment::FT_Relaxable &&
+ NextFragment->getNext() == OS.getCurrentFragment())
+ return;
+
// Macro fusion actually happens and there is no other fragment inserted
// after the previous instruction.
//
diff --git a/llvm/test/MC/X86/align-branch-fused.s b/llvm/test/MC/X86/align-branch-fused.s
index 7530967a890c6..5b4a144e30921 100644
--- a/llvm/test/MC/X86/align-branch-fused.s
+++ b/llvm/test/MC/X86/align-branch-fused.s
@@ -1,7 +1,10 @@
-# 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
+# RUN: rm -rf %t && split-file %s %t && cd %t
+# 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
+# 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
# Exercise cases where fused instructions need to be aligned.
+#--- foo.s
.text
.globl foo
foo:
@@ -40,3 +43,18 @@ foo:
cmp %rax, %rbp
jne foo
int3
+
+# Exercise the case where fused instructions need to be aligned,
+# ensuring fusion is not broken by a NOP
+
+#--- bar.s
+ .text
+ .globl bar
+bar:
+ .nops 27
+# CHECK: 20: testq %rcx, %rcx
+# CHECK: 23: je
+ testq %rcx, %rcx
+ je .EXIT
+.EXIT:
+ ret
More information about the llvm-commits
mailing list