[llvm] X86: Preserve the dead flag clobber when expanding dynamic allocas (PR #227702)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 06:18:44 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

The DYN_ALLOCA pseudos clobber EFLAGS, so propagate the pseudo's dead
flag to the stack adjustment they expand to.

Co-Authored-By: Claude Opus 5 <noreply@<!-- -->anthropic.com>

---
Full diff: https://github.com/llvm/llvm-project/pull/227702.diff


2 Files Affected:

- (modified) llvm/lib/Target/X86/X86DynAllocaExpander.cpp (+15-7) 
- (added) llvm/test/CodeGen/X86/dyn-alloca-expander-dead-eflags.ll (+51) 


``````````diff
diff --git a/llvm/lib/Target/X86/X86DynAllocaExpander.cpp b/llvm/lib/Target/X86/X86DynAllocaExpander.cpp
index 62b70bdd14b31..28212258fbe09 100644
--- a/llvm/lib/Target/X86/X86DynAllocaExpander.cpp
+++ b/llvm/lib/Target/X86/X86DynAllocaExpander.cpp
@@ -225,6 +225,7 @@ void X86DynAllocaExpander::lower(MachineInstr *MI, Lowering L) {
   // 32-bit alloca.
   bool Is64Bit = STI->is64Bit();
   bool Is64BitAlloca = MI->getOpcode() == X86::DYN_ALLOCA_64;
+  bool DeadEFLAGS = MI->registerDefIsDead(X86::EFLAGS, /*TRI=*/nullptr);
   assert(SlotSize == 4 || SlotSize == 8);
 
   std::optional<MachineFunction::DebugInstrOperandPair> InstrNum;
@@ -257,9 +258,12 @@ void X86DynAllocaExpander::lower(MachineInstr *MI, Lowering L) {
           .addReg(RegA, RegState::Undef);
     } else {
       // Sub.
-      BuildMI(*MBB, I, DL, TII->get(getSubOpcode(Is64BitAlloca)), StackPtr)
-          .addReg(StackPtr)
-          .addImm(Amount);
+      MachineInstrBuilder Sub =
+          BuildMI(*MBB, I, DL, TII->get(getSubOpcode(Is64BitAlloca)), StackPtr)
+              .addReg(StackPtr)
+              .addImm(Amount);
+      if (DeadEFLAGS)
+        Sub.setOperandDead(3); // implicit-def $eflags
     }
     break;
   case Probe:
@@ -274,10 +278,14 @@ void X86DynAllocaExpander::lower(MachineInstr *MI, Lowering L) {
                                               /*InProlog=*/false, InstrNum);
     } else {
       // Sub
-      BuildMI(*MBB, I, DL,
-              TII->get(Is64BitAlloca ? X86::SUB64rr : X86::SUB32rr), StackPtr)
-          .addReg(StackPtr)
-          .addReg(MI->getOperand(0).getReg());
+      MachineInstrBuilder Sub =
+          BuildMI(*MBB, I, DL,
+                  TII->get(Is64BitAlloca ? X86::SUB64rr : X86::SUB32rr),
+                  StackPtr)
+              .addReg(StackPtr)
+              .addReg(MI->getOperand(0).getReg());
+      if (DeadEFLAGS)
+        Sub.setOperandDead(3); // implicit-def $eflags
     }
     break;
   }
diff --git a/llvm/test/CodeGen/X86/dyn-alloca-expander-dead-eflags.ll b/llvm/test/CodeGen/X86/dyn-alloca-expander-dead-eflags.ll
new file mode 100644
index 0000000000000..bfa744a16f75c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/dyn-alloca-expander-dead-eflags.ll
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=i686-pc-win32 -stop-after=x86-dyn-alloca-expander -o - %s | FileCheck %s
+
+; The expanded stack adjustment inherits the dead flag clobber of the pseudo.
+
+define void @sub() {
+  ; CHECK-LABEL: name: sub
+  ; CHECK: bb.0.entry:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.bb:
+  ; CHECK-NEXT:   ADJCALLSTACKDOWN32 0, 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
+  ; CHECK-NEXT:   PUSH32r undef $eax, implicit-def $esp, implicit $esp
+  ; CHECK-NEXT:   $esp = SUB32ri $esp, 1020, implicit-def dead $eflags
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr32 = COPY $esp
+  ; CHECK-NEXT:   ADJCALLSTACKUP32 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
+  ; CHECK-NEXT:   ADJCALLSTACKDOWN32 4, 0, 4, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
+  ; CHECK-NEXT:   PUSH32r [[COPY]], implicit-def $esp, implicit $esp :: (store (s32) into stack)
+  ; CHECK-NEXT:   CALLpcrel32 @use, csr_32, implicit $esp, implicit $ssp, implicit-def $esp, implicit-def $ssp
+  ; CHECK-NEXT:   ADJCALLSTACKUP32 4, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
+  ; CHECK-NEXT:   RET 0
+entry:
+  br label %bb
+
+bb:
+  %a = alloca [1024 x i8]
+  call void @use(ptr %a)
+  ret void
+}
+
+define void @sub_dynamic(i32 %n) "no-stack-arg-probe" {
+  ; CHECK-LABEL: name: sub_dynamic
+  ; CHECK: bb.0 (%ir-block.0):
+  ; CHECK-NEXT:   [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %fixed-stack.0)
+  ; CHECK-NEXT:   ADJCALLSTACKDOWN32 0, 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
+  ; CHECK-NEXT:   [[ADD32ri:%[0-9]+]]:gr32 = nuw ADD32ri [[MOV32rm]], 3, implicit-def dead $eflags
+  ; CHECK-NEXT:   [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[ADD32ri]], -4, implicit-def dead $eflags
+  ; CHECK-NEXT:   $esp = SUB32rr $esp, [[AND32ri]], implicit-def dead $eflags
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr32 = COPY $esp
+  ; CHECK-NEXT:   ADJCALLSTACKUP32 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
+  ; CHECK-NEXT:   ADJCALLSTACKDOWN32 4, 0, 4, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
+  ; CHECK-NEXT:   PUSH32r [[COPY]], implicit-def $esp, implicit $esp :: (store (s32) into stack)
+  ; CHECK-NEXT:   CALLpcrel32 @use, csr_32, implicit $esp, implicit $ssp, implicit-def $esp, implicit-def $ssp
+  ; CHECK-NEXT:   ADJCALLSTACKUP32 4, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
+  ; CHECK-NEXT:   RET 0
+  %a = alloca i8, i32 %n
+  call void @use(ptr %a)
+  ret void
+}
+
+declare void @use(ptr)

``````````

</details>


https://github.com/llvm/llvm-project/pull/227702


More information about the llvm-commits mailing list