[llvm] X86: Mark the dead EFLAGS clobbers in FastISel i1 masking (PR #228044)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 09:02:18 PDT 2026


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/228044

>From dd59143c3c9d539a97eaae3db7ac74add7ed9e40 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 29 Sep 2026 03:27:07 +0200
Subject: [PATCH] X86: Mark the dead EFLAGS clobbers in FastISel i1 masking

Co-authored-by: Claude Opus 5 <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86FastISel.cpp           | 13 ++--
 .../test/CodeGen/X86/fast-isel-dead-eflags.ll | 69 +++++++++++++++++++
 2 files changed, 78 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/fast-isel-dead-eflags.ll

diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp
index 6f482038d3843..c4ca589b2ef6b 100644
--- a/llvm/lib/Target/X86/X86FastISel.cpp
+++ b/llvm/lib/Target/X86/X86FastISel.cpp
@@ -532,9 +532,11 @@ bool X86FastISel::X86FastEmitStore(EVT VT, Register ValReg, X86AddressMode &AM,
   case MVT::i1: {
     // Mask out all but lowest bit.
     Register AndResult = createResultReg(&X86::GR8RegClass);
-    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
-            TII.get(X86::AND8ri), AndResult)
-      .addReg(ValReg).addImm(1);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(X86::AND8ri),
+            AndResult)
+        .addReg(ValReg)
+        .addImm(1)
+        .setOperandDead(3); // implicit-def $eflags
     ValReg = AndResult;
     [[fallthrough]]; // handle i1 as i8.
   }
@@ -1619,7 +1621,10 @@ bool X86FastISel::X86SelectCmp(const Instruction *I) {
             FlagReg2)
         .addImm(SETFOpc[1]);
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(SETFOpc[2]),
-            ResultReg).addReg(FlagReg1).addReg(FlagReg2);
+            ResultReg)
+        .addReg(FlagReg1)
+        .addReg(FlagReg2)
+        .setOperandDead(3); // implicit-def $eflags
     updateValueMap(I, ResultReg);
     return true;
   }
diff --git a/llvm/test/CodeGen/X86/fast-isel-dead-eflags.ll b/llvm/test/CodeGen/X86/fast-isel-dead-eflags.ll
new file mode 100644
index 0000000000000..fb97530059695
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fast-isel-dead-eflags.ll
@@ -0,0 +1,69 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=x86_64-- -O0 -stop-after=finalize-isel < %s | FileCheck %s
+
+; The implicit $eflags def of the i1 store mask is unused.
+define void @store_i1(i1 %a, ptr %p) {
+  ; CHECK-LABEL: name: store_i1
+  ; CHECK: bb.0 (%ir-block.0):
+  ; CHECK-NEXT:   liveins: $edi, $rsi
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64 = COPY $rsi
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gr32 = COPY $edi
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gr8 = COPY [[COPY1]].sub_8bit
+  ; CHECK-NEXT:   [[AND8ri:%[0-9]+]]:gr8 = AND8ri [[COPY2]], 1, implicit-def dead $eflags
+  ; CHECK-NEXT:   MOV8mr [[COPY]], 1, $noreg, 0, $noreg, [[AND8ri]] :: (store (s8) into %ir.p)
+  ; CHECK-NEXT:   RET64
+  store i1 %a, ptr %p
+  ret void
+}
+
+; The implicit $eflags def combining the two fcmp condition codes is unused.
+define float @select_fcmp_oeq(float %a, float %b, float %c, float %d) {
+  ; CHECK-LABEL: name: select_fcmp_oeq
+  ; CHECK: bb.0 (%ir-block.0):
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT:   liveins: $xmm0, $xmm1, $xmm2, $xmm3
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:fr32 = COPY $xmm3
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:fr32 = COPY $xmm2
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:fr32 = COPY $xmm1
+  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:fr32 = COPY $xmm0
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:fr32 = COPY killed [[COPY3]]
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:fr32 = COPY killed [[COPY2]]
+  ; CHECK-NEXT:   [[COPY6:%[0-9]+]]:fr32 = COPY killed [[COPY1]]
+  ; CHECK-NEXT:   [[COPY7:%[0-9]+]]:fr32 = COPY killed [[COPY]]
+  ; CHECK-NEXT:   UCOMISSrr [[COPY4]], [[COPY5]], implicit-def $eflags, implicit $mxcsr
+  ; CHECK-NEXT:   [[SETCCr:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
+  ; CHECK-NEXT:   [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 11, implicit $eflags
+  ; CHECK-NEXT:   [[AND8rr:%[0-9]+]]:gr8 = AND8rr [[SETCCr]], [[SETCCr1]], implicit-def dead $eflags
+  ; CHECK-NEXT:   TEST8ri [[AND8rr]], 1, implicit-def $eflags
+  ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit $eflags
+  ; CHECK-NEXT:   JMP_1 %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.continue:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.4(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   TEST8ri [[AND8rr]], 1, implicit-def $eflags
+  ; CHECK-NEXT:   JCC_1 %bb.4, 5, implicit $eflags
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.continue:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4.continue:
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:fr32 = PHI [[COPY7]], %bb.3, [[COPY6]], %bb.1
+  ; CHECK-NEXT:   $xmm0 = COPY [[PHI]]
+  ; CHECK-NEXT:   RET64 implicit $xmm0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2.exit:
+  ; CHECK-NEXT:   $xmm0 = COPY [[COPY7]]
+  ; CHECK-NEXT:   RET64 implicit $xmm0
+  %cmp = fcmp oeq float %a, %b
+  br i1 %cmp, label %continue, label %exit
+
+continue:
+  %sel = select i1 %cmp, float %c, float %d
+  ret float %sel
+
+exit:
+  ret float %d
+}



More information about the llvm-commits mailing list