From 01cfc43fe473b6cac0e01795556324dbef4388fc Mon Sep 17 00:00:00 2001 From: Nemanja Ivanovic Date: Fri, 15 Dec 2017 07:27:53 +0000 Subject: [PATCH] [PowerPC] Convert r+r instructions to r+i (pre and post RA) This patch adds the necessary infrastructure to convert instructions that take two register operands to those that take a register and immediate if the necessary operand is produced by a load-immediate. Furthermore, it uses this infrastructure to perform such conversions twice - first at MachineSSA and then pre-emit. There are a number of reasons we may end up with opportunities for this transformation, including but not limited to: - X-Form instructions chosen since the exact offset isn't available at ISEL time - Atomic instructions with constant operands (we will add patterns for this in the future) - Tail duplication may duplicate code where one block contains this redundancy - When emitting compare-free code in PPCDAGToDAGISel, we don't handle constant comparands specially Furthermore, this patch moves the initialization of PPCMIPeepholePass so that it can be used for MIR tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320791 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/CMakeLists.txt | 1 + lib/Target/PowerPC/PPC.h | 3 + lib/Target/PowerPC/PPCInstr64Bit.td | 5 + lib/Target/PowerPC/PPCInstrInfo.cpp | 814 +++ lib/Target/PowerPC/PPCInstrInfo.h | 52 + lib/Target/PowerPC/PPCInstrInfo.td | 5 + lib/Target/PowerPC/PPCMIPeephole.cpp | 111 +- lib/Target/PowerPC/PPCPreEmitPeephole.cpp | 95 + lib/Target/PowerPC/PPCTargetMachine.cpp | 3 + test/CodeGen/PowerPC/build-vector-tests.ll | 56 +- ...convert-rr-to-ri-instrs-R0-special-handling.mir | 436 ++ test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir | 6129 ++++++++++++++++++++ test/CodeGen/PowerPC/fast-isel-call.ll | 16 +- test/CodeGen/PowerPC/setcc-logic.ll | 4 +- test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll | 51 + test/CodeGen/PowerPC/unaligned.ll | 2 +- test/CodeGen/PowerPC/variable_elem_vec_extracts.ll | 6 +- 17 files changed, 7699 insertions(+), 90 deletions(-) create mode 100644 lib/Target/PowerPC/PPCPreEmitPeephole.cpp create mode 100644 test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir create mode 100644 test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir create mode 100644 test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll diff --git a/lib/Target/PowerPC/CMakeLists.txt b/lib/Target/PowerPC/CMakeLists.txt index 1a11c95e5f5..3f173787114 100644 --- a/lib/Target/PowerPC/CMakeLists.txt +++ b/lib/Target/PowerPC/CMakeLists.txt @@ -43,6 +43,7 @@ add_llvm_target(PowerPCCodeGen PPCVSXFMAMutate.cpp PPCVSXSwapRemoval.cpp PPCExpandISEL.cpp + PPCPreEmitPeephole.cpp ) add_subdirectory(AsmParser) diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h index 199455da25b..dfdec246e86 100644 --- a/lib/Target/PowerPC/PPC.h +++ b/lib/Target/PowerPC/PPC.h @@ -50,6 +50,7 @@ namespace llvm { FunctionPass *createPPCTLSDynamicCallPass(); FunctionPass *createPPCBoolRetToIntPass(); FunctionPass *createPPCExpandISELPass(); + FunctionPass *createPPCPreEmitPeepholePass(); void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP, bool isDarwin); bool LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, @@ -59,7 +60,9 @@ namespace llvm { void initializePPCVSXFMAMutatePass(PassRegistry&); void initializePPCBoolRetToIntPass(PassRegistry&); void initializePPCExpandISELPass(PassRegistry &); + void initializePPCPreEmitPeepholePass(PassRegistry &); void initializePPCTLSDynamicCallPass(PassRegistry &); + void initializePPCMIPeepholePass(PassRegistry&); extern char &PPCVSXFMAMutateID; namespace PPCII { diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index d5b5f69e009..fdd28c2ff03 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -194,6 +194,11 @@ def : Pat<(PPCcall_nop (i64 texternalsym:$dst)), (BL8_NOP texternalsym:$dst)>; // Atomic operations +// FIXME: some of these might be used with constant operands. This will result +// in constant materialization instructions that may be redundant. We currently +// clean this up in PPCMIPeephole with calls to +// PPCInstrInfo::convertToImmediateForm() but we should probably not emit them +// in the first place. let usesCustomInserter = 1 in { let Defs = [CR0] in { def ATOMIC_LOAD_ADD_I64 : Pseudo< diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 15e457543a9..a9060b41794 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -51,6 +51,10 @@ STATISTIC(NumStoreSPILLVSRRCAsVec, STATISTIC(NumStoreSPILLVSRRCAsGpr, "Number of spillvsrrc spilled to stack as gpr"); STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc"); +STATISTIC(CmpIselsConverted, + "Number of ISELs that depend on comparison of constants converted"); +STATISTIC(MissedConvertibleImmediateInstrs, + "Number of compare-immediate instructions fed by constants"); static cl:: opt DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, @@ -2147,6 +2151,816 @@ bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 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; + } +} + +// Essentially a compile-time implementation of a compare->isel sequence. +// It takes two constants to compare, along with the true/false registers +// and the comparison type (as a subreg to a CR field) and returns one +// of the true/false registers, depending on the comparison results. +static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc, + unsigned TrueReg, unsigned FalseReg, + unsigned CRSubReg) { + // Signed comparisons. The immediates are assumed to be sign-extended. + if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) { + switch (CRSubReg) { + default: llvm_unreachable("Unknown integer comparison type."); + case PPC::sub_lt: + return Imm1 < Imm2 ? TrueReg : FalseReg; + case PPC::sub_gt: + return Imm1 > Imm2 ? TrueReg : FalseReg; + case PPC::sub_eq: + return Imm1 == Imm2 ? TrueReg : FalseReg; + } + } + // Unsigned comparisons. + else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) { + switch (CRSubReg) { + default: llvm_unreachable("Unknown integer comparison type."); + case PPC::sub_lt: + return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg; + case PPC::sub_gt: + return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg; + case PPC::sub_eq: + return Imm1 == Imm2 ? TrueReg : FalseReg; + } + } + return PPC::NoRegister; +} + +// Replace an instruction with one that materializes a constant (and sets +// CR0 if the original instruction was a record-form instruction). +void PPCInstrInfo::replaceInstrWithLI(MachineInstr &MI, + const LoadImmediateInfo &LII) const { + // Remove existing operands. + int OperandToKeep = LII.SetCR ? 1 : 0; + for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--) + MI.RemoveOperand(i); + + // Replace the instruction. + if (LII.SetCR) + MI.setDesc(get(LII.Is64Bit ? PPC::ANDIo8 : PPC::ANDIo)); + else + MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI)); + + // Set the immediate. + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .addImm(LII.Imm); +} + +MachineInstr *PPCInstrInfo::getConstantDefMI(MachineInstr &MI, + unsigned &ConstOp, + bool &SeenIntermediateUse) const { + ConstOp = ~0U; + MachineInstr *DefMI = nullptr; + MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo(); + // If we'ere in SSA, get the defs through the MRI. Otherwise, only look + // within the basic block to see if the register is defined using an LI/LI8. + if (MRI->isSSA()) { + 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) { + ConstOp = i; + break; + } + } + } + } else { + // Looking back through the definition for each operand could be expensive, + // so exit early if this isn't an instruction that either has an immediate + // form or is already an immediate form that we can handle. + ImmInstrInfo III; + unsigned Opc = MI.getOpcode(); + bool ConvertibleImmForm = + Opc == PPC::CMPWI || Opc == PPC::CMPLWI || + Opc == PPC::CMPDI || Opc == PPC::CMPLDI || + Opc == PPC::ADDI || Opc == PPC::ADDI8 || + Opc == PPC::ORI || Opc == PPC::ORI8 || + Opc == PPC::XORI || Opc == PPC::XORI8 || + Opc == PPC::RLDICL || Opc == PPC::RLDICLo || + Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 || + Opc == PPC::RLWINM || Opc == PPC::RLWINMo || + Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o; + if (!instrHasImmForm(MI, III) && !ConvertibleImmForm) + return nullptr; + + // Don't convert or %X, %Y, %Y since that's just a register move. + if ((Opc == PPC::OR || Opc == PPC::OR8) && + MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) + return nullptr; + for (int i = 1, e = MI.getNumOperands(); i < e; i++) { + MachineOperand &MO = MI.getOperand(i); + SeenIntermediateUse = false; + if (MO.isReg() && MO.isUse() && !MO.isImplicit()) { + MachineBasicBlock::reverse_iterator E = MI.getParent()->rend(), It = MI; + It++; + unsigned Reg = MI.getOperand(i).getReg(); + + // Is this register defined by a load-immediate in this block? + for ( ; It != E; ++It) { + if (It->modifiesRegister(Reg, &getRegisterInfo())) { + if (It->getOpcode() == PPC::LI || It->getOpcode() == PPC::LI8) { + ConstOp = i; + return &*It; + } else + break; + } else if (It->readsRegister(Reg, &getRegisterInfo())) + // If we see another use of this reg between the def and the MI, + // we want to flat it so the def isn't deleted. + SeenIntermediateUse = true; + } + } + } + } + return ConstOp == ~0U ? nullptr : DefMI; +} + +// 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, + MachineInstr **KilledDef) const { + MachineFunction *MF = MI.getParent()->getParent(); + MachineRegisterInfo *MRI = &MF->getRegInfo(); + bool PostRA = !MRI->isSSA(); + bool SeenIntermediateUse = true; + unsigned ConstantOperand = ~0U; + MachineInstr *DefMI = getConstantDefMI(MI, ConstantOperand, + SeenIntermediateUse); + if (!DefMI || !DefMI->getOperand(1).isImm()) + return false; + assert(ConstantOperand < MI.getNumOperands() && + "The constant operand needs to be valid at this point"); + + int64_t Immediate = DefMI->getOperand(1).getImm(); + // Sign-extend to 64-bits. + int64_t SExtImm = ((uint64_t)Immediate & ~0x7FFFuLL) != 0 ? + (Immediate | 0xFFFFFFFFFFFF0000) : Immediate; + + if (KilledDef && MI.getOperand(ConstantOperand).isKill() && + !SeenIntermediateUse) + *KilledDef = DefMI; + + // If this is a reg+reg instruction that has a reg+imm form, convert it now. + ImmInstrInfo III; + if (instrHasImmForm(MI, III)) + return transformToImmForm(MI, III, ConstantOperand, SExtImm); + + bool ReplaceWithLI = false; + bool Is64BitLI = false; + int64_t NewImm = 0; + bool SetCR = false; + unsigned Opc = MI.getOpcode(); + switch (Opc) { + default: return false; + + // FIXME: Any branches conditional on such a comparison can be made + // unconditional. At this time, this happens too infrequently to be worth + // the implementation effort, but if that ever changes, we could convert + // such a pattern here. + case PPC::CMPWI: + case PPC::CMPLWI: + case PPC::CMPDI: + case PPC::CMPLDI: { + // Doing this post-RA would require dataflow analysis to reliably find uses + // of the CR register set by the compare. + if (PostRA) + return false; + // If a compare-immediate is fed by an immediate and is itself an input of + // an ISEL (the most common case) into a COPY of the correct register. + bool Changed = false; + unsigned DefReg = MI.getOperand(0).getReg(); + int64_t Comparand = MI.getOperand(2).getImm(); + int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0 ? + (Comparand | 0xFFFFFFFFFFFF0000) : Comparand; + + for (auto &CompareUseMI : MRI->use_instructions(DefReg)) { + unsigned UseOpc = CompareUseMI.getOpcode(); + if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8) + continue; + unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg(); + unsigned TrueReg = CompareUseMI.getOperand(1).getReg(); + unsigned FalseReg = CompareUseMI.getOperand(2).getReg(); + unsigned RegToCopy = selectReg(SExtImm, SExtComparand, Opc, TrueReg, + FalseReg, CRSubReg); + if (RegToCopy == PPC::NoRegister) + continue; + // Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0. + if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) { + CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI)); + CompareUseMI.getOperand(1).ChangeToImmediate(0); + CompareUseMI.RemoveOperand(3); + CompareUseMI.RemoveOperand(2); + continue; + } + DEBUG(dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n"); + DEBUG(DefMI->dump(); MI.dump(); CompareUseMI.dump()); + DEBUG(dbgs() << "Is converted to:\n"); + // Convert to copy and remove unneeded operands. + CompareUseMI.setDesc(get(PPC::COPY)); + CompareUseMI.RemoveOperand(3); + CompareUseMI.RemoveOperand(RegToCopy == TrueReg ? 2 : 1); + CmpIselsConverted++; + Changed = true; + DEBUG(CompareUseMI.dump()); + } + if (Changed) + return true; + // This may end up incremented multiple times since this function is called + // during a fixed-point transformation, but it is only meant to indicate the + // presence of this opportunity. + 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 we're setting the CR bit, we will use + // ANDIo which won't sign extend, so that's safe. + if (isUInt<15>(InVal.getSExtValue()) || + (Opc == PPC::RLDICLo && isUInt<16>(InVal.getSExtValue()))) { + ReplaceWithLI = true; + Is64BitLI = Opc != PPC::RLDICL_32; + NewImm = InVal.getSExtValue(); + SetCR = Opc == PPC::RLDICLo; + break; + } + return false; + } + case PPC::RLWINM: + case PPC::RLWINM8: + case PPC::RLWINMo: + case PPC::RLWINM8o: { + int64_t SH = MI.getOperand(2).getImm(); + int64_t MB = MI.getOperand(3).getImm(); + int64_t ME = MI.getOperand(4).getImm(); + APInt InVal(32, SExtImm, true); + InVal = InVal.rotl(SH); + // Set the bits ( MB + 32 ) to ( ME + 32 ). + uint64_t Mask = ((1 << (32 - MB)) - 1) & ~((1 << (31 - ME)) - 1); + InVal &= Mask; + // Can't replace negative values with an LI as that will sign-extend + // and not clear the left bits. If we're setting the CR bit, we will use + // ANDIo which won't sign extend, so that's safe. + bool ValueFits = isUInt<15>(InVal.getSExtValue()); + ValueFits |= ((Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o) && + isUInt<16>(InVal.getSExtValue())); + if (ValueFits) { + ReplaceWithLI = true; + Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o; + NewImm = InVal.getSExtValue(); + SetCR = Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o; + 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; + } + } + + if (ReplaceWithLI) { + DEBUG(dbgs() << "Replacing instruction:\n"); + DEBUG(MI.dump()); + DEBUG(dbgs() << "Fed by:\n"); + DEBUG(DefMI->dump()); + LoadImmediateInfo LII; + LII.Imm = NewImm; + LII.Is64Bit = Is64BitLI; + LII.SetCR = SetCR; + // If we're setting the CR, the original load-immediate must be kept (as an + // operand to ANDIo/ANDI8o). + if (KilledDef && SetCR) + *KilledDef = nullptr; + replaceInstrWithLI(MI, LII); + DEBUG(dbgs() << "With:\n"); + DEBUG(MI.dump()); + return true; + } + return false; +} + +bool PPCInstrInfo::instrHasImmForm(const MachineInstr &MI, + ImmInstrInfo &III) const { + unsigned Opc = MI.getOpcode(); + // The vast majority of the instructions would need their operand 2 replaced + // with an immediate when switching to the reg+imm form. A marked exception + // are the update form loads/stores for which a constant operand 2 would need + // to turn into a displacement and move operand 1 to the operand 2 position. + III.ImmOpNo = 2; + III.ConstantOpNo = 2; + III.ImmWidth = 16; + III.ImmMustBeMultipleOf = 1; + switch (Opc) { + default: return false; + case PPC::ADD4: + case PPC::ADD8: + III.SignedImm = true; + III.ZeroIsSpecialOrig = 0; + III.ZeroIsSpecialNew = 1; + III.IsCommutative = true; + III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8; + break; + case PPC::ADDC: + case PPC::ADDC8: + III.SignedImm = true; + III.ZeroIsSpecialOrig = 0; + III.ZeroIsSpecialNew = 0; + III.IsCommutative = true; + III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8; + break; + case PPC::ADDCo: + III.SignedImm = true; + III.ZeroIsSpecialOrig = 0; + III.ZeroIsSpecialNew = 0; + III.IsCommutative = true; + III.ImmOpcode = PPC::ADDICo; + break; + case PPC::SUBFC: + case PPC::SUBFC8: + III.SignedImm = true; + III.ZeroIsSpecialOrig = 0; + III.ZeroIsSpecialNew = 0; + III.IsCommutative = false; + III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8; + break; + case PPC::CMPW: + case PPC::CMPD: + III.SignedImm = true; + III.ZeroIsSpecialOrig = 0; + III.ZeroIsSpecialNew = 0; + III.IsCommutative = false; + III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI; + break; + case PPC::CMPLW: + case PPC::CMPLD: + III.SignedImm = false; + III.ZeroIsSpecialOrig = 0; + III.ZeroIsSpecialNew = 0; + III.IsCommutative = false; + III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI; + break; + case PPC::ANDo: + case PPC::AND8o: + case PPC::OR: + case PPC::OR8: + case PPC::XOR: + case PPC::XOR8: + III.SignedImm = false; + III.ZeroIsSpecialOrig = 0; + III.ZeroIsSpecialNew = 0; + III.IsCommutative = true; + switch(Opc) { + default: llvm_unreachable("Unknown opcode"); + case PPC::ANDo: III.ImmOpcode = PPC::ANDIo; break; + case PPC::AND8o: III.ImmOpcode = PPC::ANDIo8; break; + case PPC::OR: III.ImmOpcode = PPC::ORI; break; + case PPC::OR8: III.ImmOpcode = PPC::ORI8; break; + case PPC::XOR: III.ImmOpcode = PPC::XORI; break; + case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break; + } + break; + case PPC::RLWNM: + case PPC::RLWNM8: + case PPC::RLWNMo: + case PPC::RLWNM8o: + case PPC::RLDCL: + case PPC::RLDCLo: + case PPC::RLDCR: + case PPC::RLDCRo: + case PPC::SLW: + case PPC::SLW8: + case PPC::SLWo: + case PPC::SLW8o: + case PPC::SRW: + case PPC::SRW8: + case PPC::SRWo: + case PPC::SRW8o: + case PPC::SRAW: + case PPC::SRAWo: + case PPC::SLD: + case PPC::SLDo: + case PPC::SRD: + case PPC::SRDo: + case PPC::SRAD: + case PPC::SRADo: + III.SignedImm = false; + III.ZeroIsSpecialOrig = 0; + III.ZeroIsSpecialNew = 0; + III.IsCommutative = false; + // This isn't actually true, but the instructions ignore any of the + // upper bits, so any immediate loaded with an LI is acceptable. + III.ImmWidth = 16; + switch(Opc) { + default: llvm_unreachable("Unknown opcode"); + case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break; + case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break; + case PPC::RLWNMo: III.ImmOpcode = PPC::RLWINMo; break; + case PPC::RLWNM8o: III.ImmOpcode = PPC::RLWINM8o; break; + case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break; + case PPC::RLDCLo: III.ImmOpcode = PPC::RLDICLo; break; + case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break; + case PPC::RLDCRo: III.ImmOpcode = PPC::RLDICRo; break; + case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break; + case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break; + case PPC::SLWo: III.ImmOpcode = PPC::RLWINMo; break; + case PPC::SLW8o: III.ImmOpcode = PPC::RLWINM8o; break; + case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break; + case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break; + case PPC::SRWo: III.ImmOpcode = PPC::RLWINMo; break; + case PPC::SRW8o: III.ImmOpcode = PPC::RLWINM8o; break; + case PPC::SRAW: III.ImmOpcode = PPC::SRAWI; break; + case PPC::SRAWo: III.ImmOpcode = PPC::SRAWIo; break; + case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break; + case PPC::SLDo: III.ImmOpcode = PPC::RLDICRo; break; + case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break; + case PPC::SRDo: III.ImmOpcode = PPC::RLDICLo; break; + case PPC::SRAD: III.ImmOpcode = PPC::SRADI; break; + case PPC::SRADo: III.ImmOpcode = PPC::SRADIo; break; + } + break; + // Loads and stores: + case PPC::LBZX: + case PPC::LBZX8: + case PPC::LHZX: + case PPC::LHZX8: + case PPC::LHAX: + case PPC::LHAX8: + case PPC::LWZX: + case PPC::LWZX8: + case PPC::LWAX: + case PPC::LDX: + case PPC::LFSX: + case PPC::LFDX: + case PPC::STBX: + case PPC::STBX8: + case PPC::STHX: + case PPC::STHX8: + case PPC::STWX: + case PPC::STWX8: + case PPC::STDX: + case PPC::STFSX: + case PPC::STFDX: + III.SignedImm = true; + III.ZeroIsSpecialOrig = 1; + III.ZeroIsSpecialNew = 2; + III.IsCommutative = true; + III.ImmOpNo = 1; + III.ConstantOpNo = 2; + switch(Opc) { + default: llvm_unreachable("Unknown opcode"); + case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break; + case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break; + case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break; + case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break; + case PPC::LHAX: III.ImmOpcode = PPC::LHA; break; + case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break; + case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break; + case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break; + case PPC::LWAX: + III.ImmOpcode = PPC::LWA; + III.ImmMustBeMultipleOf = 4; + break; + case PPC::LDX: III.ImmOpcode = PPC::LD; III.ImmMustBeMultipleOf = 4; break; + case PPC::LFSX: III.ImmOpcode = PPC::LFS; break; + case PPC::LFDX: III.ImmOpcode = PPC::LFD; break; + case PPC::STBX: III.ImmOpcode = PPC::STB; break; + case PPC::STBX8: III.ImmOpcode = PPC::STB8; break; + case PPC::STHX: III.ImmOpcode = PPC::STH; break; + case PPC::STHX8: III.ImmOpcode = PPC::STH8; break; + case PPC::STWX: III.ImmOpcode = PPC::STW; break; + case PPC::STWX8: III.ImmOpcode = PPC::STW8; break; + case PPC::STDX: + III.ImmOpcode = PPC::STD; + III.ImmMustBeMultipleOf = 4; + break; + case PPC::STFSX: III.ImmOpcode = PPC::STFS; break; + case PPC::STFDX: III.ImmOpcode = PPC::STFD; break; + } + break; + case PPC::LBZUX: + case PPC::LBZUX8: + case PPC::LHZUX: + case PPC::LHZUX8: + case PPC::LHAUX: + case PPC::LHAUX8: + case PPC::LWZUX: + case PPC::LWZUX8: + case PPC::LDUX: + case PPC::LFSUX: + case PPC::LFDUX: + case PPC::STBUX: + case PPC::STBUX8: + case PPC::STHUX: + case PPC::STHUX8: + case PPC::STWUX: + case PPC::STWUX8: + case PPC::STDUX: + case PPC::STFSUX: + case PPC::STFDUX: + III.SignedImm = true; + III.ZeroIsSpecialOrig = 2; + III.ZeroIsSpecialNew = 3; + III.IsCommutative = false; + III.ImmOpNo = 2; + III.ConstantOpNo = 3; + switch(Opc) { + default: llvm_unreachable("Unknown opcode"); + case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break; + case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break; + case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break; + case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break; + case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break; + case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break; + case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break; + case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break; + case PPC::LDUX: + III.ImmOpcode = PPC::LDU; + III.ImmMustBeMultipleOf = 4; + break; + case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break; + case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break; + case PPC::STBUX: III.ImmOpcode = PPC::STBU; break; + case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break; + case PPC::STHUX: III.ImmOpcode = PPC::STHU; break; + case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break; + case PPC::STWUX: III.ImmOpcode = PPC::STWU; break; + case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break; + case PPC::STDUX: + III.ImmOpcode = PPC::STDU; + III.ImmMustBeMultipleOf = 4; + break; + case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break; + case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break; + } + break; + // Power9 only. + case PPC::LXVX: + case PPC::LXSSPX: + case PPC::LXSDX: + case PPC::STXVX: + case PPC::STXSSPX: + case PPC::STXSDX: + if (!Subtarget.hasP9Vector()) + return false; + III.SignedImm = true; + III.ZeroIsSpecialOrig = 1; + III.ZeroIsSpecialNew = 2; + III.IsCommutative = true; + III.ImmOpNo = 1; + III.ConstantOpNo = 2; + switch(Opc) { + default: llvm_unreachable("Unknown opcode"); + case PPC::LXVX: + III.ImmOpcode = PPC::LXV; + III.ImmMustBeMultipleOf = 16; + break; + case PPC::LXSSPX: + III.ImmOpcode = PPC::LXSSP; + III.ImmMustBeMultipleOf = 4; + break; + case PPC::LXSDX: + III.ImmOpcode = PPC::LXSD; + III.ImmMustBeMultipleOf = 4; + break; + case PPC::STXVX: + III.ImmOpcode = PPC::STXV; + III.ImmMustBeMultipleOf = 16; + break; + case PPC::STXSSPX: + III.ImmOpcode = PPC::STXSSP; + III.ImmMustBeMultipleOf = 4; + break; + case PPC::STXSDX: + III.ImmOpcode = PPC::STXSD; + III.ImmMustBeMultipleOf = 4; + break; + } + break; + } + return true; +} + +// Utility function for swaping two arbitrary operands of an instruction. +static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2) { + assert(Op1 != Op2 && "Cannot swap operand with itself."); + + unsigned MaxOp = std::max(Op1, Op2); + unsigned MinOp = std::min(Op1, Op2); + MachineOperand MOp1 = MI.getOperand(MinOp); + MachineOperand MOp2 = MI.getOperand(MaxOp); + MI.RemoveOperand(std::max(Op1, Op2)); + MI.RemoveOperand(std::min(Op1, Op2)); + + // If the operands we are swapping are the two at the end (the common case) + // we can just remove both and add them in the opposite order. + if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) { + MI.addOperand(MOp2); + MI.addOperand(MOp1); + } else { + // Store all operands in a temporary vector, remove them and re-add in the + // right order. + SmallVector MOps; + unsigned TotalOps = MI.getNumOperands() + 2; // We've already removed 2 ops. + for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) { + MOps.push_back(MI.getOperand(i)); + MI.RemoveOperand(i); + } + // MOp2 needs to be added next. + MI.addOperand(MOp2); + // Now add the rest. + for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) { + if (i == MaxOp) + MI.addOperand(MOp1); + else { + MI.addOperand(MOps.back()); + MOps.pop_back(); + } + } + } +} + +bool PPCInstrInfo::transformToImmForm(MachineInstr &MI, const ImmInstrInfo &III, + unsigned ConstantOpNo, + int64_t Imm) const { + MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo(); + bool PostRA = !MRI.isSSA(); + // Exit early if we can't convert this. + if ((ConstantOpNo != III.ConstantOpNo) && !III.IsCommutative) + return false; + if (Imm % III.ImmMustBeMultipleOf) + return false; + if (III.SignedImm) { + APInt ActualValue(64, Imm, true); + if (!ActualValue.isSignedIntN(III.ImmWidth)) + return false; + } else { + uint64_t UnsignedMax = (1 << III.ImmWidth) - 1; + if ((uint64_t)Imm > UnsignedMax) + return false; + } + + // If we're post-RA, the instructions don't agree on whether register zero is + // special, we can transform this as long as the register operand that will + // end up in the location where zero is special isn't R0. + if (PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) { + unsigned PosForOrigZero = III.ZeroIsSpecialOrig ? III.ZeroIsSpecialOrig : + III.ZeroIsSpecialNew + 1; + unsigned OrigZeroReg = MI.getOperand(PosForOrigZero).getReg(); + unsigned NewZeroReg = MI.getOperand(III.ZeroIsSpecialNew).getReg(); + // If R0 is in the operand where zero is special for the new instruction, + // it is unsafe to transform if the constant operand isn't that operand. + if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) && + ConstantOpNo != III.ZeroIsSpecialNew) + return false; + if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) && + ConstantOpNo != PosForOrigZero) + return false; + } + + unsigned Opc = MI.getOpcode(); + bool SpecialShift32 = + Opc == PPC::SLW || Opc == PPC::SLWo || Opc == PPC::SRW || Opc == PPC::SRWo; + bool SpecialShift64 = + Opc == PPC::SLD || Opc == PPC::SLDo || Opc == PPC::SRD || Opc == PPC::SRDo; + bool SetCR = Opc == PPC::SLWo || Opc == PPC::SRWo || + Opc == PPC::SLDo || Opc == PPC::SRDo; + bool RightShift = + Opc == PPC::SRW || Opc == PPC::SRWo || Opc == PPC::SRD || Opc == PPC::SRDo; + + MI.setDesc(get(III.ImmOpcode)); + if (ConstantOpNo == III.ConstantOpNo) { + // Converting shifts to immediate form is a bit tricky since they may do + // one of three things: + // 1. If the shift amount is between OpSize and 2*OpSize, the result is zero + // 2. If the shift amount is zero, the result is unchanged (save for maybe + // setting CR0) + // 3. If the shift amount is in [1, OpSize), it's just a shift + if (SpecialShift32 || SpecialShift64) { + LoadImmediateInfo LII; + LII.Imm = 0; + LII.SetCR = SetCR; + LII.Is64Bit = SpecialShift64; + uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F); + if (Imm & (SpecialShift32 ? 0x20 : 0x40)) + replaceInstrWithLI(MI, LII); + // Shifts by zero don't change the value. If we don't need to set CR0, + // just convert this to a COPY. Can't do this post-RA since we've already + // cleaned up the copies. + else if (!SetCR && ShAmt == 0 && !PostRA) { + MI.RemoveOperand(2); + MI.setDesc(get(PPC::COPY)); + } else { + // The 32 bit and 64 bit instructions are quite different. + if (SpecialShift32) { + // Left shifts use (N, 0, 31-N), right shifts use (32-N, N, 31). + uint64_t SH = RightShift ? 32 - ShAmt : ShAmt; + uint64_t MB = RightShift ? ShAmt : 0; + uint64_t ME = RightShift ? 31 : 31 - ShAmt; + MI.getOperand(III.ConstantOpNo).ChangeToImmediate(SH); + MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB) + .addImm(ME); + } else { + // Left shifts use (N, 63-N), right shifts use (64-N, N). + uint64_t SH = RightShift ? 64 - ShAmt : ShAmt; + uint64_t ME = RightShift ? ShAmt : 63 - ShAmt; + MI.getOperand(III.ConstantOpNo).ChangeToImmediate(SH); + MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME); + } + } + } else + MI.getOperand(ConstantOpNo).ChangeToImmediate(Imm); + } + // Convert commutative instructions (switch the operands and convert the + // desired one to an immediate. + else if (III.IsCommutative) { + MI.getOperand(ConstantOpNo).ChangeToImmediate(Imm); + swapMIOperands(MI, ConstantOpNo, III.ConstantOpNo); + } else + llvm_unreachable("Should have exited early!"); + + // For instructions for which the constant register replaces a different + // operand than where the immediate goes, we need to swap them. + if (III.ConstantOpNo != III.ImmOpNo) + swapMIOperands(MI, III.ConstantOpNo, III.ImmOpNo); + + // If the R0/X0 register is special for the original instruction and not for + // the new instruction (or vice versa), we need to fix up the register class. + if (!PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) { + if (!III.ZeroIsSpecialOrig) { + unsigned RegToModify = MI.getOperand(III.ZeroIsSpecialNew).getReg(); + const TargetRegisterClass *NewRC = + MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ? + &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass; + MRI.setRegClass(RegToModify, NewRC); + } + } + return true; +} + const TargetRegisterClass * PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const { if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass) diff --git a/lib/Target/PowerPC/PPCInstrInfo.h b/lib/Target/PowerPC/PPCInstrInfo.h index 097faf7873c..4271c50127a 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.h +++ b/lib/Target/PowerPC/PPCInstrInfo.h @@ -72,6 +72,41 @@ enum { }; } // end namespace PPCII +// Instructions that have an immediate form might be convertible to that +// form if the correct input is a result of a load immediate. In order to +// know whether the transformation is special, we might need to know some +// of the details of the two forms. +struct ImmInstrInfo { + // Is the immediate field in the immediate form signed or unsigned? + uint64_t SignedImm : 1; + // Does the immediate need to be a multiple of some value? + uint64_t ImmMustBeMultipleOf : 5; + // Is R0/X0 treated specially by the original r+r instruction? + // If so, in which operand? + uint64_t ZeroIsSpecialOrig : 3; + // Is R0/X0 treated specially by the new r+i instruction? + // If so, in which operand? + uint64_t ZeroIsSpecialNew : 3; + // Is the operation commutative? + uint64_t IsCommutative : 1; + // The operand number to check for load immediate. + uint64_t ConstantOpNo : 3; + // The operand number for the immediate. + uint64_t ImmOpNo : 3; + // The opcode of the new instruction. + uint64_t ImmOpcode : 16; + // The size of the immediate. + uint64_t ImmWidth : 5; +}; + +// Information required to convert an instruction to just a materialized +// immediate. +struct LoadImmediateInfo { + unsigned Imm : 16; + unsigned Is64Bit : 1; + unsigned SetCR : 1; +}; + class PPCSubtarget; class PPCInstrInfo : public PPCGenInstrInfo { PPCSubtarget &Subtarget; @@ -87,6 +122,10 @@ class PPCInstrInfo : public PPCGenInstrInfo { const TargetRegisterClass *RC, SmallVectorImpl &NewMIs, bool &NonRI, bool &SpillsVRS) const; + bool transformToImmForm(MachineInstr &MI, const ImmInstrInfo &III, + unsigned ConstantOpNo, int64_t Imm) const; + MachineInstr *getConstantDefMI(MachineInstr &MI, unsigned &ConstOp, + bool &SeenIntermediateUse) const; virtual void anchor(); protected: @@ -313,6 +352,19 @@ public: bool isZeroExtended(const MachineInstr &MI, const unsigned depth = 0) const { return isSignOrZeroExtended(MI, false, depth); } + + bool convertToImmediateForm(MachineInstr &MI, + MachineInstr **KilledDef = nullptr) const; + void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) 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); + bool instrHasImmForm(const MachineInstr &MI, ImmInstrInfo &III) const; }; } diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 181dbb904e3..a932d05b24e 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -1590,6 +1590,11 @@ def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 0)), (ICBT 0, xoaddr:$dst)>, Requires<[HasICBT]>; // inst prefetch (for read) // Atomic operations +// FIXME: some of these might be used with constant operands. This will result +// in constant materialization instructions that may be redundant. We currently +// clean this up in PPCMIPeephole with calls to +// PPCInstrInfo::convertToImmediateForm() but we should probably not emit them +// in the first place. let usesCustomInserter = 1 in { let Defs = [CR0] in { def ATOMIC_LOAD_ADD_I8 : Pseudo< diff --git a/lib/Target/PowerPC/PPCMIPeephole.cpp b/lib/Target/PowerPC/PPCMIPeephole.cpp index 2f44b8c13a3..45647a2c36b 100644 --- a/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -41,6 +41,22 @@ STATISTIC(MultiTOCSaves, STATISTIC(NumEliminatedSExt, "Number of eliminated sign-extensions"); STATISTIC(NumEliminatedZExt, "Number of eliminated zero-extensions"); STATISTIC(NumOptADDLIs, "Number of optimized ADD instruction fed by LI"); +STATISTIC(NumConvertedToImmediateForm, + "Number of instructions converted to their immediate form"); +STATISTIC(NumFunctionsEnteredInMIPeephole, + "Number of functions entered in PPC MI Peepholes"); +STATISTIC(NumFixedPointIterations, + "Number of fixed-point iterations converting reg-reg instructions " + "to reg-imm ones"); + +static cl::opt +FixedPointRegToImm("ppc-reg-to-imm-fixed-point", cl::Hidden, cl::init(true), + cl::desc("Iterate to a fixed point when attempting to " + "convert reg-reg instructions to reg-imm")); + +static cl::opt +ConvertRegReg("ppc-convert-rr-to-ri", cl::Hidden, cl::init(true), + cl::desc("Convert eligible reg+reg instructions to reg+imm")); static cl::opt EnableSExtElimination("ppc-eliminate-signext", @@ -52,10 +68,6 @@ static cl::opt cl::desc("enable elimination of zero-extensions"), cl::init(false), cl::Hidden); -namespace llvm { - void initializePPCMIPeepholePass(PassRegistry&); -} - namespace { struct PPCMIPeephole : public MachineFunctionPass { @@ -83,9 +95,6 @@ private: bool eliminateRedundantTOCSaves(std::map &TOCSaves); void UpdateTOCSaves(std::map &TOCSaves, MachineInstr *MI); - // Find the "true" register represented by SrcReg (following chains - // of copies and subreg_to_reg operations). - unsigned lookThruCopyLike(unsigned SrcReg); public: @@ -212,6 +221,35 @@ bool PPCMIPeephole::simplifyCode(void) { MachineInstr* ToErase = nullptr; std::map TOCSaves; + NumFunctionsEnteredInMIPeephole++; + if (ConvertRegReg) { + // 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 { + NumFixedPointIterations++; + 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 && FixedPointRegToImm); + } + for (MachineBasicBlock &MBB : *MF) { for (MachineInstr &MI : MBB) { @@ -258,8 +296,10 @@ bool PPCMIPeephole::simplifyCode(void) { // 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)) { @@ -273,7 +313,8 @@ bool PPCMIPeephole::simplifyCode(void) { 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) @@ -299,10 +340,10 @@ bool PPCMIPeephole::simplifyCode(void) { // 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() @@ -360,7 +401,8 @@ bool PPCMIPeephole::simplifyCode(void) { 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); @@ -422,7 +464,8 @@ bool PPCMIPeephole::simplifyCode(void) { } 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); @@ -430,8 +473,10 @@ bool PPCMIPeephole::simplifyCode(void) { // 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; @@ -1221,36 +1266,6 @@ bool PPCMIPeephole::eliminateRedundantCompare(void) { 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, diff --git a/lib/Target/PowerPC/PPCPreEmitPeephole.cpp b/lib/Target/PowerPC/PPCPreEmitPeephole.cpp new file mode 100644 index 00000000000..df0e9f3515a --- /dev/null +++ b/lib/Target/PowerPC/PPCPreEmitPeephole.cpp @@ -0,0 +1,95 @@ +//===--------- PPCPreEmitPeephole.cpp - Late peephole optimizations -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// A pre-emit peephole for catching opportunities introduced by late passes such +// as MachineBlockPlacement. +// +//===----------------------------------------------------------------------===// + +#include "PPC.h" +#include "PPCInstrInfo.h" +#include "PPCSubtarget.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/LivePhysRegs.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Debug.h" + +using namespace llvm; + +#define DEBUG_TYPE "ppc-pre-emit-peephole" + +STATISTIC(NumRRConvertedInPreEmit, + "Number of r+r instructions converted to r+i in pre-emit peephole"); +STATISTIC(NumRemovedInPreEmit, + "Number of instructions deleted in pre-emit peephole"); + +static cl::opt +RunPreEmitPeephole("ppc-late-peephole", cl::Hidden, cl::init(true), + cl::desc("Run pre-emit peephole optimizations.")); + +namespace { + class PPCPreEmitPeephole : public MachineFunctionPass { + public: + static char ID; + PPCPreEmitPeephole() : MachineFunctionPass(ID) { + initializePPCPreEmitPeepholePass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + MachineFunctionPass::getAnalysisUsage(AU); + } + + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoVRegs); + } + + bool runOnMachineFunction(MachineFunction &MF) override { + if (skipFunction(*MF.getFunction()) || !RunPreEmitPeephole) + return false; + bool Changed = false; + const PPCInstrInfo *TII = MF.getSubtarget().getInstrInfo(); + SmallVector InstrsToErase; + for (MachineBasicBlock &MBB : MF) { + for (MachineInstr &MI : MBB) { + MachineInstr *DefMIToErase = nullptr; + if (TII->convertToImmediateForm(MI, &DefMIToErase)) { + Changed = true; + NumRRConvertedInPreEmit++; + DEBUG(dbgs() << "Converted instruction to imm form: "); + DEBUG(MI.dump()); + if (DefMIToErase) { + InstrsToErase.push_back(DefMIToErase); + } + } + } + } + for (MachineInstr *MI : InstrsToErase) { + DEBUG(dbgs() << "PPC pre-emit peephole: erasing instruction: "); + DEBUG(MI->dump()); + MI->eraseFromParent(); + NumRemovedInPreEmit++; + } + return Changed; + } + }; +} + +INITIALIZE_PASS(PPCPreEmitPeephole, DEBUG_TYPE, "PowerPC Pre-Emit Peephole", + false, false) +char PPCPreEmitPeephole::ID = 0; + +FunctionPass *llvm::createPPCPreEmitPeepholePass() { + return new PPCPreEmitPeephole(); +} diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index c934668a80c..491f25ca2c6 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -101,7 +101,9 @@ extern "C" void LLVMInitializePowerPCTarget() { PassRegistry &PR = *PassRegistry::getPassRegistry(); initializePPCBoolRetToIntPass(PR); initializePPCExpandISELPass(PR); + initializePPCPreEmitPeepholePass(PR); initializePPCTLSDynamicCallPass(PR); + initializePPCMIPeepholePass(PR); } /// Return the datalayout string of a subtarget. @@ -440,6 +442,7 @@ void PPCPassConfig::addPreSched2() { } void PPCPassConfig::addPreEmitPass() { + addPass(createPPCPreEmitPeepholePass()); addPass(createPPCExpandISELPass()); if (getOptLevel() != CodeGenOpt::None) diff --git a/test/CodeGen/PowerPC/build-vector-tests.ll b/test/CodeGen/PowerPC/build-vector-tests.ll index fd1f4589870..16b562bfb9f 100644 --- a/test/CodeGen/PowerPC/build-vector-tests.ll +++ b/test/CodeGen/PowerPC/build-vector-tests.ll @@ -3508,13 +3508,13 @@ entry: ; P9LE: xxmrghd ; P9LE-NEXT: xvcvdpsxds v2 ; P9LE-NEXT: blr -; P8BE: lfsx -; P8BE: lfsx +; P8BE: lfs +; P8BE: lfs ; P8BE: xxmrghd ; P8BE-NEXT: xvcvdpsxds v2 ; P8BE-NEXT: blr -; P8LE: lfsx -; P8LE: lfsx +; P8LE: lfs +; P8LE: lfs ; P8LE: xxmrghd ; P8LE-NEXT: xvcvdpsxds v2 ; P8LE-NEXT: blr @@ -3546,13 +3546,13 @@ entry: ; P9LE: xxmrghd ; P9LE-NEXT: xvcvdpsxds v2 ; P9LE-NEXT: blr -; P8BE: lfsx -; P8BE: lfsx +; P8BE: lfs +; P8BE: lfs ; P8BE: xxmrghd ; P8BE-NEXT: xvcvdpsxds v2 ; P8BE-NEXT: blr -; P8LE: lfsx -; P8LE: lfsx +; P8LE: lfs +; P8LE: lfs ; P8LE: xxmrghd ; P8LE-NEXT: xvcvdpsxds v2 ; P8LE-NEXT: blr @@ -3591,13 +3591,13 @@ entry: ; P9LE-NEXT: blr ; P8BE: sldi ; P8BE: lfsux -; P8BE: lfsx +; P8BE: lfs ; P8BE: xxmrghd ; P8BE-NEXT: xvcvdpsxds v2 ; P8BE-NEXT: blr ; P8LE: sldi ; P8LE: lfsux -; P8LE: lfsx +; P8LE: lfs ; P8LE: xxmrghd ; P8LE-NEXT: xvcvdpsxds v2 ; P8LE-NEXT: blr @@ -3636,13 +3636,13 @@ entry: ; P9LE-NEXT: blr ; P8BE: sldi ; P8BE: lfsux -; P8BE: lfsx +; P8BE: lfs ; P8BE: xxmrghd ; P8BE-NEXT: xvcvdpsxds v2 ; P8BE-NEXT: blr ; P8LE: sldi ; P8LE: lfsux -; P8LE: lfsx +; P8LE: lfs ; P8LE: xxmrghd ; P8LE-NEXT: xvcvdpsxds v2 ; P8LE-NEXT: blr @@ -3693,11 +3693,11 @@ entry: ; P9LE-NEXT: xscvdpsxds ; P9LE-NEXT: xxspltd v2 ; P9LE-NEXT: blr -; P8BE: lfsx +; P8BE: lfs ; P8BE-NEXT: xscvdpsxds ; P8BE-NEXT: xxspltd v2 ; P8BE-NEXT: blr -; P8LE: lfsx +; P8LE: lfs ; P8LE-NEXT: xscvdpsxds ; P8LE-NEXT: xxspltd v2 ; P8LE-NEXT: blr @@ -4412,13 +4412,13 @@ entry: ; P9LE: xxmrghd ; P9LE-NEXT: xvcvdpuxds v2 ; P9LE-NEXT: blr -; P8BE: lfsx -; P8BE: lfsx +; P8BE: lfs +; P8BE: lfs ; P8BE: xxmrghd ; P8BE-NEXT: xvcvdpuxds v2 ; P8BE-NEXT: blr -; P8LE: lfsx -; P8LE: lfsx +; P8LE: lfs +; P8LE: lfs ; P8LE: xxmrghd ; P8LE-NEXT: xvcvdpuxds v2 ; P8LE-NEXT: blr @@ -4450,13 +4450,13 @@ entry: ; P9LE: xxmrghd ; P9LE-NEXT: xvcvdpuxds v2 ; P9LE-NEXT: blr -; P8BE: lfsx -; P8BE: lfsx +; P8BE: lfs +; P8BE: lfs ; P8BE: xxmrghd ; P8BE-NEXT: xvcvdpuxds v2 ; P8BE-NEXT: blr -; P8LE: lfsx -; P8LE: lfsx +; P8LE: lfs +; P8LE: lfs ; P8LE: xxmrghd ; P8LE-NEXT: xvcvdpuxds v2 ; P8LE-NEXT: blr @@ -4495,13 +4495,13 @@ entry: ; P9LE-NEXT: blr ; P8BE: sldi ; P8BE: lfsux -; P8BE: lfsx +; P8BE: lfs ; P8BE: xxmrghd ; P8BE-NEXT: xvcvdpuxds v2 ; P8BE-NEXT: blr ; P8LE: sldi ; P8LE: lfsux -; P8LE: lfsx +; P8LE: lfs ; P8LE: xxmrghd ; P8LE-NEXT: xvcvdpuxds v2 ; P8LE-NEXT: blr @@ -4540,13 +4540,13 @@ entry: ; P9LE-NEXT: blr ; P8BE: sldi ; P8BE: lfsux -; P8BE: lfsx +; P8BE: lfs ; P8BE: xxmrghd ; P8BE-NEXT: xvcvdpuxds v2 ; P8BE-NEXT: blr ; P8LE: sldi ; P8LE: lfsux -; P8LE: lfsx +; P8LE: lfs ; P8LE: xxmrghd ; P8LE-NEXT: xvcvdpuxds v2 ; P8LE-NEXT: blr @@ -4597,11 +4597,11 @@ entry: ; P9LE-NEXT: xscvdpuxds ; P9LE-NEXT: xxspltd v2 ; P9LE-NEXT: blr -; P8BE: lfsx +; P8BE: lfs ; P8BE-NEXT: xscvdpuxds ; P8BE-NEXT: xxspltd v2 ; P8BE-NEXT: blr -; P8LE: lfsx +; P8LE: lfs ; P8LE-NEXT: xscvdpuxds ; P8LE-NEXT: xxspltd v2 ; P8LE-NEXT: blr diff --git a/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir b/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir new file mode 100644 index 00000000000..754f83825a2 --- /dev/null +++ b/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir @@ -0,0 +1,436 @@ +# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s +--- | + ; ModuleID = 'a.ll' + source_filename = "a.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @unsafeAddR0R3(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %add = add nsw i32 %b, %a + ret i32 %add + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @unsafeAddR3R0(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %add = add nsw i32 %b, %a + ret i32 %add + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @safeAddR0R3(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %add = add nsw i32 %b, %a + ret i32 %add + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @safeAddR3R0(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %add = add nsw i32 %b, %a + ret i32 %add + } + + ; Function Attrs: norecurse nounwind readonly + define i64 @unsafeLDXR3R0(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 { + entry: + %0 = bitcast i64* %ptr to i8* + %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off + %1 = bitcast i8* %add.ptr to i64* + %2 = load i64, i64* %1, align 8, !tbaa !3 + ret i64 %2 + } + + ; Function Attrs: norecurse nounwind readonly + define i64 @safeLDXZeroR3(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 { + entry: + %0 = bitcast i64* %ptr to i8* + %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off + %1 = bitcast i8* %add.ptr to i64* + %2 = load i64, i64* %1, align 8, !tbaa !3 + ret i64 %2 + } + + ; Function Attrs: norecurse nounwind readonly + define i64 @safeLDXR3R0(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 { + entry: + %0 = bitcast i64* %ptr to i8* + %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off + %1 = bitcast i8* %add.ptr to i64* + %2 = load i64, i64* %1, align 8, !tbaa !3 + ret i64 %2 + } + + 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" } + attributes #1 = { norecurse nounwind readonly "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, !1} + !llvm.ident = !{!2} + + !0 = !{i32 1, !"wchar_size", i32 4} + !1 = !{i32 7, !"PIC Level", i32 2} + !2 = !{!"clang version 6.0.0 (trunk 318832)"} + !3 = !{!4, !4, i64 0} + !4 = !{!"long long", !5, i64 0} + !5 = !{!"omnipotent char", !6, i64 0} + !6 = !{!"Simple C/C++ TBAA"} + +... +--- +name: unsafeAddR0R3 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x0, %x4 + + %1:g8rc = COPY %x4 + %0:g8rc = COPY %x0 + %2:gprc = LI 44 + %3:gprc = COPY %1.sub_32 + %4:gprc = ADD4 killed %r0, killed %2 + ; CHECK: li 3, 44 + ; CHECK: add 3, 0, 3 + %5:g8rc = EXTSW_32_64 killed %4 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: unsafeAddR3R0 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x0, %x4 + + %1:g8rc = COPY %x4 + %0:g8rc = COPY %x0 + %2:gprc = COPY %0.sub_32 + %3:gprc = LI 44 + %4:gprc = ADD4 killed %3, killed %r0 + ; CHECK: li 3, 44 + ; CHECK: add 3, 3, 0 + %5:g8rc = EXTSW_32_64 killed %4 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: safeAddR0R3 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1:g8rc = COPY %x4 + %0:g8rc = COPY %x3 + %2:gprc = COPY %0.sub_32 + %r0 = LI 44 + %4:gprc = ADD4 killed %r0, killed %2 + ; CHECK: addi 3, 3, 44 + %5:g8rc = EXTSW_32_64 killed %4 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: safeAddR3R0 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1:g8rc = COPY %x4 + %0:g8rc = COPY %x3 + %2:gprc = COPY %0.sub_32 + %r0 = LI 44 + %4:gprc = ADD4 killed %2, killed %r0 + ; CHECK: addi 3, 3, 44 + %5:g8rc = EXTSW_32_64 killed %4 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: unsafeLDXR3R0 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x0', 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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x0, %x4 + + %1:g8rc = COPY %x4 + %0:g8rc_and_g8rc_nox0 = LI8 44 + %2:g8rc = LDX %0, %x0 :: (load 8 from %ir.1, !tbaa !3) + ; CHECK: li 3, 44 + ; CHECK: ldx 3, 3, 0 + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: safeLDXZeroR3 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1:g8rc = LI8 44 + %0:g8rc_and_g8rc_nox0 = LI8 44 + %2:g8rc = LDX %zero8, %1 :: (load 8 from %ir.1, !tbaa !3) + ; CHECK: ld 3, 44(0) + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: safeLDXR3R0 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %x0 = LI8 44 + %0:g8rc_and_g8rc_nox0 = COPY %x3 + %2:g8rc = LDX %0, %x0 :: (load 8 from %ir.1, !tbaa !3) + ; CHECK: ld 3, 44(3) + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... diff --git a/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir b/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir new file mode 100644 index 00000000000..c4783de4a18 --- /dev/null +++ b/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir @@ -0,0 +1,6129 @@ +# RUN: llc -run-pass ppc-mi-peepholes -ppc-convert-rr-to-ri %s -o - | FileCheck %s +# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s --check-prefix=CHECK-LATE + +--- | + ; ModuleID = 'convert-rr-to-ri-instrs.ll' + source_filename = "convert-rr-to-ri-instrs.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testADD4(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %add = add nsw i32 %a, 33 + %add1 = add nsw i32 %add, %b + ret i32 %add1 + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testADD8(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %add = add nsw i64 %a, 33 + %add1 = add nsw i64 %add, %b + ret i64 %add1 + } + + ; Function Attrs: norecurse nounwind readnone + define i128 @testADDC(i128 %a, i128 %b) local_unnamed_addr #0 { + entry: + %add = add nsw i128 %b, %a + ret i128 %add + } + + ; Function Attrs: norecurse nounwind readnone + define i128 @testADDC8(i128 %a, i128 %b) local_unnamed_addr #0 { + entry: + %add = add nsw i128 %b, %a + ret i128 %add + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testADDCo(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %add = add nsw i64 %b, %a + %cmp = icmp eq i64 %add, 0 + %neg = sext i1 %cmp to i64 + %retval.0 = xor i64 %add, %neg + ret i64 %retval.0 + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testADDI(i32 signext %a) local_unnamed_addr #0 { + entry: + %add = add nsw i32 %a, 44 + ret i32 %add + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testADDI8(i32 signext %a) local_unnamed_addr #0 { + entry: + %add = add nsw i32 %a, 44 + ret i32 %add + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testANDo(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %and = and i64 %b, %a + %tobool = icmp eq i64 %and, 0 + %cond = select i1 %tobool, i64 %b, i64 %a + %conv = trunc i64 %cond to i32 + ret i32 %conv + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testAND8o(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %and = and i64 %b, %a + %tobool = icmp eq i64 %and, 0 + %cond = select i1 %tobool, i64 %b, i64 %a + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testCMPD(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %cmp = icmp sgt i64 %a, %b + %add = select i1 %cmp, i64 0, i64 %a + %cond = add nsw i64 %add, %b + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testCMPDI(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %cmp = icmp sgt i64 %a, 87 + %add = select i1 %cmp, i64 0, i64 %a + %cond = add nsw i64 %add, %b + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testCMPDI_F(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %cmp = icmp sgt i64 %a, 87 + %add = select i1 %cmp, i64 0, i64 %a + %cond = add nsw i64 %add, %b + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testCMPLD(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %cmp = icmp ugt i64 %a, %b + %add = select i1 %cmp, i64 0, i64 %a + %cond = add i64 %add, %b + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testCMPLDI(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %cmp = icmp ugt i64 %a, 87 + %add = select i1 %cmp, i64 0, i64 %a + %cond = add i64 %add, %b + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testCMPW(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %cmp = icmp sgt i32 %a, %b + %add = select i1 %cmp, i32 0, i32 %a + %cond = add nsw i32 %add, %b + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testCMPWI(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %cmp = icmp sgt i32 %a, 87 + %add = select i1 %cmp, i32 0, i32 %a + %cond = add nsw i32 %add, %b + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @testCMPLW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 { + entry: + %cmp = icmp ugt i32 %a, %b + %add = select i1 %cmp, i32 0, i32 %a + %cond = add i32 %add, %b + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @testCMPLWI(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 { + entry: + %cmp = icmp ugt i32 %a, 87 + %add = select i1 %cmp, i32 0, i32 %a + %cond = add i32 %add, %b + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readonly + define zeroext i8 @testLBZUX(i8* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom + %0 = load i8, i8* %arrayidx, align 1, !tbaa !3 + %conv = zext i8 %0 to i32 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2 + %1 = load i8, i8* %arrayidx3, align 1, !tbaa !3 + %conv4 = zext i8 %1 to i32 + %add5 = add nuw nsw i32 %conv4, %conv + %conv6 = trunc i32 %add5 to i8 + ret i8 %conv6 + } + + ; Function Attrs: norecurse nounwind readonly + define zeroext i8 @testLBZX(i8* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom + %0 = load i8, i8* %arrayidx, align 1, !tbaa !3 + %conv = zext i8 %0 to i32 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2 + %1 = load i8, i8* %arrayidx3, align 1, !tbaa !3 + %conv4 = zext i8 %1 to i32 + %add5 = add nuw nsw i32 %conv4, %conv + %conv6 = trunc i32 %add5 to i8 + ret i8 %conv6 + } + + ; Function Attrs: norecurse nounwind readonly + define zeroext i16 @testLHZUX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom + %0 = load i16, i16* %arrayidx, align 2, !tbaa !6 + %conv = zext i16 %0 to i32 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2 + %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6 + %conv4 = zext i16 %1 to i32 + %add5 = add nuw nsw i32 %conv4, %conv + %conv6 = trunc i32 %add5 to i16 + ret i16 %conv6 + } + + ; Function Attrs: norecurse nounwind readonly + define zeroext i16 @testLHZX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom + %0 = load i16, i16* %arrayidx, align 2, !tbaa !6 + %conv = zext i16 %0 to i32 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2 + %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6 + %conv4 = zext i16 %1 to i32 + %add5 = add nuw nsw i32 %conv4, %conv + %conv6 = trunc i32 %add5 to i16 + ret i16 %conv6 + } + + ; Function Attrs: norecurse nounwind readonly + define signext i16 @testLHAUX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom + %0 = load i16, i16* %arrayidx, align 2, !tbaa !6 + %conv9 = zext i16 %0 to i32 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2 + %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6 + %conv410 = zext i16 %1 to i32 + %add5 = add nuw nsw i32 %conv410, %conv9 + %conv6 = trunc i32 %add5 to i16 + ret i16 %conv6 + } + + ; Function Attrs: norecurse nounwind readonly + define signext i16 @testLHAX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom + %0 = load i16, i16* %arrayidx, align 2, !tbaa !6 + %conv9 = zext i16 %0 to i32 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2 + %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6 + %conv410 = zext i16 %1 to i32 + %add5 = add nuw nsw i32 %conv410, %conv9 + %conv6 = trunc i32 %add5 to i16 + ret i16 %conv6 + } + + ; Function Attrs: norecurse nounwind readonly + define zeroext i32 @testLWZUX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom + %0 = load i32, i32* %arrayidx, align 4, !tbaa !8 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2 + %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8 + %add4 = add i32 %1, %0 + ret i32 %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define zeroext i32 @testLWZX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom + %0 = load i32, i32* %arrayidx, align 4, !tbaa !8 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2 + %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8 + %add4 = add i32 %1, %0 + ret i32 %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define i64 @testLWAX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom + %0 = load i32, i32* %arrayidx, align 4, !tbaa !8 + %conv = sext i32 %0 to i64 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2 + %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8 + %conv4 = sext i32 %1 to i64 + %add5 = add nsw i64 %conv4, %conv + ret i64 %add5 + } + + ; Function Attrs: norecurse nounwind readonly + define i64 @testLDUX(i64* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom + %0 = load i64, i64* %arrayidx, align 8, !tbaa !10 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2 + %1 = load i64, i64* %arrayidx3, align 8, !tbaa !10 + %add4 = add i64 %1, %0 + ret i64 %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define i64 @testLDX(i64* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom + %0 = load i64, i64* %arrayidx, align 8, !tbaa !10 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2 + %1 = load i64, i64* %arrayidx3, align 8, !tbaa !10 + %add4 = add i64 %1, %0 + ret i64 %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define double @testLFDUX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom + %0 = load double, double* %arrayidx, align 8, !tbaa !12 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2 + %1 = load double, double* %arrayidx3, align 8, !tbaa !12 + %add4 = fadd double %0, %1 + ret double %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define double @testLFDX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom + %0 = load double, double* %arrayidx, align 8, !tbaa !12 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2 + %1 = load double, double* %arrayidx3, align 8, !tbaa !12 + %add4 = fadd double %0, %1 + ret double %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define <4 x float> @testLFSUX(float* nocapture readonly %ptr, i32 signext %idx) local_unnamed_addr #2 { + entry: + %idxprom = sext i32 %idx to i64 + %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom + %0 = load float, float* %arrayidx, align 4, !tbaa !14 + %conv = fptoui float %0 to i32 + %vecinit = insertelement <4 x i32> undef, i32 %conv, i32 0 + %1 = bitcast float* %ptr to i8* + %2 = shl i64 %idxprom, 2 + %uglygep = getelementptr i8, i8* %1, i64 %2 + %uglygep2 = getelementptr i8, i8* %uglygep, i64 4 + %3 = bitcast i8* %uglygep2 to float* + %4 = load float, float* %3, align 4, !tbaa !14 + %conv3 = fptoui float %4 to i32 + %vecinit4 = insertelement <4 x i32> %vecinit, i32 %conv3, i32 1 + %uglygep5 = getelementptr i8, i8* %uglygep, i64 8 + %5 = bitcast i8* %uglygep5 to float* + %6 = load float, float* %5, align 4, !tbaa !14 + %conv8 = fptoui float %6 to i32 + %vecinit9 = insertelement <4 x i32> %vecinit4, i32 %conv8, i32 2 + %uglygep8 = getelementptr i8, i8* %uglygep, i64 12 + %7 = bitcast i8* %uglygep8 to float* + %8 = load float, float* %7, align 4, !tbaa !14 + %conv13 = fptoui float %8 to i32 + %vecinit14 = insertelement <4 x i32> %vecinit9, i32 %conv13, i32 3 + %9 = bitcast <4 x i32> %vecinit14 to <4 x float> + ret <4 x float> %9 + } + + ; Function Attrs: norecurse nounwind readonly + define float @testLFSX(float* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom + %0 = load float, float* %arrayidx, align 4, !tbaa !14 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2 + %1 = load float, float* %arrayidx3, align 4, !tbaa !14 + %add4 = fadd float %0, %1 + ret float %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define double @testLXSDX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom + %0 = load double, double* %arrayidx, align 8, !tbaa !12 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2 + %1 = load double, double* %arrayidx3, align 8, !tbaa !12 + %add4 = fadd double %0, %1 + ret double %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define float @testLXSSPX(float* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom + %0 = load float, float* %arrayidx, align 4, !tbaa !14 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2 + %1 = load float, float* %arrayidx3, align 4, !tbaa !14 + %add4 = fadd float %0, %1 + ret float %add4 + } + + ; Function Attrs: norecurse nounwind readonly + define <4 x i32> @testLXVX(<4 x i32>* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom + %0 = load <4 x i32>, <4 x i32>* %arrayidx, align 16, !tbaa !3 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom2 + %1 = load <4 x i32>, <4 x i32>* %arrayidx3, align 16, !tbaa !3 + %add4 = add <4 x i32> %1, %0 + ret <4 x i32> %add4 + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testOR(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %or = or i32 %b, %a + ret i32 %or + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testOR8(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %or = or i64 %b, %a + ret i64 %or + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testORI(i32 signext %a) local_unnamed_addr #0 { + entry: + %or = or i32 %a, 88 + ret i32 %or + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testORI8(i64 %a) local_unnamed_addr #0 { + entry: + %or = or i64 %a, 99 + ret i64 %or + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testRLDCL(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %and = and i64 %b, 63 + %shl = shl i64 %a, %and + %sub = sub nsw i64 64, %and + %shr = lshr i64 %a, %sub + %or = or i64 %shr, %shl + ret i64 %or + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testRLDCLo(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %and = and i64 %b, 63 + %shl = shl i64 %a, %and + %sub = sub nsw i64 64, %and + %shr = lshr i64 %a, %sub + %or = or i64 %shr, %shl + %tobool = icmp eq i64 %or, 0 + %cond = select i1 %tobool, i64 %and, i64 %a + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testRLDCR(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %and = and i64 %b, 63 + %shl = shl i64 %a, %and + %sub = sub nsw i64 64, %and + %shr = lshr i64 %a, %sub + %or = or i64 %shr, %shl + ret i64 %or + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testRLDCRo(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %and = and i64 %b, 63 + %shl = shl i64 %a, %and + %sub = sub nsw i64 64, %and + %shr = lshr i64 %a, %sub + %or = or i64 %shr, %shl + %tobool = icmp eq i64 %or, 0 + %cond = select i1 %tobool, i64 %and, i64 %a + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testRLDICL(i64 %a) local_unnamed_addr #0 { + entry: + %shr = lshr i64 %a, 11 + %and = and i64 %shr, 16777215 + ret i64 %and + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testRLDICLo(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %shr = lshr i64 %a, 11 + %and = and i64 %shr, 16777215 + %tobool = icmp eq i64 %and, 0 + %cond = select i1 %tobool, i64 %b, i64 %and + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @testRLWINM(i32 zeroext %a) local_unnamed_addr #0 { + entry: + %shl = shl i32 %a, 4 + %and = and i32 %shl, 4080 + ret i32 %and + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testRLWINM8(i64 %a) local_unnamed_addr #0 { + entry: + %shl = shl i64 %a, 4 + %and = and i64 %shl, 4080 + ret i64 %and + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @testRLWINMo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 { + entry: + %and = and i32 %a, 255 + %tobool = icmp eq i32 %and, 0 + %cond = select i1 %tobool, i32 %b, i32 %a + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testRLWINM8o(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %a.tr = trunc i64 %a to i32 + %0 = shl i32 %a.tr, 4 + %conv = and i32 %0, 4080 + %tobool = icmp eq i32 %conv, 0 + %conv1 = zext i32 %conv to i64 + %cond = select i1 %tobool, i64 %b, i64 %conv1 + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testSLD(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %shl = shl i64 %a, %b + ret i64 %shl + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testSLDo(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %shl = shl i64 %a, %b + %tobool = icmp eq i64 %shl, 0 + %cond = select i1 %tobool, i64 %b, i64 %a + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testSRD(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %shr = lshr i64 %a, %b + ret i64 %shr + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testSRDo(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %shr = lshr i64 %a, %b + %tobool = icmp eq i64 %shr, 0 + %cond = select i1 %tobool, i64 %b, i64 %a + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @testSLW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 { + entry: + %shl = shl i32 %a, %b + ret i32 %shl + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @testSLWo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 { + entry: + %shl = shl i32 %a, %b + %tobool = icmp eq i32 %shl, 0 + %cond = select i1 %tobool, i32 %b, i32 %a + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @testSRW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 { + entry: + %shr = lshr i32 %a, %b + ret i32 %shr + } + + ; Function Attrs: norecurse nounwind readnone + define zeroext i32 @testSRWo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 { + entry: + %shr = lshr i32 %a, %b + %tobool = icmp eq i32 %shr, 0 + %cond = select i1 %tobool, i32 %b, i32 %a + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testSRAW(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %shr = ashr i32 %a, %b + ret i32 %shr + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testSRAWo(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %shr = ashr i32 %a, %b + %tobool = icmp eq i32 %shr, 0 + %cond = select i1 %tobool, i32 %b, i32 %shr + ret i32 %cond + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testSRAD(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %shr = ashr i64 %a, %b + ret i64 %shr + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testSRADo(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %shr = ashr i64 %a, %b + %tobool = icmp eq i64 %shr, 0 + %cond = select i1 %tobool, i64 %b, i64 %shr + ret i64 %cond + } + + ; Function Attrs: norecurse nounwind + define void @testSTBUX(i8* nocapture %ptr, i8 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom + store i8 %a, i8* %arrayidx, align 1, !tbaa !3 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2 + store i8 %a, i8* %arrayidx3, align 1, !tbaa !3 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTBX(i8* nocapture %ptr, i8 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom + store i8 %a, i8* %arrayidx, align 1, !tbaa !3 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2 + store i8 %a, i8* %arrayidx3, align 1, !tbaa !3 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTHUX(i16* nocapture %ptr, i16 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom + store i16 %a, i16* %arrayidx, align 2, !tbaa !6 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2 + store i16 %a, i16* %arrayidx3, align 2, !tbaa !6 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTHX(i16* nocapture %ptr, i16 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom + store i16 %a, i16* %arrayidx, align 1, !tbaa !3 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2 + store i16 %a, i16* %arrayidx3, align 1, !tbaa !3 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTWUX(i32* nocapture %ptr, i32 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom + store i32 %a, i32* %arrayidx, align 4, !tbaa !8 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2 + store i32 %a, i32* %arrayidx3, align 4, !tbaa !8 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTWX(i32* nocapture %ptr, i32 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom + store i32 %a, i32* %arrayidx, align 4, !tbaa !8 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2 + store i32 %a, i32* %arrayidx3, align 4, !tbaa !8 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTDUX(i64* nocapture %ptr, i64 %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom + store i64 %a, i64* %arrayidx, align 8, !tbaa !10 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2 + store i64 %a, i64* %arrayidx3, align 8, !tbaa !10 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTDX(i64* nocapture %ptr, i64 %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom + store i64 %a, i64* %arrayidx, align 8, !tbaa !10 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2 + store i64 %a, i64* %arrayidx3, align 8, !tbaa !10 + ret void + } + + ; Function Attrs: norecurse nounwind readonly + define void @testSTFSX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #2 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom + store float %a, float* %arrayidx, align 4, !tbaa !14 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2 + store float %a, float* %arrayidx3, align 4, !tbaa !14 + ret void + } + + ; Function Attrs: norecurse nounwind readonly + define void @testSTFSUX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #2 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom + store float %a, float* %arrayidx, align 4, !tbaa !14 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2 + store float %a, float* %arrayidx3, align 4, !tbaa !14 + ret void + } + + ; Function Attrs: norecurse nounwind readonly + define void @testSTFDX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #2 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom + store double %a, double* %arrayidx, align 8, !tbaa !12 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2 + store double %a, double* %arrayidx3, align 8, !tbaa !12 + ret void + } + + ; Function Attrs: norecurse nounwind readonly + define void @testSTFDUX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #2 { + entry: + %add = add i32 %idx, 1 + %idxprom = zext i32 %add to i64 + %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom + store double %a, double* %arrayidx, align 8, !tbaa !12 + %add1 = add i32 %idx, 2 + %idxprom2 = zext i32 %add1 to i64 + %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2 + store double %a, double* %arrayidx3, align 8, !tbaa !12 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTXSSPX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %idxprom = zext i32 %idx to i64 + %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom + store float %a, float* %arrayidx, align 4, !tbaa !14 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTXSDX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %idxprom = zext i32 %idx to i64 + %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom + store double %a, double* %arrayidx, align 8, !tbaa !12 + ret void + } + + ; Function Attrs: norecurse nounwind + define void @testSTXVX(<4 x i32>* nocapture %ptr, <4 x i32> %a, i32 zeroext %idx) local_unnamed_addr #3 { + entry: + %idxprom = zext i32 %idx to i64 + %arrayidx = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom + store <4 x i32> %a, <4 x i32>* %arrayidx, align 16, !tbaa !3 + ret void + } + + ; Function Attrs: norecurse nounwind readnone + define i128 @testSUBFC(i128 %a, i128 %b) local_unnamed_addr #0 { + entry: + %sub = sub nsw i128 %a, %b + ret i128 %sub + } + + ; Function Attrs: norecurse nounwind readnone + define i128 @testSUBFC8(i128 %a, i128 %b) local_unnamed_addr #0 { + entry: + %sub = sub nsw i128 %a, %b + ret i128 %sub + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testXOR(i32 signext %a, i32 signext %b) local_unnamed_addr #0 { + entry: + %xor = xor i32 %b, %a + ret i32 %xor + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testXOR8(i64 %a, i64 %b) local_unnamed_addr #0 { + entry: + %xor = xor i64 %b, %a + ret i64 %xor + } + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @testXORI(i32 signext %a) local_unnamed_addr #0 { + entry: + %xor = xor i32 %a, 17 + ret i32 %xor + } + + ; Function Attrs: norecurse nounwind readnone + define i64 @testXOR8I(i64 %a) local_unnamed_addr #0 { + entry: + %xor = xor i64 %a, 17 + 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"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + attributes #1 = { norecurse nounwind readonly "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"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + attributes #2 = { norecurse nounwind readonly "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"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,-vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + attributes #3 = { norecurse nounwind "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"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + + !llvm.module.flags = !{!0, !1} + !llvm.ident = !{!2} + + !0 = !{i32 1, !"wchar_size", i32 4} + !1 = !{i32 7, !"PIC Level", i32 2} + !2 = !{!"clang version 6.0.0 (trunk 316067)"} + !3 = !{!4, !4, i64 0} + !4 = !{!"omnipotent char", !5, i64 0} + !5 = !{!"Simple C/C++ TBAA"} + !6 = !{!7, !7, i64 0} + !7 = !{!"short", !4, i64 0} + !8 = !{!9, !9, i64 0} + !9 = !{!"int", !4, i64 0} + !10 = !{!11, !11, i64 0} + !11 = !{!"long long", !4, i64 0} + !12 = !{!13, !13, i64 0} + !13 = !{!"double", !4, i64 0} + !14 = !{!15, !15, i64 0} + !15 = !{!"float", !4, i64 0} + +... +--- +name: testADD4 +# CHECK-ALL: name: testADD4 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 33 + %3 = COPY %0.sub_32 + %4 = ADD4 killed %3, %2 + %5 = ADD4 killed %2, killed %4 + ; CHECK: ADDI killed %3, 33 + ; CHECK: ADDI killed %4, 33 + ; CHECK-LATE: addi 3, 3, 33 + ; CHECK-LATE: addi 3, 3, 33 + %6 = EXTSW_32_64 killed %5 + %x3 = COPY %6 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testADD8 +# CHECK-ALL: name: testADD8 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 33 + %0 = COPY %x3 + %2 = ADD8 %0, %1 + %3 = ADD8 killed %1, killed %2 + ; CHECK: ADDI8 %0, 33 + ; CHECK: ADDI8 killed %2, 33 + ; CHECK-LATE: addi 3, 3, 33 + ; CHECK-LATE: addi 3, 3, 33 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testADDC +# CHECK-ALL: name: testADDC +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } + - { reg: '%x6', virtual-reg: '%3' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5, %x6 + + %3 = COPY %x6 + %2 = COPY %x5 + %1 = COPY %x4 + %0 = COPY %x3 + %4 = COPY %0.sub_32 + %5 = LI 55 + %6 = ADDC %5, %4, implicit-def %carry + ; CHECK: ADDIC %4, 55, implicit-def %carry + ; CHECK-LATE: addic 3, 3, 55 + %7 = ADDE8 %3, %1, implicit-def dead %carry, implicit %carry + %8 = EXTSW_32_64 %6 + %x3 = COPY %8 + %x4 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4 + +... +--- +name: testADDC8 +# CHECK-ALL: name: testADDC8 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } + - { reg: '%x6', virtual-reg: '%3' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5, %x6 + + %3 = COPY %x6 + %2 = COPY %x5 + %1 = COPY %x4 + %0 = LI8 777 + %4 = ADDC8 %2, %0, implicit-def %carry + ; CHECK: ADDIC8 %2, 777, implicit-def %carry + ; CHECK-LATE: addic 3, 5, 777 + %5 = ADDE8 %3, %1, implicit-def dead %carry, implicit %carry + %x3 = COPY %4 + %x4 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4 + +... +--- +name: testADDCo +# CHECK-ALL: name: testADDCo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: gprc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: crbitrc, preferred-register: '' } + - { id: 6, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 7, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI 433 + %0 = COPY %x3 + %2 = COPY %0.sub_32 + %3 = ADDCo %1, %2, implicit-def %cr0, implicit-def %carry + ; CHECK: ADDICo %2, 433, implicit-def %cr0, implicit-def %carry + ; CHECK-LATE: addic. 3, 3, 433 + %4 = COPY killed %cr0 + %5 = COPY %4.sub_eq + %6 = LI8 0 + %7 = LI8 -1 + %8 = ISEL8 %7, %6, %5 + %x3 = COPY %8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testADDI +# CHECK-ALL: name: testADDI +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = COPY %x3 + %1 = LI 77 + %2 = ADDI killed %1, 44 + %3 = EXTSW_32_64 killed %2 + ; CHECK: LI 121 + ; CHECK-LATE: li 3, 121 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testADDI8 +# CHECK-ALL: name: testADDI8 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = COPY %x3 + %1 = LI8 333 + %2 = ADDI8 killed %1, 44 + ; CHECK: LI8 377 + ; CHECK-LATE: li 3, 377 + %3 = EXTSW killed %2 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testANDo +# CHECK-ALL: name: testANDo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: gprc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI 78 + %0 = COPY %x3 + %2 = COPY %0.sub_32 + %3 = ANDo %1, %2, implicit-def %cr0 + ; CHECK: ANDIo %2, 78, implicit-def %cr0 + ; CHECK-LATE: andi. 5, 3, 78 + %4 = COPY killed %cr0 + %5 = ISEL %2, %1, %4.sub_eq + %6 = EXTSW_32_64 killed %5 + %x3 = COPY %6 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testAND8o +# CHECK-ALL: name: testAND8o +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: crrc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 321 + %0 = COPY %x3 + %2 = AND8o %1, %0, implicit-def %cr0 + ; CHECK: ANDIo8 %0, 321, implicit-def %cr0 + ; CHECK-LATE: andi. 5, 3, 321 + %3 = COPY killed %cr0 + %4 = ISEL8 %1, %0, %3.sub_eq + %x3 = COPY %4 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPD +# CHECK-ALL: name: testCMPD +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: crrc, preferred-register: '' } + - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 65533 + %0 = COPY %x3 + %2 = CMPD %0, %1 + ; CHECK: CMPDI %0, -3 + ; CHECK-LATE: cmpdi 3, -3 + %4 = ISEL8 %zero8, %0, %2.sub_gt + %5 = ADD8 killed %4, %1 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPDI +# CHECK-ALL: name: testCMPDI +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: crrc, preferred-register: '' } + - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 89 + %2 = CMPDI %0, 87 + %4 = ISEL8 %zero8, %0, %2.sub_gt + ; CHECK: LI8 0 + %5 = ADD8 killed %4, %1 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPDI_F +# CHECK-ALL: name: testCMPDI_F +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: crrc, preferred-register: '' } + - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 87 + %2 = CMPDI %0, 87 + %4 = ISEL8 %zero8, %0, %2.sub_gt + ; CHECK: COPY %0 + %5 = ADD8 killed %4, %1 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPLD +# CHECK-ALL: name: testCMPLD +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: crrc, preferred-register: '' } + - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI8 99 + %0 = COPY %x3 + %2 = CMPLD %0, %1 + ; CHECK: CMPLDI %0, 99 + ; CHECK-LATE: cmpldi 3, 99 + %4 = ISEL8 %zero8, %0, %2.sub_gt + %5 = ADD8 killed %4, %1 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPLDI +# CHECK-ALL: name: testCMPLDI +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: crrc, preferred-register: '' } + - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 65534 + %2 = CMPLDI %0, 65535 + %4 = ISEL8 %zero8, %0, %2.sub_gt + ; CHECK: COPY %0 + %5 = ADD8 killed %4, %1 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPW +# CHECK-ALL: name: testCMPW +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI -1 + %3 = COPY %0.sub_32 + %4 = CMPW %3, %2 + ; CHECK: CMPWI %3, -1 + %6 = ISEL %zero, %3, %4.sub_gt + %7 = ADD4 killed %6, %2 + %8 = EXTSW_32_64 killed %7 + %x3 = COPY %8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPWI +# CHECK-ALL: name: testCMPWI +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = LI -3 + %4 = CMPWI %3, 87 + %6 = ISEL %zero, %3, %4.sub_gt + ; CHECK: COPY %3 + %7 = ADD4 killed %6, killed %2 + %8 = EXTSW_32_64 killed %7 + %x3 = COPY %8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPLW +# CHECK-ALL: name: testCMPLW +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 32767 + %3 = COPY %0.sub_32 + %4 = CMPLW %3, %2 + ; CHECK: CMPLWI %3, 32767 + ; CHECK-LATE: cmplwi 3, 32767 + %6 = ISEL %zero, %3, %4.sub_gt + %7 = ADD4 killed %6, %2 + %9 = IMPLICIT_DEF + %8 = INSERT_SUBREG %9, killed %7, 1 + %10 = RLDICL killed %8, 0, 32 + %x3 = COPY %10 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testCMPLWI +# CHECK-ALL: name: testCMPLWI +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = LI -3 + %4 = CMPLWI %3, 87 + %6 = ISEL %zero, %3, %4.sub_gt + ; CHECK: LI 0 + %7 = ADD4 killed %6, killed %2 + %9 = IMPLICIT_DEF + %8 = INSERT_SUBREG %9, killed %7, 1 + %10 = RLDICL killed %8, 0, 32 + %x3 = COPY %10 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLBZUX +# CHECK-ALL: name: testLBZUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: gprc, preferred-register: '' } + - { id: 14, class: g8rc, preferred-register: '' } + - { id: 15, class: g8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } + - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = RLDICL killed %4, 0, 32 + %7 = LBZX %0, killed %6 :: (load 1 from %ir.arrayidx, !tbaa !3) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -15 + %12,%17 = LBZUX %0, killed %11 :: (load 1 from %ir.arrayidx3, !tbaa !3) + ; CHECK: LBZU -15, %0 + ; CHECK-LATE: lbzu 5, -15(3) + %13 = ADD4 killed %12, killed %7 + %15 = IMPLICIT_DEF + %14 = INSERT_SUBREG %15, killed %13, 1 + %16 = RLWINM8 killed %14, 0, 24, 31 + %x3 = COPY %16 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLBZX +# CHECK-ALL: name: testLBZX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: gprc, preferred-register: '' } + - { id: 14, class: g8rc, preferred-register: '' } + - { id: 15, class: g8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 45 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = RLDICL killed %4, 0, 32 + %7 = LBZX %0, killed %6 :: (load 1 from %ir.arrayidx, !tbaa !3) + ; CHECK: LBZ 45, killed %6 + ; CHECK-LATE: lbz 5, 45(5) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = RLDICL killed %9, 0, 32 + %12 = LBZX %0, killed %11 :: (load 1 from %ir.arrayidx3, !tbaa !3) + ; CHECK: LBZ 45, killed %11 + ; CHECK-LATE: lbz 3, 45(4) + %13 = ADD4 killed %12, killed %7 + %15 = IMPLICIT_DEF + %14 = INSERT_SUBREG %15, killed %13, 1 + %16 = RLWINM8 killed %14, 0, 24, 31 + %x3 = COPY %16 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLHZUX +# CHECK-ALL: name: testLHZUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: gprc, preferred-register: '' } + - { id: 14, class: g8rc, preferred-register: '' } + - { id: 15, class: g8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } + - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = RLDIC killed %4, 1, 31 + %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 31440 + %12,%17 = LHZUX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6) + ; CHECK: LHZU 31440, %0 + ; CHECK-LATE: lhzu 5, 31440(3) + %13 = ADD4 killed %12, killed %7 + %15 = IMPLICIT_DEF + %14 = INSERT_SUBREG %15, killed %13, 1 + %16 = RLWINM8 killed %14, 0, 16, 31 + %x3 = COPY %16 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLHZX +# CHECK-ALL: name: testLHZX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: gprc, preferred-register: '' } + - { id: 14, class: g8rc, preferred-register: '' } + - { id: 15, class: g8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = RLDIC killed %4, 1, 31 + %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 882 + %12 = LHZX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6) + ; CHECK: LHZ 882, %0 + ; CHECK-LATE: lhz 3, 882(3) + %13 = ADD4 killed %12, killed %7 + %15 = IMPLICIT_DEF + %14 = INSERT_SUBREG %15, killed %13, 1 + %16 = RLWINM8 killed %14, 0, 16, 31 + %x3 = COPY %16 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLHAUX +# CHECK-ALL: name: testLHAUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: gprc, preferred-register: '' } + - { id: 14, class: g8rc, preferred-register: '' } + - { id: 15, class: g8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } + - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = RLDIC %4, 1, 31 + %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 400 + %12,%17 = LHAUX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6) + ; CHECK: LHAU 400, %0 + ; CHECK-LATE: lhau 5, 400(3) + %13 = ADD4 killed %12, killed %7 + %15 = IMPLICIT_DEF + %14 = INSERT_SUBREG %15, killed %13, 1 + %16 = EXTSH8 killed %14 + %x3 = COPY %16 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLHAX +# CHECK-ALL: name: testLHAX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: gprc, preferred-register: '' } + - { id: 14, class: g8rc, preferred-register: '' } + - { id: 15, class: g8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 -999 + %7 = LHAX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6) + ; CHECK: LHA -999, %0 + ; CHECK-LATE: lha 4, -999(3) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 999 + %12 = LHAX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6) + ; CHECK: LHA 999, %0 + ; CHECK-LATE: lha 3, 999(3) + %13 = ADD4 killed %12, killed %7 + %15 = IMPLICIT_DEF + %14 = INSERT_SUBREG %15, killed %13, 1 + %16 = EXTSH8 killed %14 + %x3 = COPY %16 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLWZUX +# CHECK-ALL: name: testLWZUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: gprc, preferred-register: '' } + - { id: 14, class: g8rc, preferred-register: '' } + - { id: 15, class: g8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } + - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 18, class: g8rc_and_g8rc_nox0, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 889 + %7,%17 = LWZUX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8) + ; CHECK: LWZU 889, %0 + ; CHECK-LATE: lwzu 5, 889(4) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -2 + %12,%18 = LWZUX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8) + ; CHECK: LWZU -2, %0 + ; CHECK-LATE: lwzu 4, -2(3) + %13 = ADD4 killed %12, killed %7 + %15 = IMPLICIT_DEF + %14 = INSERT_SUBREG %15, killed %13, 1 + %16 = RLDICL killed %14, 0, 32 + %x3 = COPY %16 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLWZX +# CHECK-ALL: name: testLWZX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: gprc, preferred-register: '' } + - { id: 14, class: g8rc, preferred-register: '' } + - { id: 15, class: g8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 1000 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = RLDIC %4, 2, 30 + %7 = LWZX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8) + ; CHECK: LWZ 1000, killed %6 + ; CHECK-LATE: lwz 5, 1000(5) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = RLDIC %9, 2, 30 + %12 = LWZX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8) + ; CHECK: LWZ 1000, killed %11 + ; CHECK-LATE: lwz 3, 1000(4) + %13 = ADD4 killed %12, killed %7 + %15 = IMPLICIT_DEF + %14 = INSERT_SUBREG %15, killed %13, 1 + %16 = RLDICL killed %14, 0, 32 + %x3 = COPY %16 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLWAX +# CHECK-ALL: name: testLWAX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } + - { id: 13, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 444 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = RLDIC %4, 2, 30 + %7 = LWAX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8) + ; CHECK: LWA 444, killed %6 + ; CHECK-LATE: lwa 5, 444(5) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = RLDIC %9, 2, 30 + %12 = LWAX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8) + ; CHECK: LWA 444, killed %11 + ; CHECK-LATE: lwa 3, 444(4) + %13 = ADD8 killed %12, killed %7 + %x3 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLDUX +# CHECK-ALL: name: testLDUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } + - { id: 13, class: g8rc, preferred-register: '' } + - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 15, class: g8rc_and_g8rc_nox0, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 100 + %7,%14 = LDUX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !10) + ; CHECK: LDU 100, %0 + ; CHECK-LATE: ldu 5, 100(4) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 200 + %12,%15 = LDUX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !10) + ; CHECK: LDU 200, %0 + ; CHECK-LATE: ldu 4, 200(3) + %13 = ADD8 killed %12, killed %7 + %x3 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLDX +# CHECK-ALL: name: testLDX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } + - { id: 13, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 120 + %7 = LDX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !10) + ; CHECK: LD 120, %0 + ; CHECK-LATE: ld 4, 120(3) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 280 + %12 = LDX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !10) + ; CHECK: LD 280, %0 + ; CHECK-LATE: ld 12, 280(3) + %13 = ADD8 killed %12, killed %7 + %x3 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testLFDUX +# CHECK-ALL: name: testLFDUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: f8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: f8rc, preferred-register: '' } + - { id: 13, class: f8rc, preferred-register: '' } + - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 15, class: g8rc_and_g8rc_nox0, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 440 + %7,%14 = LFDUX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !12) + ; CHECK: LFDU 440, %0 + ; CHECK-LATE: lfdu 0, 440(4) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 16 + %12,%15 = LFDUX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !12) + ; CHECK: LFDU 16, %0 + ; CHECK-LATE: lfdu 1, 16(3) + %13 = FADD killed %7, killed %12, implicit %rm + %f1 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %f1 + +... +--- +name: testLFDX +# CHECK-ALL: name: testLFDX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: f8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: f8rc, preferred-register: '' } + - { id: 13, class: f8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 -20 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = RLDIC %4, 3, 29 + %7 = LFDX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !12) + ; CHECK: LFD -20, killed %6 + ; CHECK-LATE: lfd 0, -20(5) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = RLDIC %9, 3, 29 + %12 = LFDX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !12) + ; CHECK: LFD -20, killed %11 + ; CHECK-LATE: lfd 1, -20(4) + %13 = FADD killed %7, killed %12, implicit %rm + %f1 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %f1 + +... +--- +name: testLFSUX +# CHECK-ALL: name: testLFSUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: f8rc, preferred-register: '' } + - { id: 4, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 5, class: f8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: f8rc, preferred-register: '' } + - { id: 9, class: f8rc, preferred-register: '' } + - { id: 10, class: f8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: gprc, preferred-register: '' } + - { id: 13, class: f8rc, preferred-register: '' } + - { id: 14, class: f8rc, preferred-register: '' } + - { id: 15, class: f8rc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } + - { id: 17, class: gprc, preferred-register: '' } + - { id: 18, class: f8rc, preferred-register: '' } + - { id: 19, class: f8rc, preferred-register: '' } + - { id: 20, class: f8rc, preferred-register: '' } + - { id: 21, class: g8rc, preferred-register: '' } + - { id: 22, class: gprc, preferred-register: '' } + - { id: 23, class: g8rc, preferred-register: '' } + - { id: 24, class: vrrc, preferred-register: '' } +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: 16 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: + - { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 16, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -16, di-variable: '', di-expression: '', di-location: '' } + - { id: 1, name: '', type: default, offset: 0, size: 4, alignment: 4, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -20, di-variable: '', di-expression: '', di-location: '' } + - { id: 2, name: '', type: default, offset: 0, size: 4, alignment: 4, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -24, di-variable: '', di-expression: '', di-location: '' } + - { id: 3, name: '', type: default, offset: 0, size: 4, alignment: 4, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -28, di-variable: '', di-expression: '', di-location: '' } + - { id: 4, name: '', type: default, offset: 0, size: 4, alignment: 4, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -32, di-variable: '', di-expression: '', di-location: '' } +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI8 72 + %3, %4 = LFSUX %0, killed %2 :: (load 4 from %ir.arrayidx, !tbaa !14) + ; CHECK: LFSU 72, %0 + ; CHECK-LATE: lfsu 0, 72(3) + %5 = FCTIWUZ killed %3, implicit %rm + %6 = ADDI8 %stack.4, 0 + STFIWX killed %5, %zero8, killed %6 + %7 = LWZ 0, %stack.4 :: (load 4 from %stack.4) + %8 = LFS 4, %4 :: (load 4 from %ir.3, !tbaa !14) + %10 = FCTIWUZ %8, implicit %rm + %11 = ADDI8 %stack.1, 0 + STFIWX killed %10, %zero8, killed %11 + %12 = LWZ 0, %stack.1 :: (load 4 from %stack.1) + %13 = LFS 8, %4 :: (load 4 from %ir.5, !tbaa !14) + %15 = FCTIWUZ %13, implicit %rm + %16 = ADDI8 %stack.2, 0 + STFIWX killed %15, %zero8, killed %16 + %17 = LWZ 0, %stack.2 :: (load 4 from %stack.2) + %18 = LFS 12, %4 :: (load 4 from %ir.7, !tbaa !14) + %20 = FCTIWUZ %18, implicit %rm + %21 = ADDI8 %stack.3, 0 + STFIWX killed %20, %zero8, killed %21 + %22 = LWZ 0, %stack.3 :: (load 4 from %stack.3) + STW killed %7, 0, %stack.0 :: (store 4 into %stack.0, align 16) + STW killed %22, 12, %stack.0 :: (store 4 into %stack.0 + 12) + STW killed %17, 8, %stack.0 :: (store 4 into %stack.0 + 8, align 8) + STW killed %12, 4, %stack.0 :: (store 4 into %stack.0 + 4) + %23 = ADDI8 %stack.0, 0 + %24 = LVX %zero8, killed %23 :: (load 16 from %stack.0) + %v2 = COPY %24 + BLR8 implicit %lr8, implicit %rm, implicit %v2 + +... +--- +name: testLFSX +# CHECK-ALL: name: testLFSX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: f4rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: f4rc, preferred-register: '' } + - { id: 13, class: f4rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 88 + %7 = LFSX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !14) + ; CHECK: LFS 88, %0 + ; CHECK-LATE: lfs 0, 88(3) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -88 + %12 = LFSX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !14) + ; CHECK: LFS -88, %0 + ; CHECK-LATE: lfs 1, -88(3) + %13 = FADDS killed %7, killed %12, implicit %rm + %f1 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %f1 + +... +--- +name: testLXSDX +# CHECK-ALL: name: testLXSDX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: vsfrc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: vsfrc, preferred-register: '' } + - { id: 13, class: vsfrc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 100 + %7 = LXSDX %0, killed %6, implicit %rm :: (load 8 from %ir.arrayidx, !tbaa !12) + ; CHECK: LXSD 100, %0 + ; CHECK-LATE: lxsd 0, 100(3) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -120 + %12 = LXSDX %0, killed %11, implicit %rm :: (load 8 from %ir.arrayidx3, !tbaa !12) + ; CHECK: LXSD -120, %0 + ; CHECK-LATE: lxsd 1, -120(3) + %13 = XSADDDP killed %7, killed %12, implicit %rm + %f1 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %f1 + +... +--- +name: testLXSSPX +# CHECK-ALL: name: testLXSSPX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: vssrc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: vssrc, preferred-register: '' } + - { id: 13, class: vssrc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 96 + %7 = LXSSPX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !14) + ; CHECK: LXSSP 96, %0 + ; CHECK-LATE: lxssp 0, 96(3) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -92 + %12 = LXSSPX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !14) + ; CHECK: LXSSP -92, %0 + ; CHECK-LATE: lxssp 1, -92(3) + %13 = XSADDSP killed %7, killed %12 + %f1 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %f1 + +... +--- +name: testLXVX +# CHECK-ALL: name: testLXVX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: vrrc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: vrrc, preferred-register: '' } + - { id: 13, class: vrrc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = ADDI %2, 1 + %5 = IMPLICIT_DEF + %4 = INSERT_SUBREG %5, killed %3, 1 + %6 = LI8 32 + %7 = LXVX %0, killed %6 :: (load 16 from %ir.arrayidx, !tbaa !3) + ; CHECK: LXV 32, %0 + ; CHECK-LATE: lxv 34, 32(3) + %8 = ADDI %2, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -16 + %12 = LXVX %0, killed %11 :: (load 16 from %ir.arrayidx3, !tbaa !3) + ; CHECK: LXV -16, %0 + ; CHECK-LATE: lxv 35, -16(3) + %13 = VADDUWM killed %12, killed %7 + %v2 = COPY %13 + BLR8 implicit %lr8, implicit %rm, implicit %v2 + +... +--- +name: testOR +# CHECK-ALL: name: testOR +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: gprc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI 99 + %3 = COPY %1.sub_32 + %2 = OR %0, %3 + ; CHECK: ORI %3, 99 + ; CHECK-LATE: ori 3, 4, 99 + %x3 = EXTSW_32_64 %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testOR8 +# CHECK-ALL: name: testOR8 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 777 + %2 = OR8 %1, %0 + ; CHECK: ORI8 %1, 777 + ; CHECK-LATE: ori 3, 4, 777 + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testORI +# CHECK-ALL: name: testORI +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: gprc, preferred-register: '' } + - { id: 1, class: gprc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI 777 + %1 = ORI %0, 88 + ; CHECK: LI 857 + ; CHECK-LATE: li 3, 857 + %x3 = EXTSW_32_64 %1 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testORI8 +# CHECK-ALL: name: testORI8 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI8 8721 + %1 = ORI8 %0, 99 + ; CHECK: LI8 8819 + ; CHECK-LATE: li 3, 8819 + %x3 = COPY %1 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLDCL +# CHECK-ALL: name: testRLDCL +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = LI 14 + %4 = RLDCL %0, killed %3, 0 + ; CHECK: RLDICL %0, 14, 0 + ; CHECK-LATE: rotldi 3, 3, 14 + %x3 = COPY %4 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLDCLo +# CHECK-ALL: name: testRLDCLo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: crrc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = RLDICL %1, 0, 58 + %3 = LI 37 + %4 = RLDCLo %0, killed %3, 0, implicit-def %cr0 + ; CHECK: RLDICLo %0, 37, 0, implicit-def %cr0 + ; CHECK-LATE: rldicl. 5, 3, 37, 0 + %5 = COPY killed %cr0 + %6 = ISEL8 %2, %0, %5.sub_eq + %x3 = COPY %6 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLDCR +# CHECK-ALL: name: testRLDCR +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = LI 0 + %4 = RLDCR %0, killed %3, 0 + ; CHECK: RLDICR %0, 0, 0 + ; CHECK-LATE: rldicr 3, 3, 0, 0 + %x3 = COPY %4 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLDCRo +# CHECK-ALL: name: testRLDCRo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: crrc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = RLDICL %1, 0, 58 + %3 = LI 18 + %4 = RLDCRo %0, killed %3, 0, implicit-def %cr0 + ; CHECK: RLDICRo %0, 18, 0, implicit-def %cr0 + ; CHECK-LATE: rldicr. 5, 3, 18, 0 + %5 = COPY killed %cr0 + %6 = ISEL8 %2, %0, %5.sub_eq + %x3 = COPY %6 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLDICL +# CHECK-ALL: name: testRLDICL +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI8 -1 + %1 = RLDICL %0, 53, 49 + ; CHECK: LI8 32767 + ; CHECK-LATE: li 3, 32767 + %x3 = COPY %1 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLDICLo +# CHECK-ALL: name: testRLDICLo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 3, class: crrc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 -1 + %2 = RLDICLo %0, 53, 48, implicit-def %cr0 + ; CHECK: ANDIo8 %0, 65535 + ; CHECK-LATE: li 3, -1 + ; CHECK-LATE: andi. 3, 3, 65535 + %3 = COPY killed %cr0 + %4 = ISEL8 %1, %2, %3.sub_eq + %x3 = COPY %4 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLWINM +# CHECK-ALL: name: testRLWINM +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: gprc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = COPY %x3 + %1 = COPY %0.sub_32 + %3 = IMPLICIT_DEF + %2 = LI 17 + %4 = RLWINM killed %2, 4, 20, 27 + ; CHECK: LI 272 + ; CHECK-LATE: li 3, 272 + %x3 = EXTSW_32_64 %4 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLWINM8 +# CHECK-ALL: name: testRLWINM8 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI8 234 + %1 = RLWINM8 %0, 4, 20, 27 + ; CHECK: LI8 3744 + ; CHECK-LATE: li 3, 3744 + %x3 = COPY %1 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLWINMo +# CHECK-ALL: name: testRLWINMo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: crrc, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %3 = LI -22 + %4 = RLWINMo %3, 0, 24, 31, implicit-def %cr0 + ; CHECK: ANDIo %3, 234 + ; CHECK-LATE: li 3, -22 + ; CHECK-LATE: andi. 5, 3, 234 + %5 = COPY killed %cr0 + %6 = ISEL %2, %3, %5.sub_eq + %8 = IMPLICIT_DEF + %7 = INSERT_SUBREG %8, killed %6, 1 + %9 = RLDICL killed %7, 0, 32 + %x3 = COPY %9 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testRLWINM8o +# CHECK-ALL: name: testRLWINM8o +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 7, class: crrc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI8 -18 + %3 = RLWINM8o %2, 4, 20, 27, implicit-def %cr0 + ; CHECK: ANDIo8 %2, 3808 + ; CHECK-LATE: li 3, -18 + ; CHECK-LATE: andi. 3, 3, 3808 + %7 = COPY killed %cr0 + %6 = RLDICL killed %3, 0, 32 + %8 = ISEL8 %1, %6, %7.sub_eq + %x3 = COPY %8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSLD +# CHECK-ALL: name: testSLD +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 13 + %3 = SLD %0, killed %2 + ; CHECK: RLDICR %0, 13, 50 + ; CHECK-LATE: sldi 3, 3, 13 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSLDo +# CHECK-ALL: name: testSLDo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 17 + %3 = SLDo %0, killed %2, implicit-def %cr0 + ; CHECK: RLDICRo %0, 17, 46, implicit-def %cr0 + ; CHECK-LATE: rldicr. 5, 3, 17, 46 + %4 = COPY killed %cr0 + %5 = ISEL8 %1, %0, %4.sub_eq + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSRD +# CHECK-ALL: name: testSRD +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 4 + %3 = SRD %0, killed %2 + ; CHECK: RLDICL %0, 60, 4 + ; CHECK-LATE: rldicl 3, 3, 60, 4 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSRDo +# CHECK-ALL: name: testSRDo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 17 + %3 = SRDo %0, killed %2, implicit-def %cr0 + ; CHECK: RLDICLo %0, 47, 17, implicit-def %cr0 + ; CHECK-LATE: rldicl. 5, 3, 47, 17 + %4 = COPY killed %cr0 + %5 = ISEL8 %1, %0, %4.sub_eq + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSLW +# CHECK-ALL: name: testSLW +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = COPY %1.sub_32 + %5 = LI 21 + %8 = SLW killed %2, killed %5 + ; CHECK: RLWINM killed %2, 21, 0, 10 + ; CHECK-LATE: slwi 3, 4, 21 + %x3 = EXTSW_32_64 %8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSLWo +# CHECK-ALL: name: testSLWo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: crrc, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 11 + %3 = COPY %0.sub_32 + %4 = SLWo %3, %2, implicit-def %cr0 + ; CHECK: RLWINMo %3, 11, 0, 20, implicit-def %cr0 + ; CHECK-LATE: rlwinm. 5, 3, 11, 0, 20 + %5 = COPY killed %cr0 + %6 = ISEL %2, %3, %5.sub_eq + %8 = IMPLICIT_DEF + %7 = INSERT_SUBREG %8, killed %6, 1 + %9 = RLDICL killed %7, 0, 32 + %x3 = COPY %9 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSRW +# CHECK-ALL: name: testSRW +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 8 + %5 = COPY %0.sub_32 + %8 = SRW killed %5, killed %2 + ; CHECK: RLWINM killed %5, 24, 8, 31 + ; CHECK-LATE: srwi 3, 3, 8 + %x3 = EXTSW_32_64 %8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSRWo +# CHECK-ALL: name: testSRWo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: crrc, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 7 + %3 = COPY %0.sub_32 + %4 = SRWo %3, %2, implicit-def %cr0 + ; CHECK: RLWINMo %3, 25, 7, 31 + ; CHECK-LATE: rlwinm. 5, 3, 25, 7, 31 + %5 = COPY killed %cr0 + %6 = ISEL %2, %3, %5.sub_eq + %8 = IMPLICIT_DEF + %7 = INSERT_SUBREG %8, killed %6, 1 + %9 = RLDICL killed %7, 0, 32 + %x3 = COPY %9 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSRAW +# CHECK-ALL: name: testSRAW +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %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-LATE: srawi 3, 3, 15 + %5 = EXTSW_32_64 killed %4 + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSRAWo +# CHECK-ALL: name: testSRAWo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 5, class: crrc, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 8 + %3 = COPY %0.sub_32 + %4 = SRAWo killed %3, %2, implicit-def dead %carry, implicit-def %cr0 + ; CHECK: SRAWIo killed %3, 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 + %7 = EXTSW_32_64 killed %6 + %x3 = COPY %7 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSRAD +# CHECK-ALL: name: testSRAD +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 44 + %3 = SRAD %0, killed %2, implicit-def dead %carry + ; CHECK: SRADI %0, 44, implicit-def dead %carry + ; CHECK-LATE: sradi 3, 3, 44 + %x3 = COPY %3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSRADo +# CHECK-ALL: name: testSRADo +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 4, class: crrc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = COPY %x3 + %2 = LI 61 + %3 = SRADo %0, killed %2, implicit-def dead %carry, implicit-def %cr0 + ; CHECK: SRADIo %0, 61, implicit-def dead %carry, implicit-def %cr0 + ; CHECK-LATE: sradi. 3, 3, 61 + %4 = COPY killed %cr0 + %5 = ISEL8 %1, %3, %4.sub_eq + %x3 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testSTBUX +# CHECK-ALL: name: testSTBUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: gprc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } + - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5 + + %2 = COPY %x5 + %1 = COPY %x4 + %0 = COPY %x3 + %3 = COPY %1.sub_32 + %4 = COPY %2.sub_32 + %5 = ADDI %4, 1 + %7 = IMPLICIT_DEF + %6 = INSERT_SUBREG %7, killed %5, 1 + %8 = LI8 966 + %13 = STBUX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3) + ; CHECK: STBU %3, 966, %0 + ; CHECK-LATE: 4, 966(5) + %9 = ADDI %4, 2 + %11 = IMPLICIT_DEF + %10 = INSERT_SUBREG %11, killed %9, 1 + %12 = LI8 777 + %14 = STBUX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3) + ; CHECK: STBU %3, 777, %0 + ; CHECK-LATE: 4, 777(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTBX +# CHECK-ALL: name: testSTBX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: gprc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5 + + %2 = COPY %x5 + %1 = COPY %x4 + %0 = LI8 975 + %3 = COPY %1.sub_32 + %4 = COPY %2.sub_32 + %5 = ADDI %4, 1 + %7 = IMPLICIT_DEF + %6 = INSERT_SUBREG %7, killed %5, 1 + %8 = RLDICL killed %6, 0, 32 + STBX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3) + ; CHECK: STB %3, 975, killed %8 + ; CHECK-LATE: stb 4, 975(6) + %9 = ADDI %4, 2 + %11 = IMPLICIT_DEF + %10 = INSERT_SUBREG %11, killed %9, 1 + %12 = RLDICL killed %10, 0, 32 + STBX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3) + ; CHECK: STB %3, 975, killed %12 + ; CHECK-LATE: stb 4, 975(5) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTHUX +# CHECK-ALL: name: testSTHUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: gprc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } + - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5 + + %2 = COPY %x5 + %1 = COPY %x4 + %0 = COPY %x3 + %3 = COPY %1.sub_32 + %4 = COPY %2.sub_32 + %5 = ADDI %4, 1 + %7 = IMPLICIT_DEF + %6 = INSERT_SUBREG %7, killed %5, 1 + %8 = LI8 32000 + %13 = STHUX %3, %0, killed %8 :: (store 2 into %ir.arrayidx, !tbaa !6) + ; CHECK: STHU %3, 32000, %0 + ; CHECK-LATE: sthu 4, 32000(5) + %9 = ADDI %4, 2 + %11 = IMPLICIT_DEF + %10 = INSERT_SUBREG %11, killed %9, 1 + %12 = LI8 -761 + %14 = STHUX %3, %0, killed %12 :: (store 2 into %ir.arrayidx3, !tbaa !6) + ; CHECK: STHU %3, -761, %0 + ; CHECK-LATE: sthu 4, -761(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTHX +# CHECK-ALL: name: testSTHX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: gprc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5 + + %2 = COPY %x5 + %1 = COPY %x4 + %0 = COPY %x3 + %3 = COPY %1.sub_32 + %4 = COPY %2.sub_32 + %5 = ADDI %4, 1 + %7 = IMPLICIT_DEF + %6 = INSERT_SUBREG %7, killed %5, 1 + %8 = LI8 900 + STHX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3) + ; CHECK: STH %3, 900, %0 + ; CHECK-LATE: sth 4, 900(3) + %9 = ADDI %4, 2 + %11 = IMPLICIT_DEF + %10 = INSERT_SUBREG %11, killed %9, 1 + %12 = LI8 -900 + STHX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3) + ; CHECK: STH %3, -900, %0 + ; CHECK-LATE: sth 4, -900(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTWUX +# CHECK-ALL: name: testSTWUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: gprc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } + - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5 + + %2 = COPY %x5 + %1 = COPY %x4 + %0 = COPY %x3 + %3 = COPY %1.sub_32 + %4 = COPY %2.sub_32 + %5 = ADDI %4, 1 + %7 = IMPLICIT_DEF + %6 = INSERT_SUBREG %7, killed %5, 1 + %8 = LI8 111 + %13 = STWUX %3, %0, killed %8 :: (store 4 into %ir.arrayidx, !tbaa !8) + ; CHECK: STWU %3, 111, %0 + ; CHECK-LATE: stwu 4, 111(5) + %9 = ADDI %4, 2 + %11 = IMPLICIT_DEF + %10 = INSERT_SUBREG %11, killed %9, 1 + %12 = LI8 0 + %14 = STWUX %3, %0, killed %12 :: (store 4 into %ir.arrayidx3, !tbaa !8) + ; CHECK: STWU %3, 0, %0 + ; CHECK-LATE: stwu 4, 0(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTWX +# CHECK-ALL: name: testSTWX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } + - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: g8rc, preferred-register: '' } + - { id: 9, class: gprc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5 + + %2 = COPY %x5 + %1 = COPY %x4 + %0 = COPY %x3 + %3 = COPY %1.sub_32 + %4 = COPY %2.sub_32 + %5 = ADDI %4, 1 + %7 = IMPLICIT_DEF + %6 = INSERT_SUBREG %7, killed %5, 1 + %8 = LI8 2 + STWX %3, %0, killed %8 :: (store 4 into %ir.arrayidx, !tbaa !8) + ; CHECK: STW %3, 2, %0 + ; CHECK-LATE: stw 4, 2(3) + %9 = ADDI %4, 2 + %11 = IMPLICIT_DEF + %10 = INSERT_SUBREG %11, killed %9, 1 + %12 = LI8 99 + STWX %3, %0, killed %12 :: (store 4 into %ir.arrayidx3, !tbaa !8) + ; CHECK: STW %3, 99, %0 + ; CHECK-LATE: stw 4, 99(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTDUX +# CHECK-ALL: name: testSTDUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5 + + %2 = COPY %x5 + %1 = COPY %x4 + %0 = COPY %x3 + %3 = COPY %2.sub_32 + %4 = ADDI %3, 1 + %6 = IMPLICIT_DEF + %5 = INSERT_SUBREG %6, killed %4, 1 + %7 = LI8 444 + %12 = STDUX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !10) + ; CHECK: STDU %1, 444, %0 + ; CHECK-LATE: stdu 4, 444(5) + %8 = ADDI %3, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -8 + %13 = STDUX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !10) + ; CHECK: STDU %1, -8, %0 + ; CHECK-LATE: stdu 4, -8(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTDX +# CHECK-ALL: name: testSTDX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5 + + %2 = COPY %x5 + %1 = COPY %x4 + %0 = LI8 1000 + %3 = COPY %2.sub_32 + %4 = ADDI %3, 1 + %6 = IMPLICIT_DEF + %5 = INSERT_SUBREG %6, killed %4, 1 + %7 = LI8 900 + STDX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !10) + ; CHECK: STD %1, 1000, killed %7 + ; CHECK-LATE: 4, 1000(5) + %8 = ADDI %3, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -900 + STDX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !10) + ; CHECK: STD %1, 1000, killed %11 + ; CHECK-LATE: 4, 1000(6) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTFSX +# CHECK-ALL: name: testSTFSX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: f4rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%f1', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %f1, %x5 + + %2 = COPY %x5 + %1 = COPY %f1 + %0 = COPY %x3 + %3 = COPY %2.sub_32 + %4 = ADDI %3, 1 + %6 = IMPLICIT_DEF + %5 = INSERT_SUBREG %6, killed %4, 1 + %7 = LI8 400 + STFSX %1, %0, killed %7 :: (store 4 into %ir.arrayidx, !tbaa !14) + ; CHECK: STFS %1, 400, %0 + ; CHECK-LATE: stfs 1, 400(3) + %8 = ADDI %3, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -401 + STFSX %1, %0, killed %11 :: (store 4 into %ir.arrayidx3, !tbaa !14) + ; CHECK: STFS %1, -401, %0 + ; CHECK-LATE: stfs 1, -401(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTFSUX +# CHECK-ALL: name: testSTFSUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: f4rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%f1', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %f1, %x5 + + %2 = COPY %x5 + %1 = COPY %f1 + %0 = COPY %x3 + %3 = COPY %2.sub_32 + %4 = ADDI %3, 1 + %6 = IMPLICIT_DEF + %5 = INSERT_SUBREG %6, killed %4, 1 + %7 = LI8 111 + %12 = STFSUX %1, %0, killed %7 :: (store 4 into %ir.arrayidx, !tbaa !14) + ; CHECK: STFSU %1, 111, %0 + ; CHECK-LATE: stfsu 1, 111(4) + %8 = ADDI %3, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 987 + %13 = STFSUX %1, %0, killed %11 :: (store 4 into %ir.arrayidx3, !tbaa !14) + ; CHECK: STFSU %1, 987, %0 + ; CHECK-LATE: stfsu 1, 987(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTFDX +# CHECK-ALL: name: testSTFDX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: f8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%f1', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %f1, %x5 + + %2 = COPY %x5 + %1 = COPY %f1 + %0 = COPY %x3 + %3 = COPY %2.sub_32 + %4 = ADDI %3, 1 + %6 = IMPLICIT_DEF + %5 = INSERT_SUBREG %6, killed %4, 1 + %7 = LI8 876 + STFDX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !12) + ; CHECK: STFD %1, 876, %0 + ; CHECK-LATE: stfd 1, 876(3) + %8 = ADDI %3, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 -873 + STFDX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !12) + ; CHECK: STFD %1, -873, %0 + ; CHECK-LATE: stfd 1, -873(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTFDUX +# CHECK-ALL: name: testSTFDUX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: f8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } + - { id: 6, class: g8rc, preferred-register: '' } + - { id: 7, class: g8rc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } + - { id: 9, class: g8rc, preferred-register: '' } + - { id: 10, class: g8rc, preferred-register: '' } + - { id: 11, class: g8rc, preferred-register: '' } + - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%f1', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %f1, %x5 + + %2 = COPY %x5 + %1 = COPY %f1 + %0 = COPY %x3 + %3 = COPY %2.sub_32 + %4 = ADDI %3, 1 + %6 = IMPLICIT_DEF + %5 = INSERT_SUBREG %6, killed %4, 1 + %7 = LI8 -9038 + %12 = STFDUX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !12) + ; CHECK: STFDU %1, -9038, %0 + ; CHECK-LATE: stfdu 1, -9038(4) + %8 = ADDI %3, 2 + %10 = IMPLICIT_DEF + %9 = INSERT_SUBREG %10, killed %8, 1 + %11 = LI8 6477 + %13 = STFDUX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !12) + ; CHECK: STFDU %1, 6477, %0 + ; CHECK-LATE: stfdu 1, 6477(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTXSSPX +# CHECK-ALL: name: testSTXSSPX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: vssrc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%f1', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %f1, %x5 + + %2 = COPY %x5 + %1 = COPY %f1 + %0 = COPY %x3 + %3 = LI8 444 + STXSSPX %1, %0, killed %3 :: (store 4 into %ir.arrayidx, !tbaa !14) + ; CHECK: STXSSP %1, 444, %0 + ; CHECK-LATE: stxssp 1, 444(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTXSDX +# CHECK-ALL: name: testSTXSDX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: vsfrc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%f1', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %f1, %x5 + + %2 = COPY %x5 + %1 = COPY %f1 + %0 = COPY %x3 + %3 = LI8 4 + STXSDX %1, %0, killed %3, implicit %rm :: (store 8 into %ir.arrayidx, !tbaa !12) + ; CHECK: STXSD %1, 4, %0 + ; CHECK-LATE: stxsd 1, 4(3) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSTXVX +# CHECK-ALL: name: testSTXVX +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: vrrc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%v2', virtual-reg: '%1' } + - { reg: '%x7', virtual-reg: '%2' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %v2, %x7 + + %2 = COPY %x7 + %1 = COPY %v2 + %0 = LI8 16 + %3 = RLDICR %2, 4, 59 + STXVX %1, %0, killed %3 :: (store 16 into %ir.arrayidx, !tbaa !3) + ; CHECK: STXV %1, 16, killed %3 + ; CHECK-LATE: stxv 34, 16(4) + BLR8 implicit %lr8, implicit %rm + +... +--- +name: testSUBFC +# CHECK-ALL: name: testSUBFC +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: gprc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: gprc, preferred-register: '' } + - { id: 5, class: gprc, preferred-register: '' } + - { id: 6, class: gprc, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: gprc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } + - { reg: '%x6', virtual-reg: '%3' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5, %x6 + + %3 = COPY %x6 + %2 = COPY %x5 + %1 = COPY %x4 + %6 = COPY %3.sub_32 + %7 = COPY %2.sub_32 + %8 = COPY %1.sub_32 + %0 = LI 55 + %4 = SUBFC %7, %0, implicit-def %carry + ; CHECK: SUBFIC %7, 55 + ; CHECK-LATE: subfic 3, 5, 55 + %5 = SUBFE %6, %8, implicit-def dead %carry, implicit %carry + %x3 = EXTSW_32_64 %4 + %x4 = EXTSW_32_64 %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4 + +... +--- +name: testSUBFC8 +# CHECK-ALL: name: testSUBFC8 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } + - { id: 3, class: g8rc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc, preferred-register: '' } +liveins: + - { reg: '%x3', virtual-reg: '%0' } + - { reg: '%x4', virtual-reg: '%1' } + - { reg: '%x5', virtual-reg: '%2' } + - { reg: '%x6', virtual-reg: '%3' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4, %x5, %x6 + + %3 = COPY %x6 + %2 = COPY %x5 + %1 = COPY %x4 + %0 = LI8 7635 + %4 = SUBFC8 %2, %0, implicit-def %carry + ; CHECK: SUBFIC8 %2, 7635 + ; CHECK-LATE: subfic 3, 5, 7635 + %5 = SUBFE8 %3, %1, implicit-def dead %carry, implicit %carry + %x3 = COPY %4 + %x4 = COPY %5 + BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4 + +... +--- +name: testXOR +# CHECK-ALL: name: testXOR +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: gprc, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: gprc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = LI 10101 + %0 = COPY %x3 + %3 = COPY %0.sub_32 + %2 = XOR %1, %3 + ; CHECK: XORI %3, 10101 + ; CHECK-LATE: 3, 3, 10101 + %x3 = EXTSW_32_64 %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testXOR8 +# CHECK-ALL: name: testXOR8 +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } + - { id: 2, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3, %x4 + + %1 = COPY %x4 + %0 = LI8 5535 + %2 = XOR8 %1, %0 + ; CHECK: XORI8 %1, 5535 + ; CHECK-LATE: xori 3, 4, 5535 + %x3 = COPY %2 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testXORI +# CHECK-ALL: name: testXORI +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: gprc, preferred-register: '' } + - { id: 1, class: gprc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI 871 + %1 = XORI %0, 17 + ; CHECK: LI 886 + ; CHECK-LATE: li 3, 886 + %x3 = EXTSW_32_64 %1 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... +--- +name: testXOR8I +# CHECK-ALL: name: testXOR8I +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: g8rc, preferred-register: '' } + - { id: 1, class: g8rc, preferred-register: '' } +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 + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + liveins: %x3 + + %0 = LI8 453 + %1 = XORI8 %0, 17 + ; CHECK: LI8 468 + ; CHECK-LATE: li 3, 468 + %x3 = COPY %1 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + +... diff --git a/test/CodeGen/PowerPC/fast-isel-call.ll b/test/CodeGen/PowerPC/fast-isel-call.ll index c89aa2b3655..231f29e6e4d 100644 --- a/test/CodeGen/PowerPC/fast-isel-call.ll +++ b/test/CodeGen/PowerPC/fast-isel-call.ll @@ -37,9 +37,13 @@ define void @foo(i8 %a, i16 %b) nounwind { ;; A few test to check materialization %5 = call i32 @t2(i8 zeroext 255) -; ELF64: clrldi {{[0-9]+}}, {{[0-9]+}}, 56 +; ELF64: li 3, 255 +; ELF64-NOT: clrldi %6 = call i32 @t4(i16 zeroext 65535) -; ELF64: clrldi {{[0-9]+}}, {{[0-9]+}}, 48 +; ELF64: lis 3, 0 +; ELF64: ori 3, 3, 65535 +; ELF64: clrldi 3, 3, 48 +; ELF64: bl t4 ret void } @@ -66,12 +70,8 @@ entry: ; ELF64: li 6, 28 ; ELF64: li 7, 40 ; ELF64: li 8, 186 -; ELF64: clrldi 3, 3, 56 -; ELF64: clrldi 4, 4, 56 -; ELF64: clrldi 5, 5, 56 -; ELF64: clrldi 6, 6, 56 -; ELF64: clrldi 7, 7, 56 -; ELF64: clrldi 8, 8, 56 +; ELF64-NOT: clrldi +; ELF64: bl bar ret i32 0 } diff --git a/test/CodeGen/PowerPC/setcc-logic.ll b/test/CodeGen/PowerPC/setcc-logic.ll index b17869f312c..d27538fb8d5 100644 --- a/test/CodeGen/PowerPC/setcc-logic.ll +++ b/test/CodeGen/PowerPC/setcc-logic.ll @@ -418,9 +418,9 @@ define <4 x i1> @any_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) { 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 diff --git a/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll b/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll new file mode 100644 index 00000000000..3988d9c8d5a --- /dev/null +++ b/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll @@ -0,0 +1,51 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=powerpc64le-unknown-unknown -mcpu=pwr8 \ +; RUN: -ppc-convert-rr-to-ri -verify-machineinstrs | FileCheck %s +define void @test(i32 zeroext %parts) { +; CHECK-LABEL: test: +; CHECK: # %bb.0: # %cond.end.i +; CHECK-NEXT: cmplwi 0, 3, 1 +; CHECK-NEXT: bnelr+ 0 +; CHECK-NEXT: # %bb.1: # %test2.exit.us.unr-lcssa +; CHECK-NEXT: ld 3, 0(3) +; CHECK-NEXT: std 3, 0(3) +entry: + br label %cond.end.i + +cond.end.i: ; preds = %entry + %cmp18.i = icmp eq i32 %parts, 1 + br i1 %cmp18.i, label %while.body.lr.ph.i.us.preheader, label %test3.exit.split + +while.body.lr.ph.i.us.preheader: ; preds = %cond.end.i + %0 = icmp eq i32 %parts, 1 + br label %for.body.i62.us.preheader + +for.body.i62.us.preheader: ; preds = %while.body.lr.ph.i.us.preheader + br i1 %0, label %test2.exit.us.unr-lcssa, label %for.body.i62.us.preheader.new + +for.body.i62.us.preheader.new: ; preds = %for.body.i62.us.preheader + br label %for.body.i62.us + +for.body.i62.us: ; preds = %if.end.i.us.1, %for.body.i62.us.preheader.new + %niter = phi i64 [ undef, %for.body.i62.us.preheader.new ], [ %niter.nsub.1, %if.end.i.us.1 ] + %cmp8.i.us.1 = icmp uge i64 undef, 0 + br label %if.end.i.us.1 + +test2.exit.us.unr-lcssa: ; preds = %if.end.i.us.1, %for.body.i62.us.preheader + %c.addr.036.i.us.unr = phi i64 [ 0, %for.body.i62.us.preheader ], [ %c.addr.1.i.us.1, %if.end.i.us.1 ] + %1 = load i64, i64* undef, align 8 + %tobool.i61.us.epil = icmp eq i64 %c.addr.036.i.us.unr, 0 + %add.neg.i.us.epil.pn = select i1 %tobool.i61.us.epil, i64 %1, i64 0 + %storemerge269 = sub i64 %add.neg.i.us.epil.pn, 0 + store i64 %storemerge269, i64* undef, align 8 + unreachable + +test3.exit.split: ; preds = %cond.end.i + ret void + +if.end.i.us.1: ; preds = %for.body.i62.us + %c.addr.1.i.us.1 = zext i1 %cmp8.i.us.1 to i64 + %niter.nsub.1 = add i64 %niter, -2 + %niter.ncmp.1 = icmp eq i64 %niter.nsub.1, 0 + br i1 %niter.ncmp.1, label %test2.exit.us.unr-lcssa, label %for.body.i62.us +} diff --git a/test/CodeGen/PowerPC/unaligned.ll b/test/CodeGen/PowerPC/unaligned.ll index 2d1fd80e5c4..c9f65f243b1 100644 --- a/test/CodeGen/PowerPC/unaligned.ll +++ b/test/CodeGen/PowerPC/unaligned.ll @@ -89,7 +89,7 @@ entry: ; CHECK: @foo6 ; CHECK-DAG: ld ; CHECK-DAG: ld -; CHECK-DAG: stdx +; CHECK-DAG: std ; CHECK: stdx ; For VSX on P7, unaligned loads and stores are preferable to aligned diff --git a/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll b/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll index 98862cd049a..89a248dc053 100644 --- a/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll +++ b/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll @@ -70,9 +70,9 @@ entry: ; 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: lvsl [[SHMSKREG:[0-9]+]], 0, [[TRUNCREG]] +; CHECK: xori [[TRUNCREG:[0-9]+]], 5, 3 +; CHECK: sldi [[SHIFTREG:[0-9]+]], [[TRUNCREG]], 2 +; CHECK: lvsl [[SHMSKREG:[0-9]+]], 0, [[SHIFTREG]] ; CHECK: vperm {{[0-9]+}}, 2, 2, [[SHMSKREG]] ; CHECK: xscvspdpn 1, ; CHECK-P7-DAG: rlwinm [[ELEMOFFREG:[0-9]+]], 5, 2, 28, 29 -- 2.11.0