Index: lib/Target/PowerPC/PPC.h =================================================================== --- lib/Target/PowerPC/PPC.h +++ lib/Target/PowerPC/PPC.h @@ -52,6 +52,7 @@ void initializePPCVSXFMAMutatePass(PassRegistry&); void initializePPCBoolRetToIntPass(PassRegistry&); void initializePPCExpandISELPass(PassRegistry &); + void initializePPCMIPeepholePass(PassRegistry&); extern char &PPCVSXFMAMutateID; namespace PPCII { Index: lib/Target/PowerPC/PPCInstrInfo.h =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.h +++ lib/Target/PowerPC/PPCInstrInfo.h @@ -305,6 +305,16 @@ bool isZeroExtended(const MachineInstr &MI, const unsigned depth = 0) const { return isSignOrZeroExtended(MI, false, depth); } + + bool convertToImmediateForm(MachineInstr &MI) const; + + // This is used to find the "true" source register for n + // Machine instruction. Returns the original SrcReg unless it is the target + // of a copy-like operation, in which case we chain backwards through all + // such operations to the ultimate source register. If a + // physical register is encountered, we stop the search. + static unsigned lookThruCopyLike(unsigned SrcReg, + const MachineRegisterInfo *MRI); }; } Index: lib/Target/PowerPC/PPCInstrInfo.cpp =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.cpp +++ lib/Target/PowerPC/PPCInstrInfo.cpp @@ -37,6 +37,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/Statistic.h" using namespace llvm; @@ -46,6 +47,9 @@ #define GET_INSTRINFO_CTOR_DTOR #include "PPCGenInstrInfo.inc" +STATISTIC(MissedConvertibleImmediateInstrs, + "Number of compare-immediate instructions fed by constants."); + static cl:: opt DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, cl::desc("Disable analysis for CTR loops")); @@ -2128,3 +2132,328 @@ return false; } +unsigned PPCInstrInfo::lookThruCopyLike(unsigned SrcReg, + const MachineRegisterInfo *MRI) { + while (true) { + MachineInstr *MI = MRI->getVRegDef(SrcReg); + if (!MI->isCopyLike()) + return SrcReg; + + unsigned CopySrcReg; + if (MI->isCopy()) + CopySrcReg = MI->getOperand(1).getReg(); + else { + assert(MI->isSubregToReg() && "bad opcode for lookThruCopyLike"); + CopySrcReg = MI->getOperand(2).getReg(); + } + + if (!TargetRegisterInfo::isVirtualRegister(CopySrcReg)) + return CopySrcReg; + + SrcReg = CopySrcReg; + } +} + +// If this instruction has an immediate form and one of its operands is a +// result of a load-immediate, convert it to the immediate form if the constant +// is in range. +bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI) const { + MachineFunction *MF = MI.getParent()->getParent(); + MachineRegisterInfo *MRI = &MF->getRegInfo(); + MachineInstr *DefMI = nullptr; + unsigned ConstantOperand = ~0U; + for (int i = 1, e = MI.getNumOperands(); i < e; i++) { + if (!MI.getOperand(i).isReg()) + continue; + unsigned Reg = MI.getOperand(i).getReg(); + if (!TargetRegisterInfo::isVirtualRegister(Reg)) + continue; + unsigned TrueReg = lookThruCopyLike(Reg, MRI); + if (TargetRegisterInfo::isVirtualRegister(TrueReg)) { + DefMI = MRI->getVRegDef(TrueReg); + if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8) { + ConstantOperand = i; + break; + } + } + } + if (ConstantOperand == ~0U || !DefMI->getOperand(1).isImm()) + return false; + + int64_t Immediate = DefMI->getOperand(1).getImm(); + // Sign-extend to 64-bits. + int64_t SExtImm = ((uint64_t)Immediate & ~0x7FFFuLL) != 0 ? + (Immediate | 0xFFFFFFFFFFFF0000) : Immediate; + + bool ReplaceWithLI = false; + bool Is64BitLI = false; + int64_t NewImm = 0; + bool SetCR = false; + unsigned Opc = MI.getOpcode(); + switch (Opc) { + default: return false; + + // FIXME: Immediate comparisons fed by a load-immediate. Any branches or + // selects it feeds can be converted to unconditional branches/selects. + case PPC::CMPWI: + case PPC::CMPLWI: + case PPC::CMPDI: + case PPC::CMPLDI: + MissedConvertibleImmediateInstrs++; + return false; + + // Immediate forms - may simply be convertable to an LI. + case PPC::ADDI: + case PPC::ADDI8: { + // Does the sum fit in a 16-bit signed field? + int64_t Addend = MI.getOperand(2).getImm(); + if (isInt<16>(Addend + SExtImm)) { + ReplaceWithLI = true; + Is64BitLI = Opc == PPC::ADDI8; + NewImm = Addend + SExtImm; + break; + } + } + case PPC::RLDICL: + case PPC::RLDICLo: + case PPC::RLDICL_32: + case PPC::RLDICL_32_64: { + // Use APInt's rotate function. + int64_t SH = MI.getOperand(2).getImm(); + int64_t MB = MI.getOperand(3).getImm(); + APInt InVal(Opc == PPC::RLDICL ? 64 : 32, SExtImm, true); + InVal = InVal.rotl(SH); + uint64_t Mask = (1LU << (63 - MB + 1)) - 1; + InVal &= Mask; + // Can't replace negative values with an LI as that will sign-extend + // and not clear the left bits. + if (isUInt<16>(InVal.getSExtValue())) { + ReplaceWithLI = true; + Is64BitLI = Opc != PPC::RLDICL_32; + NewImm = InVal.getSExtValue(); + SetCR = Opc == PPC::RLDICLo; + break; + } + return false; + } + case PPC::ORI: + case PPC::ORI8: + case PPC::XORI: + case PPC::XORI8: { + int64_t LogicalImm = MI.getOperand(2).getImm(); + int64_t Result = 0; + if (Opc == PPC::ORI || Opc == PPC::ORI8) + Result = LogicalImm | SExtImm; + else + Result = LogicalImm ^ SExtImm; + if (isInt<16>(Result)) { + ReplaceWithLI = true; + Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8; + NewImm = Result; + break; + } + return false; + } + + // Additions - commutable. + case PPC::ADD4: + case PPC::ADD8: { + DEBUG(dbgs() << "Converted reg/reg instruction:\n"); + DEBUG(MI.dump()); + MachineOperand Op1 = MI.getOperand(1); + MachineOperand Op2 = MI.getOperand(2); + MI.setDesc(get(Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8)); + MI.RemoveOperand(2); + MI.RemoveOperand(1); + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .add(ConstantOperand == 1 ? Op2 : Op1) + .addImm(Immediate); + MRI->setRegClass(MI.getOperand(1).getReg(), + Opc == PPC::ADD4 ? &PPC::GPRC_and_GPRC_NOR0RegClass : + &PPC::G8RC_and_G8RC_NOX0RegClass); + DEBUG(dbgs() << "To reg/imm instruction:\n"); + DEBUG(MI.dump()); + return true; + } + // Subtraction, compares - non-commutable. + case PPC::SUBFC: + case PPC::SUBFC8: { + if (ConstantOperand != 2) + return false; + unsigned NewOpc = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8; + DEBUG(dbgs() << "Converted:\n"); + DEBUG(MI.dump()); + DEBUG(dbgs() << "Fed by:\n"); + DEBUG(DefMI->dump()); + MI.RemoveOperand(2); + MI.setDesc(get(NewOpc)); + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .addImm(Immediate); + DEBUG(dbgs() << "To:\n"); + DEBUG(MI.dump()); + return true; + } + case PPC::CMPLW: + case PPC::CMPLD: + if (!isUInt<16>(SExtImm)) + return false; + LLVM_FALLTHROUGH; + case PPC::CMPW: + case PPC::CMPD: { + if (ConstantOperand != 2) + return false; + unsigned NewOpc = Opc == PPC::CMPLW ? PPC::CMPLWI : + Opc == PPC::CMPLD ? PPC::CMPLDI : + Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI; + DEBUG(dbgs() << "Converted:\n"); + DEBUG(MI.dump()); + DEBUG(dbgs() << "Fed by:\n"); + DEBUG(DefMI->dump()); + MI.RemoveOperand(2); + MI.setDesc(get(NewOpc)); + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .addImm(Immediate); + DEBUG(dbgs() << "To:\n"); + DEBUG(MI.dump()); + return true; + } + + case PPC::SLD: + case PPC::SLDo: { + if (ConstantOperand == 2) { + DEBUG(dbgs() << "Converted:\n"); + DEBUG(MI.dump()); + DEBUG(dbgs() << "Fed by:\n"); + DEBUG(DefMI->dump()); + MI.RemoveOperand(2); + uint64_t SH = Immediate & 0x3F; + uint64_t ME = 63 - SH; + + // According to the ISA, shifting by 64-127 is zero. It is important to + // keep in mind that only bits 57-63 are considered. So the result is zero + // if bit 57 is set in the shift register. + if (SExtImm & 0x40) { + ReplaceWithLI = true; + Is64BitLI = true; + NewImm = 0; + SetCR = Opc == PPC::SLDo; + break; + } + // Shifting by zero is redundant (but still needed if it sets CR0). + if (SH == 0 && Opc == PPC::SLD) + MI.setDesc(get(PPC::COPY)); + else { + MI.setDesc(get(Opc == PPC::SLD ? PPC::RLDICR : PPC::RLDICRo)); + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .addImm(SH).addImm(ME); + } + DEBUG(dbgs() << "To:\n"); + DEBUG(MI.dump()); + return true; + } + break; + } + case PPC::SRD: + case PPC::SRDo: + if (ConstantOperand == 2) { + DEBUG(dbgs() << "Converted:\n"); + DEBUG(MI.dump()); + DEBUG(dbgs() << "Fed by:\n"); + DEBUG(DefMI->dump()); + MI.RemoveOperand(2); + uint64_t MB = Immediate & 0x3F; + uint64_t SH = 64 - MB; + + // According to the ISA, shifting by 64-127 is zero. It is important to + // keep in mind that only bits 57-63 are considered. So the result is zero + // if bit 57 is set in the shift register. + if (SExtImm & 0x40) { + ReplaceWithLI = true; + Is64BitLI = true; + NewImm = 0; + SetCR = Opc == PPC::SRDo; + break; + } + // Shifting by zero is redundant (but still needed if it sets CR0). + if (SH == 64 && Opc == PPC::SRD) + MI.setDesc(get(PPC::COPY)); + else { + MI.setDesc(get(Opc == PPC::SRD ? PPC::RLDICL : PPC::RLDICLo)); + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .addImm(SH).addImm(MB); + } + DEBUG(dbgs() << "To:\n"); + DEBUG(MI.dump()); + return true; + } + break; + case PPC::ANDo: + case PPC::AND8o: + case PPC::OR: + case PPC::OR8: + case PPC::XOR: + case PPC::XOR8: { + unsigned ImmOpc = 0; + switch (Opc) { + case PPC::ANDo: + ImmOpc = PPC::ANDIo; + break; + case PPC::AND8o: + ImmOpc = PPC::ANDIo8; + break; + case PPC::OR: + ImmOpc = PPC::ORI; + break; + case PPC::OR8: + ImmOpc = PPC::ORI8; + break; + case PPC::XOR: + ImmOpc = PPC::XORI; + break; + case PPC::XOR8: + ImmOpc = PPC::XORI8; + break; + } + if (((uint64_t)Immediate & ~0x7FFFuLL) == 0) { + DEBUG(dbgs() << "Converted reg/reg instruction:\n"); + DEBUG(MI.dump()); + MachineOperand Op1 = MI.getOperand(1); + MachineOperand Op2 = MI.getOperand(2); + MI.setDesc(get(ImmOpc)); + MI.RemoveOperand(2); + MI.RemoveOperand(1); + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .add(ConstantOperand == 1 ? Op2 : Op1) + .addImm(Immediate); + DEBUG(dbgs() << "To reg/imm instruction:\n"); + DEBUG(MI.dump()); + return true; + } + } + } + + if (ReplaceWithLI) { + DEBUG(dbgs() << "Replacing instruction:\n"); + DEBUG(MI.dump()); + DEBUG(dbgs() << "Fed by:\n"); + DEBUG(DefMI->dump()); + // Remove existing operands. + int OperandToKeep = SetCR ? 1 : 0; + for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--) + MI.RemoveOperand(i); + + // Replace the instruction. + if (SetCR) + MI.setDesc(get(Is64BitLI ? PPC::ANDIo8 : PPC::ANDIo)); + else + MI.setDesc(get(Is64BitLI ? PPC::LI8 : PPC::LI)); + + // Set the immediate. + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .addImm(NewImm); + DEBUG(dbgs() << "With:\n"); + DEBUG(MI.dump()); + return true; + } + return false; +} Index: lib/Target/PowerPC/PPCMIPeephole.cpp =================================================================== --- lib/Target/PowerPC/PPCMIPeephole.cpp +++ lib/Target/PowerPC/PPCMIPeephole.cpp @@ -35,6 +35,8 @@ STATISTIC(NumEliminatedSExt, "Number of eliminated sign-extensions"); STATISTIC(NumEliminatedZExt, "Number of eliminated zero-extensions"); +STATISTIC(NumConvertedToImmediateForm, + "Number of instructions converted to their immediate form."); static cl::opt EnableSExtElimination("ppc-eliminate-signext", @@ -46,10 +48,6 @@ cl::desc("enable elimination of zero-extensions"), cl::init(true), cl::Hidden); -namespace llvm { - void initializePPCMIPeepholePass(PassRegistry&); -} - namespace { struct PPCMIPeephole : public MachineFunctionPass { @@ -70,10 +68,6 @@ // Perform peepholes. bool simplifyCode(void); - // Find the "true" register represented by SrcReg (following chains - // of copies and subreg_to_reg operations). - unsigned lookThruCopyLike(unsigned SrcReg); - public: // Main entry point for this pass. bool runOnMachineFunction(MachineFunction &MF) override { @@ -98,6 +92,31 @@ bool Simplified = false; MachineInstr* ToErase = nullptr; + // Fixed-point conversion of reg/reg instructions fed by load-immediate + // into reg/imm instructions. FIXME: This is expensive, control it with + // an option. + bool SomethingChanged = false; + do { + SomethingChanged = false; + for (MachineBasicBlock &MBB : *MF) { + for (MachineInstr &MI : MBB) { + if (MI.isDebugValue()) + continue; + + if (TII->convertToImmediateForm(MI)) { + // We don't erase anything in case the def has other uses. Let DCE + // remove it if it can be removed. + DEBUG(dbgs() << "Converted instruction to imm form: "); + DEBUG(MI.dump()); + NumConvertedToImmediateForm++; + SomethingChanged = true; + Simplified = true; + continue; + } + } + } + } while (SomethingChanged); + for (MachineBasicBlock &MBB : *MF) { for (MachineInstr &MI : MBB) { @@ -132,8 +151,10 @@ // XXPERMDI t, SUBREG_TO_REG(s), SUBREG_TO_REG(s), immed. // We have to look through chains of COPY and SUBREG_TO_REG // to find the real source values for comparison. - unsigned TrueReg1 = lookThruCopyLike(MI.getOperand(1).getReg()); - unsigned TrueReg2 = lookThruCopyLike(MI.getOperand(2).getReg()); + unsigned TrueReg1 = + TII->lookThruCopyLike(MI.getOperand(1).getReg(), MRI); + unsigned TrueReg2 = + TII->lookThruCopyLike(MI.getOperand(2).getReg(), MRI); if (TrueReg1 == TrueReg2 && TargetRegisterInfo::isVirtualRegister(TrueReg1)) { @@ -147,7 +168,8 @@ auto isConversionOfLoadAndSplat = [=]() -> bool { if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS) return false; - unsigned DefReg = lookThruCopyLike(DefMI->getOperand(1).getReg()); + unsigned DefReg = + TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI); if (TargetRegisterInfo::isVirtualRegister(DefReg)) { MachineInstr *LoadMI = MRI->getVRegDef(DefReg); if (LoadMI && LoadMI->getOpcode() == PPC::LXVDSX) @@ -173,10 +195,10 @@ // can replace it with a copy. if (DefOpc == PPC::XXPERMDI) { unsigned FeedImmed = DefMI->getOperand(3).getImm(); - unsigned FeedReg1 - = lookThruCopyLike(DefMI->getOperand(1).getReg()); - unsigned FeedReg2 - = lookThruCopyLike(DefMI->getOperand(2).getReg()); + unsigned FeedReg1 = + TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI); + unsigned FeedReg2 = + TII->lookThruCopyLike(DefMI->getOperand(2).getReg(), MRI); if ((FeedImmed == 0 || FeedImmed == 3) && FeedReg1 == FeedReg2) { DEBUG(dbgs() @@ -234,7 +256,8 @@ case PPC::XXSPLTW: { unsigned MyOpcode = MI.getOpcode(); unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2; - unsigned TrueReg = lookThruCopyLike(MI.getOperand(OpNo).getReg()); + unsigned TrueReg = + TII->lookThruCopyLike(MI.getOperand(OpNo).getReg(), MRI); if (!TargetRegisterInfo::isVirtualRegister(TrueReg)) break; MachineInstr *DefMI = MRI->getVRegDef(TrueReg); @@ -296,7 +319,8 @@ } case PPC::XVCVDPSP: { // If this is a DP->SP conversion fed by an FRSP, the FRSP is redundant. - unsigned TrueReg = lookThruCopyLike(MI.getOperand(1).getReg()); + unsigned TrueReg = + TII->lookThruCopyLike(MI.getOperand(1).getReg(), MRI); if (!TargetRegisterInfo::isVirtualRegister(TrueReg)) break; MachineInstr *DefMI = MRI->getVRegDef(TrueReg); @@ -304,8 +328,10 @@ // This can occur when building a vector of single precision or integer // values. if (DefMI && DefMI->getOpcode() == PPC::XXPERMDI) { - unsigned DefsReg1 = lookThruCopyLike(DefMI->getOperand(1).getReg()); - unsigned DefsReg2 = lookThruCopyLike(DefMI->getOperand(2).getReg()); + unsigned DefsReg1 = + TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI); + unsigned DefsReg2 = + TII->lookThruCopyLike(DefMI->getOperand(2).getReg(), MRI); if (!TargetRegisterInfo::isVirtualRegister(DefsReg1) || !TargetRegisterInfo::isVirtualRegister(DefsReg2)) break; @@ -439,36 +465,6 @@ return Simplified; } -// This is used to find the "true" source register for an -// XXPERMDI instruction, since MachineCSE does not handle the -// "copy-like" operations (Copy and SubregToReg). Returns -// the original SrcReg unless it is the target of a copy-like -// operation, in which case we chain backwards through all -// such operations to the ultimate source register. If a -// physical register is encountered, we stop the search. -unsigned PPCMIPeephole::lookThruCopyLike(unsigned SrcReg) { - - while (true) { - - MachineInstr *MI = MRI->getVRegDef(SrcReg); - if (!MI->isCopyLike()) - return SrcReg; - - unsigned CopySrcReg; - if (MI->isCopy()) - CopySrcReg = MI->getOperand(1).getReg(); - else { - assert(MI->isSubregToReg() && "bad opcode for lookThruCopyLike"); - CopySrcReg = MI->getOperand(2).getReg(); - } - - if (!TargetRegisterInfo::isVirtualRegister(CopySrcReg)) - return CopySrcReg; - - SrcReg = CopySrcReg; - } -} - } // end default namespace INITIALIZE_PASS_BEGIN(PPCMIPeephole, DEBUG_TYPE, Index: lib/Target/PowerPC/PPCTargetMachine.cpp =================================================================== --- lib/Target/PowerPC/PPCTargetMachine.cpp +++ lib/Target/PowerPC/PPCTargetMachine.cpp @@ -93,6 +93,7 @@ PassRegistry &PR = *PassRegistry::getPassRegistry(); initializePPCBoolRetToIntPass(PR); initializePPCExpandISELPass(PR); + initializePPCMIPeepholePass(PR); } /// Return the datalayout string of a subtarget. Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-add.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-add.mir @@ -0,0 +1,83 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @test(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %add = add i32 %a, 422 + %add1 = add i32 %add, %b + ret i32 %add1 + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: gprc } + - { id: 4, class: gprc_and_gprc_nor0 } + - { id: 5, class: gprc } + - { id: 6, class: gprc } + - { id: 7, class: gprc } + - { id: 8, class: gprc } + - { id: 9, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = COPY %0.sub_32 + %4 = LI 422 + %5 = ADD4 killed %3, killed %2 + %6 = ADD4 killed %5, %4 + ; CHECK: %6 = ADDI killed %5, 422 + %7 = ADDI killed %4, 333 + ; CHECK: %7 = LI 755 + %8 = ADD4 killed %6, killed %7 + ; CHECK: %8 = ADDI killed %6, 755 + %9 = EXTSW_32_64 killed %8 + %x3 = COPY %9 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-and.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-and.mir @@ -0,0 +1,139 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %and = and i64 %b, %a + %tobool = icmp ne i64 %and, 0 + %conv = select i1 %tobool, i64 778, i64 223 + ret i64 %conv + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @test3(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 { + entry: + %and = and i32 %b, %a + %tobool = icmp ne i32 %and, 0 + %cond = select i1 %tobool, i32 778, i32 223 + ret i32 %cond + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc } + - { id: 3, class: crrc } + - { id: 4, class: g8rc_and_g8rc_nox0 } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 263 + %0 = COPY %x3 + %2 = AND8o %1, %0, implicit-def %cr0 + ; CHECK: %2 = ANDIo8 %0, 263, implicit-def %cr0 + %3 = COPY killed %cr0 + %4 = LI8 223 + %5 = LI8 778 + %6 = ISEL8 %4, %5, %3.sub_eq + %x3 = COPY %6 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test3 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: gprc } + - { id: 4, class: gprc } + - { id: 5, class: crrc } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc_and_g8rc_nox0 } + - { id: 8, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 511 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = COPY %0.sub_32 + %4 = ANDo %2, %3, implicit-def %cr0 + ; CHECK: %4 = ANDIo %3, 511, implicit-def %cr0 + %5 = COPY killed %cr0 + %6 = LI8 223 + %7 = LI8 778 + %8 = ISEL8 %6, %7, %5.sub_eq + %x3 = COPY %8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-cmp.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-cmp.mir @@ -0,0 +1,251 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %conv = sext i32 %b to i64 + %cmp = icmp ult i64 %conv, %a + %conv2 = select i1 %cmp, i64 778, i64 223 + ret i64 %conv2 + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @test2(i32 zeroext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %cmp = icmp ugt i32 %a, %b + %cond = select i1 %cmp, i32 778, i32 223 + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test3(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %conv = sext i32 %b to i64 + %cmp = icmp slt i64 %conv, %a + %conv2 = select i1 %cmp, i64 778, i64 223 + ret i64 %conv2 + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @test4(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %cmp = icmp sgt i32 %a, %b + %cond = select i1 %cmp, i32 778, i32 223 + ret i32 %cond + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: crrc } + - { id: 3, class: g8rc_and_g8rc_nox0 } + - { id: 4, class: g8rc_and_g8rc_nox0 } + - { id: 5, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 433 + %2 = CMPLD %1, %0 + ; CHECK: %2 = CMPLDI %1, 433 + %3 = LI8 223 + %4 = LI8 778 + %5 = ISEL8 %4, %3, %2.sub_lt + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test2 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: gprc } + - { id: 4, class: crrc } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = LI 332 + %4 = CMPLW killed %2, killed %3 + ; CHECK: %4 = CMPLWI killed %2, 332 + %5 = LI8 223 + %6 = LI8 778 + %7 = ISEL8 %6, %5, %4.sub_gt + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test3 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: crrc } + - { id: 3, class: g8rc_and_g8rc_nox0 } + - { id: 4, class: g8rc_and_g8rc_nox0 } + - { id: 5, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 443 + %2 = CMPD %1, %0 + ; CHECK: %2 = CMPDI %1, 443 + %3 = LI8 223 + %4 = LI8 778 + %5 = ISEL8 %4, %3, %2.sub_lt + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test4 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: gprc } + - { id: 4, class: crrc } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = LI 332 + %4 = CMPW killed %2, killed %3 + ; CHECK: %4 = CMPWI killed %2, 332 + %5 = LI8 223 + %6 = LI8 778 + %7 = ISEL8 %6, %5, %4.sub_gt + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-or-xor.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-or-xor.mir @@ -0,0 +1,115 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %or = or i64 %b, %a + ret i64 %or + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test2(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %xor = xor i64 %b, %a + ret i64 %xor + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 44 + %0 = COPY %x3 + %2 = OR8 %1, %0 + ; CHECK: %2 = ORI8 %0, 44 + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test2 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 44 + %0 = COPY %x3 + %2 = XOR8 %1, %0 + ; CHECK: %2 = XORI8 %0, 44 + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-ori.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-ori.mir @@ -0,0 +1,64 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %or = or i64 %a, 13 + ret i64 %or + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI8 224 + %2 = ORI8 %0, 14 + ; CHECK: %2 = LI8 238 + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-rldicl.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-rldicl.mir @@ -0,0 +1,64 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %shr = lshr i64 %a, 13 + ret i64 %shr + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI8 22543 + %2 = RLDICL %0, 51, 13 + ; CHECK: %2 = LI8 2 + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-sld.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-sld.mir @@ -0,0 +1,359 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shl = shl i64 %a, %sh_prom + %tobool = icmp ne i64 %shl, 0 + %conv = select i1 %tobool, i64 778, i64 223 + ret i64 %conv + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test2(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shl = shl i64 %a, %sh_prom + ret i64 %shl + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test3(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shl = shl i64 %a, %sh_prom + %tobool = icmp ne i64 %shl, 0 + %conv = select i1 %tobool, i64 778, i64 223 + ret i64 %conv + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test4(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shl = shl i64 %a, %sh_prom + ret i64 %shl + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test5(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shl = shl i64 %a, %sh_prom + %tobool = icmp ne i64 %shl, 0 + %conv = select i1 %tobool, i64 778, i64 223 + ret i64 %conv + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test6(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shl = shl i64 %a, %sh_prom + ret i64 %shl + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } + - { id: 4, class: crrc } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 6 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SLDo %0, killed %2, implicit-def %cr0 + ; CHECK: %3 = RLDICRo %0, 6, 57, implicit-def %cr0 + %4 = COPY killed %cr0 + %5 = LI8 223 + %6 = LI8 778 + %7 = ISEL8 %5, %6, %4.sub_eq + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test2 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 9 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SLD %0, killed %2 + ; CHECK: %3 = RLDICR %0, 9, 54 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test3 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } + - { id: 4, class: crrc } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 113 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SLDo %0, killed %2, implicit-def %cr0 + ; CHECK: %3 = ANDIo8 %0, 0 + %4 = COPY killed %cr0 + %5 = LI8 223 + %6 = LI8 778 + %7 = ISEL8 %5, %6, %4.sub_eq + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test4 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 113 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SLD %0, killed %2 + ; CHECK: %3 = LI8 0 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test5 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } + - { id: 4, class: crrc } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 0 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SLDo %0, killed %2, implicit-def %cr0 + ; CHECK: %3 = RLDICRo %0, 0, 63, implicit-def %cr0 + %4 = COPY killed %cr0 + %5 = LI8 223 + %6 = LI8 778 + %7 = ISEL8 %5, %6, %4.sub_eq + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test6 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 0 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SLD %0, killed %2 + ; CHECK: %3 = COPY %0 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-srd.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-srd.mir @@ -0,0 +1,359 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shr = lshr i64 %a, %sh_prom + %tobool = icmp ne i64 %shr, 0 + %conv = select i1 %tobool, i64 778, i64 223 + ret i64 %conv + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test2(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shr = lshr i64 %a, %sh_prom + ret i64 %shr + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test3(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shr = lshr i64 %a, %sh_prom + %tobool = icmp ne i64 %shr, 0 + %conv = select i1 %tobool, i64 778, i64 223 + ret i64 %conv + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test4(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shr = lshr i64 %a, %sh_prom + ret i64 %shr + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test5(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shr = lshr i64 %a, %sh_prom + %tobool = icmp ne i64 %shr, 0 + %conv = select i1 %tobool, i64 778, i64 223 + ret i64 %conv + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @test6(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %sh_prom = zext i32 %b to i64 + %shr = lshr i64 %a, %sh_prom + ret i64 %shr + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } + - { id: 4, class: crrc } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 6 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SRDo %0, killed %2, implicit-def %cr0 + ; CHECK: %3 = RLDICLo %0, 58, 6, implicit-def %cr0 + %4 = COPY killed %cr0 + %5 = LI8 223 + %6 = LI8 778 + %7 = ISEL8 %5, %6, %4.sub_eq + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test2 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 9 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SRD %0, killed %2 + ; CHECK: %3 = RLDICL %0, 55, 9 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test3 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } + - { id: 4, class: crrc } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 113 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SRDo %0, killed %2, implicit-def %cr0 + ; CHECK: %3 = ANDIo8 %0, 0 + %4 = COPY killed %cr0 + %5 = LI8 223 + %6 = LI8 778 + %7 = ISEL8 %5, %6, %4.sub_eq + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test4 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 113 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SRD %0, killed %2 + ; CHECK: %3 = LI8 0 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test5 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } + - { id: 4, class: crrc } + - { id: 5, class: g8rc_and_g8rc_nox0 } + - { id: 6, class: g8rc_and_g8rc_nox0 } + - { id: 7, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 0 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SRDo %0, killed %2, implicit-def %cr0 + ; CHECK: %3 = RLDICLo %0, 64, 0, implicit-def %cr0 + %4 = COPY killed %cr0 + %5 = LI8 223 + %6 = LI8 778 + %7 = ISEL8 %5, %6, %4.sub_eq + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: test6 +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: gprc } + - { id: 3, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 0 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = SRD %0, killed %2 + ; CHECK: %3 = COPY %0 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-subfc.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-subfc.mir @@ -0,0 +1,71 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %cmp = icmp ugt i64 %a, 13 + %conv1 = zext i1 %cmp to i64 + ret i64 %conv1 + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc } + - { id: 3, class: g8rc } + - { id: 4, class: g8rc } + - { id: 5, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3 + + %0 = COPY %x3 + %2 = LI8 13 + %3 = SUBFC8 %0, %2, implicit-def %carry + ; CHECK: %3 = SUBFIC8 %0, 13, implicit-def %carry + %4 = SUBFE8 %2, %2, implicit-def dead %carry, implicit %carry + %5 = NEG8 killed %4 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/fold-constants-into-imm-instrs-xori.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fold-constants-into-imm-instrs-xori.mir @@ -0,0 +1,64 @@ +# RUN: llc -run-pass ppc-mi-peepholes -o - %s | FileCheck %s + +--- | + ; ModuleID = 't.ll' + source_filename = "t.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define i64 @test(i64 %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %xor = xor i64 %a, 13 + ret i64 %xor + } + + attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0} + !llvm.ident = !{!1} + + !0 = !{i32 1, !"PIC Level", i32 2} + !1 = !{!"clang version 5.0.0 (git@github.ibm.com:llvm/clang.git 5e5be8ed354acb606e083cee2ff9c9e096099ff2) (llvm/llvm.git c5a7ad098a8772950f4005869a14354e7f233ab3)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +noVRegs: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc } +liveins: + - { reg: '%x3', virtual-reg: '%0' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI8 224 + %2 = XORI8 %0, 13 + ; CHECK: %2 = LI8 237 + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... Index: test/CodeGen/PowerPC/setcc-logic.ll =================================================================== --- test/CodeGen/PowerPC/setcc-logic.ll +++ test/CodeGen/PowerPC/setcc-logic.ll @@ -422,9 +422,9 @@ define zeroext i1 @ne_neg1_and_ne_zero(i64 %x) { ; CHECK-LABEL: ne_neg1_and_ne_zero: ; CHECK: # BB#0: -; CHECK-NEXT: li 4, 1 ; CHECK-NEXT: addi 3, 3, 1 -; CHECK-NEXT: subfc 3, 3, 4 +; CHECK-NEXT: li 4, 1 +; CHECK-NEXT: subfic 3, 3, 1 ; CHECK-NEXT: subfe 3, 4, 4 ; CHECK-NEXT: neg 3, 3 ; CHECK-NEXT: blr Index: test/CodeGen/PowerPC/variable_elem_vec_extracts.ll =================================================================== --- test/CodeGen/PowerPC/variable_elem_vec_extracts.ll +++ test/CodeGen/PowerPC/variable_elem_vec_extracts.ll @@ -70,8 +70,7 @@ ; CHECK-LABEL: @getf ; CHECK-P7-LABEL: @getf ; CHECK-BE-LABEL: @getf -; CHECK: li [[IMMREG:[0-9]+]], 3 -; CHECK: xor [[TRUNCREG:[0-9]+]], [[IMMREG]], 5 +; CHECK: xori [[TRUNCREG:[0-9]+]], 5, 3 ; CHECK: lvsl [[SHMSKREG:[0-9]+]], 0, [[TRUNCREG]] ; CHECK: vperm {{[0-9]+}}, 2, 2, [[SHMSKREG]] ; CHECK: xscvspdpn 1,