https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/208052
>From 32e27201f4ef6ab67659a5751b2314c6e6b45603 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Tue, 7 Jul 2026 17:04:45 +0200 Subject: [PATCH 1/3] PPC: Fix extsw elimination when the input reads a subregister The EXTSW_32_64 sign-extend elimination previously assumed its input was a full register value. It would then try using that value as the source of the new (unnecessary) INSERT_SUBREG. The new test would then hit this verifier error: ``` bb.0: liveins: $x3 %0:g8rc = COPY killed $x3 %1:g8rc = RLDICL killed %0:g8rc, 0, 33 %3:g8rc = IMPLICIT_DEF %2:g8rc = INSERT_SUBREG %3:g8rc(tied-def 0), %1:g8rc, %subreg.sub_32 $x3 = COPY killed %2:g8rc BLR8 implicit $lr8, implicit $rm, implicit killed $x3 *** Bad machine code: INSERT_SUBREG expected inserted value to have equal or lesser size than the subreg it was inserted into *** - function: extsw_elim_subreg_input - basic block: %bb.0 (0x13c834070) - instruction: %2:g8rc = INSERT_SUBREG %3:g8rc(tied-def 0), %1:g8rc, %subreg.sub_32 ``` This avoids verifier error regressions in a future change. Co-Authored-By: Claude <[email protected]> (Claude Opus 4.8, claude-opus-4-8) --- llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 39 +++++++++++++------ .../peephole-elim-extsw-subreg-input.mir | 30 ++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/peephole-elim-extsw-subreg-input.mir diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index 71a7994750c56..ea56e71eb789a 100644 --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1016,11 +1016,14 @@ bool PPCMIPeephole::simplifyCode() { if (!NarrowReg.isVirtual()) break; + unsigned NarrowSubReg = MI.getOperand(1).getSubReg(); + MachineInstr *SrcMI = MRI->getVRegDef(NarrowReg); unsigned SrcOpcode = SrcMI->getOpcode(); // If we've used a zero-extending load that we will sign-extend, // just do a sign-extending load. - if (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX) { + if (!NarrowSubReg && + (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX)) { if (!MRI->hasOneNonDBGUse(SrcMI->getOperand(0).getReg())) break; @@ -1088,18 +1091,30 @@ bool PPCMIPeephole::simplifyCode() { // chain used to deduce sign extension to eliminate the 'extsw' will // need to be promoted to 64-bit pseudo instructions when the 'extsw' // is eliminated. - TII->promoteInstr32To64ForElimEXTSW(NarrowReg, MRI, 0, LV); - LLVM_DEBUG(dbgs() << "Removing redundant sign-extension\n"); - Register TmpReg = - MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass); - BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::IMPLICIT_DEF), - TmpReg); - BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::INSERT_SUBREG), - MI.getOperand(0).getReg()) - .addReg(TmpReg) - .addReg(NarrowReg) - .addImm(PPC::sub_32); + + if (NarrowSubReg) { + // The input reads a subregister of a wider register which we can + // use directly. + assert(NarrowSubReg == PPC::sub_32 && + "EXTSW_32_64 input must read the sub_32 subregister"); + BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::COPY), + MI.getOperand(0).getReg()) + .addReg(NarrowReg); + addRegToUpdate(NarrowReg); + } else { + TII->promoteInstr32To64ForElimEXTSW(NarrowReg, MRI, 0, LV); + + Register TmpReg = + MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass); + BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::IMPLICIT_DEF), + TmpReg); + BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::INSERT_SUBREG), + MI.getOperand(0).getReg()) + .addReg(TmpReg) + .addReg(NarrowReg) + .addImm(PPC::sub_32); + } ToErase = &MI; Simplified = true; NumEliminatedSExt++; diff --git a/llvm/test/CodeGen/PowerPC/peephole-elim-extsw-subreg-input.mir b/llvm/test/CodeGen/PowerPC/peephole-elim-extsw-subreg-input.mir new file mode 100644 index 0000000000000..86caff368f3f2 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/peephole-elim-extsw-subreg-input.mir @@ -0,0 +1,30 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -run-pass=ppc-mi-peepholes -ppc-eliminate-signext -verify-machineinstrs -o - %s | FileCheck %s + +# When the EXTSW_32_64 input reads the sub_32 subregister of a 64-bit register +# that is already sign-extended (here RLDICL with MB >= 33), the high 32 bits of +# that register already hold the sign extension of the low word, so the result +# of the sign-extend is the whole 64-bit register. Eliminate the EXTSW by +# copying that register directly rather than building an INSERT_SUBREG that would +# use the full register where a 32-bit register is required. + +--- +name: extsw_elim_subreg_input +tracksRegLiveness: true +body: | + bb.0: + liveins: $x3 + ; CHECK-LABEL: name: extsw_elim_subreg_input + ; CHECK: liveins: $x3 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:g8rc = COPY killed $x3 + ; CHECK-NEXT: [[RLDICL:%[0-9]+]]:g8rc = RLDICL killed [[COPY]], 0, 33 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:g8rc = COPY killed [[RLDICL]] + ; CHECK-NEXT: $x3 = COPY killed [[COPY1]] + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 + %0:g8rc = COPY $x3 + %1:g8rc = RLDICL %0, 0, 33 + %2:g8rc = EXTSW_32_64 %1.sub_32 + $x3 = COPY %2 + BLR8 implicit $lr8, implicit $rm, implicit $x3 +... >From 01992e6ce932b769f42fe9077ed56a39f5706a9b Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Tue, 21 Jul 2026 20:03:15 +0200 Subject: [PATCH 2/3] Remove NarrowSubReg check --- llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index ea56e71eb789a..5372cf8044d56 100644 --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1022,8 +1022,7 @@ bool PPCMIPeephole::simplifyCode() { unsigned SrcOpcode = SrcMI->getOpcode(); // If we've used a zero-extending load that we will sign-extend, // just do a sign-extending load. - if (!NarrowSubReg && - (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX)) { + if ((SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX)) { if (!MRI->hasOneNonDBGUse(SrcMI->getOperand(0).getReg())) break; >From 3ec282d981362bca39e57f20e500faace7be7751 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Sun, 20 Sep 2026 10:57:45 +0200 Subject: [PATCH 3/3] review comments --- llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index 5372cf8044d56..a7c627915a7ca 100644 --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1016,13 +1016,11 @@ bool PPCMIPeephole::simplifyCode() { if (!NarrowReg.isVirtual()) break; - unsigned NarrowSubReg = MI.getOperand(1).getSubReg(); - MachineInstr *SrcMI = MRI->getVRegDef(NarrowReg); unsigned SrcOpcode = SrcMI->getOpcode(); // If we've used a zero-extending load that we will sign-extend, // just do a sign-extending load. - if ((SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX)) { + if (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX) { if (!MRI->hasOneNonDBGUse(SrcMI->getOperand(0).getReg())) break; @@ -1092,9 +1090,10 @@ bool PPCMIPeephole::simplifyCode() { // is eliminated. LLVM_DEBUG(dbgs() << "Removing redundant sign-extension\n"); + unsigned NarrowSubReg = MI.getOperand(1).getSubReg(); if (NarrowSubReg) { // The input reads a subregister of a wider register which we can - // use directly. + // use directly by dropping the subreg. assert(NarrowSubReg == PPC::sub_32 && "EXTSW_32_64 input must read the sub_32 subregister"); BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::COPY), _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
