[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
Mon Aug 25 14:52:18 PDT 2025


https://github.com/aleks-tmb created https://github.com/llvm/llvm-project/pull/155316

None

>From 4a959a972d618d76c2877a8c4256ba9b9a02a446 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

---
 .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 14 ++++++++++++-
 llvm/test/MC/X86/align-branch-fuse-2.s        | 21 +++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/MC/X86/align-branch-fuse-2.s

diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 3cee53a886ebf..4b0adabf57c86 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -520,7 +520,19 @@ void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
   if (!canPadInst(Inst, OS))
     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-fuse-2.s b/llvm/test/MC/X86/align-branch-fuse-2.s
new file mode 100644
index 0000000000000..cfa6bfd0f6f94
--- /dev/null
+++ b/llvm/test/MC/X86/align-branch-fuse-2.s
@@ -0,0 +1,21 @@
+# RUN: llvm-mc -filetype=obj -triple x86_64 -mattr=+prfchw -x86-pad-max-prefix-size=15 --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc %s | llvm-objdump -d --no-show-raw-insn - | FileCheck %s
+
+	.globl	f
+f:
+  	.p2align  5
+	xchgw	%ax, %ax
+	pushq	%rbp
+	pushq	%r14
+	pushq	%rbx
+	subq	$16, %rsp
+	movq	%rdx, %r14
+	movq	%rsi, %rbx
+	cmpl	$0, %gs:104
+	jne	.L_EXIT
+.LBB0_1:
+# CHECK:      20:       testq   %rcx, %rcx
+# CHECK:      23:       je
+	testq	%rcx, %rcx
+	je	.L_EXIT
+.L_EXIT:
+	ret
\ No newline at end of file



More information about the llvm-commits mailing list