diff --git a/llvm/lib/Target/PowerPC/P10InstrResources.td b/llvm/lib/Target/PowerPC/P10InstrResources.td index 32cebb65cb56..92af04a4cff2 100644 --- a/llvm/lib/Target/PowerPC/P10InstrResources.td +++ b/llvm/lib/Target/PowerPC/P10InstrResources.td @@ -825,7 +825,8 @@ def : InstRW<[P10W_F2_4C, P10W_DISP_ANY, P10F2_Read, P10F2_Read, P10F2_Read], def : InstRW<[P10W_F2_4C, P10W_DISP_EVEN, P10W_DISP_ANY, P10F2_Read], (instrs SRADI_rec, - SRAWI_rec + SRAWI_rec, + SRAWI8_rec )>; // Single crack instructions @@ -833,7 +834,8 @@ def : InstRW<[P10W_F2_4C, P10W_DISP_EVEN, P10W_DISP_ANY, P10F2_Read], def : InstRW<[P10W_F2_4C, P10W_DISP_EVEN, P10W_DISP_ANY, P10F2_Read, P10F2_Read], (instrs SRAD_rec, - SRAW_rec + SRAW_rec, + SRAW8_rec )>; // 2-way crack instructions @@ -926,7 +928,7 @@ def : InstRW<[P10W_FX_3C, P10W_DISP_ANY, P10FX_Read], SETNBC, SETNBC8, SETNBCR, SETNBCR8, SRADI, SRADI_32, - SRAWI, + SRAWI, SRAWI8, SUBFIC, SUBFIC8, SUBFME, SUBFME8, SUBFME8O, SUBFMEO, @@ -1008,7 +1010,7 @@ def : InstRW<[P10W_FX_3C, P10W_DISP_ANY, P10FX_Read, P10FX_Read], SLD, SLW, SLW8, SRAD, - SRAW, + SRAW, SRAW8, SRD, SRW, SRW8, SUBF, SUBF8, diff --git a/llvm/lib/Target/PowerPC/P9InstrResources.td b/llvm/lib/Target/PowerPC/P9InstrResources.td index 395999c7242a..801ae83cd07c 100644 --- a/llvm/lib/Target/PowerPC/P9InstrResources.td +++ b/llvm/lib/Target/PowerPC/P9InstrResources.td @@ -189,7 +189,8 @@ def : InstRW<[P9_ALU_2C, IP_EXEC_1C, DISP_3SLOTS_1C], (instregex "F(N)?ABS(D|S)$"), (instregex "FNEG(D|S)$"), (instregex "FCPSGN(D|S)$"), - (instregex "SRAW(I)?$"), + (instregex "SRAW(8)?$"), + (instregex "SRAWI(8)?$"), (instregex "ISEL(8)?$"), RLDIMI, XSIEXPDP, @@ -1091,7 +1092,8 @@ def : InstRW<[P9_ALUOpAndALUOp_4C, IP_EXEC_1C, IP_EXEC_1C, (instregex "RLD(I)?C(R|L)_rec$"), (instregex "RLW(IMI|INM|NM)(8)?_rec$"), (instregex "SLW(8)?_rec$"), - (instregex "SRAW(I)?_rec$"), + (instregex "SRAW(8)?_rec$"), + (instregex "SRAWI(8)?_rec$"), (instregex "SRW(8)?_rec$"), RLDICL_32_rec, RLDIMI_rec diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td index 72c5909f10c3..39da42846139 100644 --- a/llvm/lib/Target/PowerPC/PPC.td +++ b/llvm/lib/Target/PowerPC/PPC.td @@ -552,6 +552,18 @@ def getAltVSXFMAOpcode : InstrMapping { let ValueCols = [["1"]]; } +def get64BitInstrFromSignedExt32BitInstr : InstrMapping { + let FilterClass = "SExt32To64"; + // Instructions with the same opcode. + let RowFields = ["Inst"]; + // Instructions with the same Interpretation64Bit value form a column. + let ColFields = ["Interpretation64Bit"]; + // The key column are not the Interpretation64Bit-form instructions. + let KeyCol = ["0"]; + // Value columns are the Interpretation64Bit-form instructions. + let ValueCols = [["1"]]; +} + //===----------------------------------------------------------------------===// // Register File Description //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td index ae25f5c78a0e..68419068e52a 100644 --- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -932,6 +932,14 @@ defm SLW8 : XForm_6r<31, 24, (outs g8rc:$RA), (ins g8rc:$RST, g8rc:$RB), "slw", "$RA, $RST, $RB", IIC_IntGeneral, []>, ZExt32To64; defm SRW8 : XForm_6r<31, 536, (outs g8rc:$RA), (ins g8rc:$RST, g8rc:$RB), "srw", "$RA, $RST, $RB", IIC_IntGeneral, []>, ZExt32To64; + +defm SRAW8 : XForm_6rc<31, 792, (outs g8rc:$RA), (ins g8rc:$RST, g8rc:$RB), + "sraw", "$RA, $RST, $RB", IIC_IntShift, + []>, SExt32To64; + +defm SRAWI8 : XForm_10rc<31, 824, (outs g8rc:$RA), (ins g8rc:$RST, u5imm:$RB), + "srawi", "$RA, $RST, $RB", IIC_IntShift, []>, SExt32To64; + } // Interpretation64Bit // For fast-isel: diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index bc2a1b295b43..3c331cee8f76 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -5250,6 +5250,215 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const { // We limit the max depth to track incoming values of PHIs or binary ops // (e.g. AND) to avoid excessive cost. const unsigned MAX_BINOP_DEPTH = 1; + +// This function will promote the instruction which defines the register `Reg` +// in the parameter from a 32-bit to a 64-bit instruction if needed. The logic +// used to check whether an instruction needs to be promoted or not is similar +// to the logic used to check whether or not a defined register is sign or zero +// extended within the function PPCInstrInfo::isSignOrZeroExtended. +// Additionally, the `promoteInstr32To64ForElimEXTSW` function is recursive. +// BinOpDepth does not count all of the recursions. The parameter BinOpDepth is +// incremented only when `promoteInstr32To64ForElimEXTSW` calls itself more +// than once. This is done to prevent exponential recursion. +void PPCInstrInfo::promoteInstr32To64ForElimEXTSW(const Register &Reg, + MachineRegisterInfo *MRI, + unsigned BinOpDepth, + LiveVariables *LV) const { + if (!Reg.isVirtual()) + return; + + MachineInstr *MI = MRI->getVRegDef(Reg); + if (!MI) + return; + + unsigned Opcode = MI->getOpcode(); + + switch (Opcode) { + case PPC::OR: + case PPC::ISEL: + case PPC::OR8: + case PPC::PHI: { + if (BinOpDepth >= MAX_BINOP_DEPTH) + break; + unsigned OperandEnd = 3, OperandStride = 1; + if (Opcode == PPC::PHI) { + OperandEnd = MI->getNumOperands(); + OperandStride = 2; + } + + for (unsigned I = 1; I < OperandEnd; I += OperandStride) { + assert(MI->getOperand(I).isReg() && "Operand must be register"); + promoteInstr32To64ForElimEXTSW(MI->getOperand(I).getReg(), MRI, + BinOpDepth + 1, LV); + } + + break; + } + case PPC::COPY: { + // Refers to the logic of the `case PPC::COPY` statement in the function + // PPCInstrInfo::isSignOrZeroExtended(). + + Register SrcReg = MI->getOperand(1).getReg(); + // In both ELFv1 and v2 ABI, method parameters and the return value + // are sign- or zero-extended. + const MachineFunction *MF = MI->getMF(); + if (!MF->getSubtarget().isSVR4ABI()) { + // If this is a copy from another register, we recursively promote the + // source. + promoteInstr32To64ForElimEXTSW(SrcReg, MRI, BinOpDepth, LV); + return; + } + + // From here on everything is SVR4ABI. COPY will be eliminated in the other + // pass, we do not need promote the COPY pseudo opcode. + + if (SrcReg != PPC::X3) + // If this is a copy from another register, we recursively promote the + // source. + promoteInstr32To64ForElimEXTSW(SrcReg, MRI, BinOpDepth, LV); + return; + } + case PPC::ORI: + case PPC::XORI: + case PPC::ORIS: + case PPC::XORIS: + case PPC::ORI8: + case PPC::XORI8: + case PPC::ORIS8: + case PPC::XORIS8: + promoteInstr32To64ForElimEXTSW(MI->getOperand(1).getReg(), MRI, BinOpDepth, + LV); + break; + case PPC::AND: + case PPC::AND8: + if (BinOpDepth >= MAX_BINOP_DEPTH) + break; + + promoteInstr32To64ForElimEXTSW(MI->getOperand(1).getReg(), MRI, + BinOpDepth + 1, LV); + promoteInstr32To64ForElimEXTSW(MI->getOperand(2).getReg(), MRI, + BinOpDepth + 1, LV); + break; + } + + const TargetRegisterClass *RC = MRI->getRegClass(Reg); + if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass) + return; + + const PPCInstrInfo *TII = + MI->getMF()->getSubtarget().getInstrInfo(); + + // Map the 32bit to 64bit opcodes for instructions that are not signed or zero + // extended themselves, but may have operands who's destination registers of + // signed or zero extended instructions. + std::unordered_map OpcodeMap = { + {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8}, + {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8}, + {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8}, + {PPC::AND, PPC::AND8}}; + + int NewOpcode = -1; + auto It = OpcodeMap.find(Opcode); + if (It != OpcodeMap.end()) { + // Set the new opcode to the mapped 64-bit version. + NewOpcode = It->second; + } else { + if (!TII->isSExt32To64(Opcode)) + return; + + // The TableGen function `get64BitInstrFromSignedExt32BitInstr` is used to + // map the 32-bit instruction with the `SExt32To64` flag to the 64-bit + // instruction with the same opcode. + NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode); + } + + assert(NewOpcode != -1 && + "Must have a 64-bit opcode to map the 32-bit opcode!"); + + const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo(); + const MCInstrDesc &MCID = TII->get(NewOpcode); + const TargetRegisterClass *NewRC = + TRI->getRegClass(MCID.operands()[0].RegClass); + + Register SrcReg = MI->getOperand(0).getReg(); + const TargetRegisterClass *SrcRC = MRI->getRegClass(SrcReg); + + // If the register class of the defined register in the 32-bit instruction + // is the same as the register class of the defined register in the promoted + // 64-bit instruction, we do not need to promote the instruction. + if (NewRC == SrcRC) + return; + + DebugLoc DL = MI->getDebugLoc(); + auto MBB = MI->getParent(); + + // Since the pseudo-opcode of the instruction is promoted from 32-bit to + // 64-bit, if the source reg class of the original instruction belongs to + // PPC::GRCRegClass or PPC::GPRC_and_GPRC_NOR0RegClass, we need to promote + // the operand to PPC::G8CRegClass or PPC::G8RC_and_G8RC_NOR0RegClass, + // respectively. + DenseMap PromoteRegs; + for (unsigned i = 1; i < MI->getNumOperands(); i++) { + MachineOperand &Operand = MI->getOperand(i); + if (!Operand.isReg()) + continue; + + Register OperandReg = Operand.getReg(); + if (!OperandReg.isVirtual()) + continue; + + const TargetRegisterClass *NewUsedRegRC = + TRI->getRegClass(MCID.operands()[i].RegClass); + const TargetRegisterClass *OrgRC = MRI->getRegClass(OperandReg); + if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass || + OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) { + // Promote the used 32-bit register to 64-bit register. + Register TmpReg = MRI->createVirtualRegister(NewUsedRegRC); + Register DstTmpReg = MRI->createVirtualRegister(NewUsedRegRC); + BuildMI(*MBB, MI, DL, TII->get(PPC::IMPLICIT_DEF), TmpReg); + BuildMI(*MBB, MI, DL, TII->get(PPC::INSERT_SUBREG), DstTmpReg) + .addReg(TmpReg) + .addReg(OperandReg) + .addImm(PPC::sub_32); + PromoteRegs[i] = DstTmpReg; + } + } + + Register NewDefinedReg = MRI->createVirtualRegister(NewRC); + + BuildMI(*MBB, MI, DL, TII->get(NewOpcode), NewDefinedReg); + MachineBasicBlock::instr_iterator Iter(MI); + --Iter; + MachineInstrBuilder MIBuilder(*Iter->getMF(), Iter); + for (unsigned i = 1; i < MI->getNumOperands(); i++) { + if (PromoteRegs.find(i) != PromoteRegs.end()) + MIBuilder.addReg(PromoteRegs[i], RegState::Kill); + else + Iter->addOperand(MI->getOperand(i)); + } + + for (unsigned i = 1; i < Iter->getNumOperands(); i++) { + MachineOperand &Operand = Iter->getOperand(i); + if (!Operand.isReg()) + continue; + Register OperandReg = Operand.getReg(); + if (!OperandReg.isVirtual()) + continue; + LV->recomputeForSingleDefVirtReg(OperandReg); + } + + MI->eraseFromParent(); + + // 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, TII->get(PPC::COPY), SrcReg) + .addReg(NewDefinedReg, RegState::Kill, PPC::sub_32); + LV->recomputeForSingleDefVirtReg(NewDefinedReg); + return; +} + // The isSignOrZeroExtended function is recursive. The parameter BinOpDepth // does not count all of the recursions. The parameter BinOpDepth is incremented // only when isSignOrZeroExtended calls itself more than once. This is done to diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index 40996f6fbb75..c2abf2f94274 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -17,6 +17,7 @@ #include "PPC.h" #include "PPCRegisterInfo.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/TargetInstrInfo.h" #define GET_INSTRINFO_HEADER @@ -625,6 +626,10 @@ public: const MachineRegisterInfo *MRI) const { return isSignOrZeroExtended(Reg, 0, MRI).second; } + void promoteInstr32To64ForElimEXTSW(const Register &Reg, + MachineRegisterInfo *MRI, + unsigned BinOpDepth, + LiveVariables *LV) const; bool convertToImmediateForm(MachineInstr &MI, SmallSet &RegsToUpdate, diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index b8abee76cdfa..b762cac8ea4f 100644 --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1053,7 +1053,16 @@ bool PPCMIPeephole::simplifyCode() { } else if (MI.getOpcode() == PPC::EXTSW_32_64 && TII->isSignExtended(NarrowReg, MRI)) { // We can eliminate EXTSW if the input is known to be already - // sign-extended. + // sign-extended. However, we are not sure whether a spill will occur + // during register allocation. If there is no promotion, it will use + // 'stw' instead of 'std', and 'lwz' instead of 'ld' when spilling, + // since the register class is 32-bits. Consequently, the high 32-bit + // information will be lost. Therefore, all these instructions in the + // 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); diff --git a/llvm/lib/Target/PowerPC/PPCScheduleP7.td b/llvm/lib/Target/PowerPC/PPCScheduleP7.td index 93399e5ddbca..bf7f2f7a9c99 100644 --- a/llvm/lib/Target/PowerPC/PPCScheduleP7.td +++ b/llvm/lib/Target/PowerPC/PPCScheduleP7.td @@ -216,7 +216,7 @@ let SchedModel = P7Model in { RLWNM, RLWNM8, RLWNM_rec, RLDIMI, RLDIMI_rec, RLDICL_32, RLDICL_32_64, RLDICL_32_rec, RLDICR_32, RLWINM8_rec, RLWNM8_rec, SLD, SLD_rec, SLW, SLW8, SLW_rec, SLW8_rec, SRD, SRD_rec, SRW, SRW8, SRW_rec, - SRW8_rec, SRADI, SRADI_rec, SRAWI, SRAWI_rec, SRAD, SRAD_rec, SRAW, SRAW_rec, + SRW8_rec, SRADI, SRADI_rec, SRAWI, SRAWI_rec, SRAWI8, SRAWI8_rec, SRAD, SRAD_rec, SRAW, SRAW_rec, SRAW8, SRAW8_rec, SRADI_32, SUBFE, SUBFE8, SUBFE8O_rec, SUBFEO_rec )>; 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 dfbf412a9392..cdd6be56b46d 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 @@ -604,7 +604,7 @@ body: | %2 = LI 48 %5 = COPY %0.sub_32 %8 = SRW killed %5, killed %2 - ; CHECK: LI 0 + ; CHECK: LI8 0 ; CHECK-LATE: li 3, 0 $x3 = EXTSW_32_64 %8 BLR8 implicit $lr8, implicit $rm, implicit $x3 @@ -722,7 +722,7 @@ body: | %3 = COPY %0.sub_32 %4 = SRAW killed %3, killed %2, implicit-def dead $carry ; CHECK: LI 48 - ; CHECK: SRAW killed %3, killed %2, implicit-def dead $carry + ; CHECK: SRAW8 killed %7, killed %9, implicit-def $carry, implicit-def dead $carry ; CHECK-LATE: sraw 3, 3, 4 %5 = EXTSW_32_64 killed %4 $x3 = COPY %5 @@ -779,7 +779,7 @@ body: | %2 = LI 80 %3 = COPY %0.sub_32 %4 = SRAW_rec killed %3, %2, implicit-def dead $carry, implicit-def $cr0 - ; CHECK: 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-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 761316ed7726..fa06dd551a0d 100644 --- a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir +++ b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir @@ -1348,7 +1348,7 @@ body: | %1 = LI 77 %2 = ADDI killed %1, 44 %3 = EXTSW_32_64 killed %2 - ; CHECK: LI 121 + ; CHECK: LI8 121 ; CHECK-LATE: li 3, 121 $x3 = COPY %3 BLR8 implicit $lr8, implicit $rm, implicit $x3 @@ -3573,7 +3573,7 @@ body: | %0 = LI 777 %1 = ORI %0, 88 - ; CHECK: LI 857 + ; CHECK: LI8 857 ; CHECK-LATE: li 3, 857 $x3 = EXTSW_32_64 %1 BLR8 implicit $lr8, implicit $rm, implicit $x3 @@ -4145,7 +4145,7 @@ body: | %3 = IMPLICIT_DEF %2 = LI 17 %4 = RLWINM killed %2, 4, 20, 27 - ; CHECK: LI 272 + ; CHECK: LI8 272 ; CHECK-LATE: li 3, 272 $x3 = EXTSW_32_64 %4 BLR8 implicit $lr8, implicit $rm, implicit $x3 @@ -4990,7 +4990,10 @@ body: | %2 = LI 15 %3 = COPY %0.sub_32 %4 = SRAW killed %3, killed %2, implicit-def dead $carry - ; CHECK: SRAWI killed %3, 15, implicit-def dead $carry + ; CHECK: %6:g8rc = IMPLICIT_DEF + ; CHECK-NEXT: %7:g8rc = INSERT_SUBREG %6, killed %3, %subreg.sub_32 + ; CHECK-NEXT: %8:g8rc = SRAWI8 killed %7, 15, implicit-def $carry, 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 $x3 = COPY %5 @@ -5047,7 +5050,7 @@ body: | %2 = LI 8 %3 = COPY %0.sub_32 %4 = SRAW_rec killed %3, %2, implicit-def dead $carry, implicit-def $cr0 - ; CHECK: SRAWI_rec killed %3, 8, 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-LATE: srawi. 3, 3, 8 %5 = COPY killed $cr0 %6 = ISEL %2, %4, %5.sub_eq @@ -6456,7 +6459,7 @@ body: | %0 = LI 871 %1 = XORI %0, 17 - ; CHECK: LI 886 + ; CHECK: LI8 886 ; CHECK-LATE: li 3, 886 $x3 = EXTSW_32_64 %1 BLR8 implicit $lr8, implicit $rm, implicit $x3 diff --git a/llvm/test/CodeGen/PowerPC/peephole-replaceInstr-after-eliminate-extsw.mir b/llvm/test/CodeGen/PowerPC/peephole-replaceInstr-after-eliminate-extsw.mir index 71b1ad536810..8e3c0862d3cb 100644 --- a/llvm/test/CodeGen/PowerPC/peephole-replaceInstr-after-eliminate-extsw.mir +++ b/llvm/test/CodeGen/PowerPC/peephole-replaceInstr-after-eliminate-extsw.mir @@ -496,7 +496,8 @@ body: | %6:g8rc_and_g8rc_nox0 = EXTSB8 killed %84 %7:gprc = LHZ 6, %64 :: (dereferenceable load (s16) from `ptr getelementptr inbounds ([8 x i16], ptr @shortArray, i64 0, i64 3)`, !tbaa !3) %86:gprc_and_gprc_nor0 = LHA 4, %64 :: (dereferenceable load (s16) from `ptr getelementptr inbounds ([8 x i16], ptr @shortArray, i64 0, i64 2)`) - ; CHECK: [[VIRREG1:%[0-9]+]]:gprc_and_gprc_nor0 = LHA 6, %64 :: (dereferenceable load (s16) from `ptr getelementptr inbounds ([8 x i16], ptr @shortArray, i64 0, i64 3)`, !tbaa !3) + ; CHECK: [[VIRREG162:%[0-9]+]]:g8rc = LHA8 6, %64 + ; CHECK-NEXT: [[VIRREG150:%[0-9]+]]:gprc_and_gprc_nor0 = COPY killed [[VIRREG162]].sub_32 %87:crrc = CMPW %80, %86 %88:gprc = ISEL %80, %86, %87.sub_lt %89:crrc = CMPLWI killed %88, 0 @@ -544,13 +545,19 @@ body: | %150:gprc_and_gprc_nor0 = EXTSH %7 %151:gprc_and_gprc_nor0 = EXTSH %0 - ; CHECK: [[VIRREG2:%[0-9]+]]:gprc_and_gprc_nor0 = EXTSH killed %0 + ; CHECK: [[VIRREG159:%[0-9]+]]:g8rc = IMPLICIT_DEF + ; CHECK-NEXT: [[VIRREG160:%[0-9]+]]:g8rc = INSERT_SUBREG [[VIRREG159]], %0, %subreg.sub_32 + ; CHECK-NEXT: [[VIRREG161:%[0-9]+]]:g8rc = EXTSH8 killed [[VIRREG160]] + ; CHECK-NEXT: %151:gprc_and_gprc_nor0 = COPY killed [[VIRREG161]].sub_32 + %152:crrc = CMPW %151, %150 %153:gprc = ISEL %151, %150, %152.sub_lt %154:g8rc = EXTSW_32_64 killed %153 - ; CHECK-NEXT: [[VIRREG3:%[0-9]+]]:crrc = CMPW [[VIRREG2]], [[VIRREG1]] - ; CHECK-NEXT: %153:gprc = ISEL killed [[VIRREG2]], killed [[VIRREG1]], killed [[VIRREG3]].sub_lt - ; CHECK-NOT: EXTSW_32_64 + ; CHECK: [[VIRREG165:%[0-9]+]]:g8rc = IMPLICIT_DEF + ; CHECK-NEXT: [[VIRREG166:%[0-9]+]]:g8rc = INSERT_SUBREG [[VIRREG165]], [[VIRREG150]], %subreg.sub_32 + ; CHECK-NEXT: [[VIRREG167:%[0-9]+]]:g8rc = ISEL8 killed %164, killed [[VIRREG166]], %152.sub_lt + ; CHECK-NEXT: %{{[0-9]+}}:gprc = COPY killed [[VIRREG167]].sub_32 + ; CHECK-NOT: EXTSW_32_64 %155:g8rc_and_g8rc_nox0 = LDtoc @computedResultUll, $x2 :: (load (s64) from got) STD %154, 0, killed %155 :: (store (s64) into @computedResultUll, !tbaa !7) ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1 diff --git a/llvm/test/CodeGen/PowerPC/sext_elimination.mir b/llvm/test/CodeGen/PowerPC/sext_elimination.mir index e920848a4137..bf6b9005fcf7 100644 --- a/llvm/test/CodeGen/PowerPC/sext_elimination.mir +++ b/llvm/test/CodeGen/PowerPC/sext_elimination.mir @@ -41,8 +41,14 @@ body: | ; CHECK: %4:g8rc = EXTSW_32_64 killed %3 ; CHECK: %5:g8rc = INSERT_SUBREG %15, %1, %subreg.sub_32 ; CHECK: %7:g8rc = EXTSW_32_64 killed %6 - ; CHECK: %9:g8rc = INSERT_SUBREG %16, %8, %subreg.sub_32 - ; CHECK: %11:g8rc = INSERT_SUBREG %17, %10, %subreg.sub_32 + ; CHECK: %17:g8rc = INSERT_SUBREG %16, %1, %subreg.sub_32 + ; CHECK-NEXT: %18:g8rc = ORIS8 killed %17, 32767 + ; CHECK-NEXT: %8:gprc = COPY killed %18.sub_32 + ; CHECK: %9:g8rc = INSERT_SUBREG %19, %8, %subreg.sub_32 + ; CHECK: %21:g8rc = INSERT_SUBREG %20, %1, %subreg.sub_32 + ; CHECK-NEXT: %22:g8rc = ORI8 killed %21, 32768 + ; CHECK-NEXT: %10:gprc = COPY killed %22.sub_32 + ; CHECK: %11:g8rc = INSERT_SUBREG %23, %10, %subreg.sub_32 ; CHECK: %14:g8rc = COPY killed %13 %0:g8rc_nox0 = COPY $x3 diff --git a/llvm/test/CodeGen/PowerPC/stack-restore-with-setjmp.ll b/llvm/test/CodeGen/PowerPC/stack-restore-with-setjmp.ll index 8748767501bd..bc12276060a8 100644 --- a/llvm/test/CodeGen/PowerPC/stack-restore-with-setjmp.ll +++ b/llvm/test/CodeGen/PowerPC/stack-restore-with-setjmp.ll @@ -19,9 +19,10 @@ define dso_local signext i32 @main(i32 signext %argc, ptr nocapture readnone %ar ; CHECK-NEXT: # kill: def $r3 killed $r3 killed $x3 ; CHECK-NEXT: cmpwi 2, 3, 2 ; CHECK-NEXT: li 4, 0 +; CHECK-NEXT: # kill: def $r4 killed $r4 killed $x4 +; CHECK-NEXT: mr 3, 4 ; CHECK-NEXT: std 0, 800(1) ; CHECK-NEXT: mr 31, 1 -; CHECK-NEXT: mr 3, 4 ; CHECK-NEXT: blt 2, .LBB0_3 ; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: addi 3, 31, 112 @@ -65,6 +66,7 @@ define dso_local signext i32 @main(i32 signext %argc, ptr nocapture readnone %ar ; BE-NEXT: stdu 1, -800(1) ; BE-NEXT: li 4, 0 ; BE-NEXT: # kill: def $r3 killed $r3 killed $x3 +; BE-NEXT: # kill: def $r4 killed $r4 killed $x4 ; BE-NEXT: cmpwi 2, 3, 2 ; BE-NEXT: mr 3, 4 ; BE-NEXT: std 0, 816(1)