[llvm] 804efba - PowerPC: Promote 32-bit ops to 64-bit in place for EXTSW elimination (#229054)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 7 03:05:46 PDT 2026


Author: Matt Arsenault
Date: 2026-10-07T10:05:38Z
New Revision: 804efba8a498197855111bd290728aac4cfdbc21

URL: https://github.com/llvm/llvm-project/commit/804efba8a498197855111bd290728aac4cfdbc21
DIFF: https://github.com/llvm/llvm-project/commit/804efba8a498197855111bd290728aac4cfdbc21.diff

LOG: PowerPC: Promote 32-bit ops to 64-bit in place for EXTSW elimination (#229054)

promoteInstr32To64ForElimEXTSW rebuilt a 32-bit instruction as its
64-bit counterpart (e.g. SRAWI -> SRAWI8) with BuildMI, which adds the opcode's
implicit defs, and then copied over the original operands, which already carry them. 
This produced duplicate, inconsistent defs:

%8:g8rc = SRAWI8 killed %7, 8, implicit-def $carry, implicit-def dead $carry

The 32-bit and 64-bit opcodes have the same operand layout, so mutate the 
original instruction with setDesc instead. This keeps the original implicit defs 
with their dead flags, and also preserves the memoperands and MI flags
that rebuilding dropped. The preserved memoperand on a promoted LHA8 allows
the scheduler to reorder it with spills in aix-cc-abi.ll.

Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
    llvm/test/CodeGen/PowerPC/aix-cc-abi.ll
    llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir
    llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 67b8f481dfcad..80b7dcf2efc8b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -5484,7 +5484,6 @@ void PPCInstrInfo::promoteInstr32To64ForElimEXTSW(const Register &Reg,
   // PPC::GRCRegClass or PPC::GPRC_and_GPRC_NOR0RegClass, we need to promote
   // the operand to PPC::G8CRegClass or PPC::G8RC_and_G8RC_NOR0RegClass,
   // respectively.
-  SmallVector<Register> PromoteRegs(MI->getNumOperands());
   for (unsigned i = 1; i < MI->getNumOperands(); i++) {
     MachineOperand &Operand = MI->getOperand(i);
     if (!Operand.isReg())
@@ -5507,30 +5506,20 @@ void PPCInstrInfo::promoteInstr32To64ForElimEXTSW(const Register &Reg,
           .addReg(TmpReg)
           .addReg(OperandReg)
           .addImm(PPC::sub_32);
-      PromoteRegs[i] = DstTmpReg;
+      Operand.setReg(DstTmpReg);
+      Operand.setIsKill();
     }
   }
 
   Register NewDefinedReg = MRI->createVirtualRegister(NewRC);
-
-  BuildMI(*MBB, MI, DL, get(NewOpcode), NewDefinedReg);
-  MachineBasicBlock::instr_iterator Iter(MI);
-  --Iter;
-  MachineInstrBuilder MIBuilder(*Iter->getMF(), Iter);
-  for (unsigned i = 1; i < MI->getNumOperands(); i++) {
-    if (PromoteRegs[i])
-      MIBuilder.addReg(PromoteRegs[i], RegState::Kill);
-    else
-      Iter->addOperand(MI->getOperand(i));
-  }
-
-  MI->eraseFromParent();
+  MI->setDesc(MCID);
+  MI->getOperand(0).setReg(NewDefinedReg);
 
   // A defined register may be used by other instructions that are 32-bit.
   // After the defined register is promoted to 64-bit for the promoted
   // instruction, we need to demote the 64-bit defined register back to a
   // 32-bit register
-  BuildMI(*MBB, ++Iter, DL, get(PPC::COPY), SrcReg)
+  BuildMI(*MBB, std::next(MI->getIterator()), DL, get(PPC::COPY), SrcReg)
       .addReg(NewDefinedReg, RegState::Kill, PPC::sub_32);
 }
 

diff  --git a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll
index 6838d61fff8de..6a3ece77cf367 100644
--- a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll
@@ -1238,30 +1238,30 @@ define i64 @test_ints_stack(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6
 ; ASM64PWR4-LABEL: test_ints_stack:
 ; ASM64PWR4:       # %bb.0: # %entry
 ; ASM64PWR4-NEXT:    add 3, 3, 4
-; ASM64PWR4-NEXT:    std 31, -8(1) # 8-byte Folded Spill
+; ASM64PWR4-NEXT:    lha 0, 126(1)
 ; ASM64PWR4-NEXT:    add 3, 3, 5
 ; ASM64PWR4-NEXT:    add 3, 3, 6
 ; ASM64PWR4-NEXT:    add 3, 3, 7
-; ASM64PWR4-NEXT:    std 2, -16(1) # 8-byte Folded Spill
 ; ASM64PWR4-NEXT:    add 3, 3, 8
-; ASM64PWR4-NEXT:    add 3, 3, 9
 ; ASM64PWR4-NEXT:    ld 6, 112(1)
+; ASM64PWR4-NEXT:    add 3, 3, 9
 ; ASM64PWR4-NEXT:    add 3, 3, 10
 ; ASM64PWR4-NEXT:    extsw 3, 3
-; ASM64PWR4-NEXT:    lha 0, 126(1)
+; ASM64PWR4-NEXT:    lbz 5, 135(1)
 ; ASM64PWR4-NEXT:    add 3, 3, 6
 ; ASM64PWR4-NEXT:    add 3, 3, 0
-; ASM64PWR4-NEXT:    lbz 5, 135(1)
 ; ASM64PWR4-NEXT:    lwz 7, 140(1)
 ; ASM64PWR4-NEXT:    add 3, 3, 5
 ; ASM64PWR4-NEXT:    lwa 12, 148(1)
 ; ASM64PWR4-NEXT:    add 3, 3, 7
 ; ASM64PWR4-NEXT:    add 3, 3, 12
+; ASM64PWR4-NEXT:    std 31, -8(1) # 8-byte Folded Spill
 ; ASM64PWR4-NEXT:    ld 31, 152(1)
 ; ASM64PWR4-NEXT:    lbz 5, 167(1)
 ; ASM64PWR4-NEXT:    add 3, 3, 31
-; ASM64PWR4-NEXT:    lwa 11, 172(1)
+; ASM64PWR4-NEXT:    std 2, -16(1) # 8-byte Folded Spill
 ; ASM64PWR4-NEXT:    add 3, 3, 5
+; ASM64PWR4-NEXT:    lwa 11, 172(1)
 ; ASM64PWR4-NEXT:    add 3, 3, 11
 ; ASM64PWR4-NEXT:    lbz 2, 183(1)
 ; ASM64PWR4-NEXT:    lbz 6, 191(1)

diff  --git a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir
index b9ca97a8bd68f..01e87731fc3aa 100644
--- a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir
+++ b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir
@@ -712,20 +712,20 @@ frameInfo:
   hasMustTailInVarArgFunc: false
   savePoint:       []
   restorePoint:    []
-fixedStack:      
-stack:           
-constants:       
+fixedStack:
+stack:
+constants:
 body:             |
   bb.0.entry:
     liveins: $x3, $x4
-  
+
     %1 = COPY $x4
     %0 = COPY $x3
     %2 = LI 48
     %3 = COPY %0.sub_32
     %4 = SRAW killed %3, killed %2, implicit-def dead $carry
     ; CHECK: LI 48
-    ; CHECK: SRAW8 killed %7, killed %9, implicit-def $carry, implicit-def dead $carry 
+    ; CHECK: SRAW8 killed %7, killed %9, implicit-def dead $carry
     ; CHECK-LATE: sraw 3, 3, 4
     %5 = EXTSW_32_64 killed %4
     $x3 = COPY %5
@@ -782,7 +782,7 @@ body:             |
     %2 = LI 80
     %3 = COPY %0.sub_32
     %4 = SRAW_rec killed %3, %2, implicit-def dead $carry, implicit-def $cr0
-    ; CHECK: SRAW8_rec killed %10, killed %12, implicit-def $carry, implicit-def $cr0, implicit-def dead $carry, implicit-def $cr0
+    ; CHECK: SRAW8_rec killed %10, killed %12, implicit-def dead $carry, implicit-def $cr0
     ; CHECK-LATE: sraw. 3, 3, 4
     %5 = COPY killed $cr0
     %6 = ISEL %2, %4, %5.sub_eq

diff  --git a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
index 3462bbf3a7e9e..bee9637b4f570 100644
--- a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
+++ b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
@@ -5038,8 +5038,7 @@ body:             |
     %4 = SRAW killed %3, killed %2, implicit-def dead $carry
     ; CHECK:      %6:g8rc = IMPLICIT_DEF
     ; CHECK-NEXT: %7:g8rc = INSERT_SUBREG %6, %3, %subreg.sub_32
-
-    ; CHECK-NEXT: %8:g8rc = SRAWI8 killed %7, 15, implicit-def $carry, implicit-def dead $carry
+    ; CHECK-NEXT: %8:g8rc = SRAWI8 killed %7, 15, implicit-def dead $carry
     ; CHECK-NEXT: %4:gprc = COPY killed %8.sub_32
     ; CHECK-LATE: srawi 3, 3, 15
     %5 = EXTSW_32_64 killed %4
@@ -5097,7 +5096,7 @@ body:             |
     %2 = LI 8
     %3 = COPY %0.sub_32
     %4 = SRAW_rec killed %3, %2, implicit-def dead $carry, implicit-def $cr0
-    ; CHECK:  %11:g8rc = SRAWI8_rec killed %10, 8, implicit-def $carry, implicit-def $cr0, implicit-def dead $carry, implicit-def $cr0
+    ; CHECK:  %11:g8rc = SRAWI8_rec killed %10, 8, implicit-def dead $carry, implicit-def $cr0
     ; CHECK-LATE: srawi. 3, 3, 8
     %5 = COPY killed $cr0
     %6 = ISEL %2, %4, %5.sub_eq


        


More information about the llvm-commits mailing list