Index: lib/Target/PowerPC/PPCInstrInfo.h =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.h +++ lib/Target/PowerPC/PPCInstrInfo.h @@ -340,19 +340,22 @@ bool isTOCSaveMI(const MachineInstr &MI) const; - bool isSignOrZeroExtended(const MachineInstr &MI, bool SignExt, - const unsigned PhiDepth) const; + std::pair + isSignOrZeroExtended(const unsigned Reg, const unsigned BinOpDepth, + const MachineRegisterInfo *MRI) const; - /// Return true if the output of the instruction is always a sign-extended, + /// Return true if the register is always a sign-extended, /// i.e. 0 to 31-th bits are same as 32-th bit. - bool isSignExtended(const MachineInstr &MI, const unsigned depth = 0) const { - return isSignOrZeroExtended(MI, true, depth); + bool isSignExtended(const unsigned Reg, + const MachineRegisterInfo *MRI) const { + return isSignOrZeroExtended(Reg, 0, MRI).first; } - /// Return true if the output of the instruction is always zero-extended, + /// Return true if the register is always zero-extended, /// i.e. 0 to 31-th bits are all zeros - bool isZeroExtended(const MachineInstr &MI, const unsigned depth = 0) const { - return isSignOrZeroExtended(MI, false, depth); + bool isZeroExtended(const unsigned Reg, + const MachineRegisterInfo *MRI) const { + return isSignOrZeroExtended(Reg, 0, MRI).second; } bool convertToImmediateForm(MachineInstr &MI, Index: lib/Target/PowerPC/PPCInstrInfo.cpp =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.cpp +++ lib/Target/PowerPC/PPCInstrInfo.cpp @@ -20,6 +20,7 @@ #include "PPCTargetMachine.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -1643,15 +1644,15 @@ bool noSub = false; if (isPPC64) { if (is32BitSignedCompare) { - // We can perform this optimization only if MI is sign-extending. - if (isSignExtended(*MI)) + // We can perform this optimization only if SrcReg is sign-extending. + if (isSignExtended(SrcReg, MRI)) noSub = true; else return false; } else if (is32BitUnsignedCompare) { - // We can perform this optimization, equality only, if MI is + // We can perform this optimization, equality only, if SrcReg is // zero-extending. - if (isZeroExtended(*MI)) { + if (isZeroExtended(SrcReg, MRI)) { noSub = true; equalityOnly = true; } else @@ -3036,53 +3037,77 @@ // This function returns true if the machine instruction // always outputs a value by sign-extending a 32 bit value, // i.e. 0 to 31-th bits are same as 32-th bit. -static bool isSignExtendingOp(const MachineInstr &MI) { - int Opcode = MI.getOpcode(); - if (Opcode == PPC::LI || Opcode == PPC::LI8 || - Opcode == PPC::LIS || Opcode == PPC::LIS8 || - Opcode == PPC::SRAW || Opcode == PPC::SRAWo || - Opcode == PPC::SRAWI || Opcode == PPC::SRAWIo || - Opcode == PPC::LWA || Opcode == PPC::LWAX || - Opcode == PPC::LWA_32 || Opcode == PPC::LWAX_32 || - Opcode == PPC::LHA || Opcode == PPC::LHAX || - Opcode == PPC::LHA8 || Opcode == PPC::LHAX8 || - Opcode == PPC::LBZ || Opcode == PPC::LBZX || - Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 || - Opcode == PPC::LBZU || Opcode == PPC::LBZUX || - Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8 || - Opcode == PPC::LHZ || Opcode == PPC::LHZX || - Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 || - Opcode == PPC::LHZU || Opcode == PPC::LHZUX || - Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8 || - Opcode == PPC::EXTSB || Opcode == PPC::EXTSBo || - Opcode == PPC::EXTSH || Opcode == PPC::EXTSHo || - Opcode == PPC::EXTSB8 || Opcode == PPC::EXTSH8 || - Opcode == PPC::EXTSW || Opcode == PPC::EXTSWo || - Opcode == PPC::EXTSH8_32_64 || Opcode == PPC::EXTSW_32_64 || - Opcode == PPC::EXTSB8_32_64) +static bool definedBySignExtendingOp(const unsigned Reg, + const MachineRegisterInfo *MRI) { + if (!TargetRegisterInfo::isVirtualRegister(Reg)) + return false; + + MachineInstr *MI = MRI->getVRegDef(Reg); + if (!MI) return false; + + // Opcodes included in this set always return sign-extended value. + static const DenseSet OpcodesSExt32To64{ + PPC::LI, PPC::LI8, PPC::LIS, PPC::LIS8, PPC::ANDIo, PPC::ANDIo8, + PPC::SRAW, PPC::SRAWo, PPC::SRAWI, PPC::SRAWIo, PPC::LWA, PPC::LWAX, + PPC::LWA_32, PPC::LWAX_32, PPC::LHA, PPC::LHAX, PPC::LHA8, PPC::LHAX8, + PPC::LBZ, PPC::LBZX, PPC::LBZ8, PPC::LBZX8, PPC::LHZ, PPC::LHZX, PPC::LHZ8, + PPC::LHZX8, PPC::EXTSB, PPC::EXTSBo, PPC::EXTSH, PPC::EXTSHo, PPC::EXTSB8, + PPC::EXTSH8, PPC::EXTSW, PPC::EXTSWo, PPC::EXTSH8_32_64, PPC::EXTSW_32_64, + PPC::EXTSB8_32_64}; + + int Opcode = MI->getOpcode(); + if (OpcodesSExt32To64.find(Opcode) != OpcodesSExt32To64.end()) return true; - if (Opcode == PPC::RLDICL && MI.getOperand(3).getImm() >= 33) + // The first def of LBZU/LHZU is sign extended. + if ((Opcode == PPC::LBZU || Opcode == PPC::LBZUX || + Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8 || + Opcode == PPC::LHZU || Opcode == PPC::LHZUX || + Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8) && + MI->getOperand(0).getReg() == Reg) return true; + // RLDICL generates sign-extended output if it cleares at least + // 33 bits from the left (MSB). + if (Opcode == PPC::RLDICL && MI->getOperand(3).getImm() >= 33) + return true; + + // If at least one bit from left in a lower word is masked, + // all of 0 to 32-th bits of the output are cleared. + // Hence the output is already sign extended. if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINMo || Opcode == PPC::RLWNM || Opcode == PPC::RLWNMo) && - MI.getOperand(3).getImm() > 0 && - MI.getOperand(3).getImm() <= MI.getOperand(4).getImm()) + MI->getOperand(3).getImm() > 0 && + MI->getOperand(3).getImm() <= MI->getOperand(4).getImm()) return true; + // If the most significant bit of immediate in ANDIS is zero, + // all of 0 to 32-th bits are cleared. + if (Opcode == PPC::ANDISo || Opcode == PPC::ANDISo8) { + uint16_t Imm = MI->getOperand(2).getImm(); + if ((Imm & 0x8000) == 0) + return true; + } + return false; } // This function returns true if the machine instruction // always outputs zeros in higher 32 bits. -static bool isZeroExtendingOp(const MachineInstr &MI) { - int Opcode = MI.getOpcode(); +static bool definedByZeroExtendingOp(const unsigned Reg, + const MachineRegisterInfo *MRI) { + if (!TargetRegisterInfo::isVirtualRegister(Reg)) + return false; + + MachineInstr *MI = MRI->getVRegDef(Reg); + if (!MI) return false; + + int Opcode = MI->getOpcode(); // The 16-bit immediate is sign-extended in li/lis. // If the most significant bit is zero, all higher bits are zero. if (Opcode == PPC::LI || Opcode == PPC::LI8 || Opcode == PPC::LIS || Opcode == PPC::LIS8) { - int64_t Imm = MI.getOperand(1).getImm(); + int64_t Imm = MI->getOperand(1).getImm(); if (((uint64_t)Imm & ~0x7FFFuLL) == 0) return true; } @@ -3092,50 +3117,43 @@ if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICLo || Opcode == PPC::RLDCL || Opcode == PPC::RLDCLo || Opcode == PPC::RLDICL_32_64) && - MI.getOperand(3).getImm() >= 32) + MI->getOperand(3).getImm() >= 32) return true; if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDICo) && - MI.getOperand(3).getImm() >= 32 && - MI.getOperand(3).getImm() <= 63 - MI.getOperand(2).getImm()) + MI->getOperand(3).getImm() >= 32 && + MI->getOperand(3).getImm() <= 63 - MI->getOperand(2).getImm()) return true; if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINMo || Opcode == PPC::RLWNM || Opcode == PPC::RLWNMo || Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) && - MI.getOperand(3).getImm() <= MI.getOperand(4).getImm()) + MI->getOperand(3).getImm() <= MI->getOperand(4).getImm()) return true; - // There are other instructions that clear higher 32-bits. - if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZWo || - Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZWo || - Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8 || - Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZDo || - Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZDo || - Opcode == PPC::POPCNTD || Opcode == PPC::POPCNTW || - Opcode == PPC::SLW || Opcode == PPC::SLWo || - Opcode == PPC::SRW || Opcode == PPC::SRWo || - Opcode == PPC::SLW8 || Opcode == PPC::SRW8 || - Opcode == PPC::SLWI || Opcode == PPC::SLWIo || - Opcode == PPC::SRWI || Opcode == PPC::SRWIo || - Opcode == PPC::LWZ || Opcode == PPC::LWZX || - Opcode == PPC::LWZU || Opcode == PPC::LWZUX || - Opcode == PPC::LWBRX || Opcode == PPC::LHBRX || - Opcode == PPC::LHZ || Opcode == PPC::LHZX || - Opcode == PPC::LHZU || Opcode == PPC::LHZUX || - Opcode == PPC::LBZ || Opcode == PPC::LBZX || - Opcode == PPC::LBZU || Opcode == PPC::LBZUX || - Opcode == PPC::LWZ8 || Opcode == PPC::LWZX8 || - Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8 || - Opcode == PPC::LWBRX8 || Opcode == PPC::LHBRX8 || - Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 || - Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8 || - Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 || - Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8 || - Opcode == PPC::ANDIo || Opcode == PPC::ANDISo || - Opcode == PPC::ROTRWI || Opcode == PPC::ROTRWIo || - Opcode == PPC::EXTLWI || Opcode == PPC::EXTLWIo || - Opcode == PPC::MFVSRWZ) + // Opcodes included in this set always clear higher 32-bits. + static const DenseSet OpcodesZExt32To64{ + PPC::CNTLZW, PPC::CNTLZWo, PPC::CNTTZW, PPC::CNTTZWo, PPC::CNTLZW8, + PPC::CNTTZW8, PPC::CNTLZD, PPC::CNTLZDo, PPC::CNTTZD, PPC::CNTTZDo, + PPC::POPCNTD, PPC::POPCNTW, PPC::SLW, PPC::SLWo, PPC::SRW, PPC::SRWo, + PPC::SLW8, PPC::SRW8, PPC::SLWI, PPC::SLWIo, PPC::SRWI, PPC::SRWIo, + PPC::LWZ, PPC::LWZX, PPC::LWBRX, PPC::LHBRX, PPC::LHZ, PPC::LHZX, + PPC::LBZ, PPC::LBZX, PPC::LWZ8, PPC::LWZX8, PPC::LWBRX8, PPC::LHBRX8, + PPC::LHZ8, PPC::LHZX8, PPC::LBZ8, PPC::LBZX8, PPC::ANDIo, PPC::ANDIo8, + PPC::ANDISo, PPC::ANDISo8, PPC::ROTRWI, PPC::ROTRWIo, PPC::EXTLWI, + PPC::EXTLWIo, PPC::MFVSRWZ}; + + if (OpcodesZExt32To64.find(Opcode) != OpcodesZExt32To64.end()) + return true; + + // The first def of LBZU/LHZU/LWZU are zero extended. + if ((Opcode == PPC::LBZU || Opcode == PPC::LBZUX || + Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8 || + Opcode == PPC::LHZU || Opcode == PPC::LHZUX || + Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8 || + Opcode == PPC::LWZU || Opcode == PPC::LWZUX || + Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) && + MI->getOperand(0).getReg() == Reg) return true; return false; @@ -3157,35 +3175,44 @@ // We limit the max depth to track incoming values of PHIs or binary ops // (e.g. AND) to avoid exsessive cost. -const unsigned MAX_DEPTH = 1; +const unsigned MAX_BINOP_DEPTH = 1; -bool -PPCInstrInfo::isSignOrZeroExtended(const MachineInstr &MI, bool SignExt, - const unsigned Depth) const { - const MachineFunction *MF = MI.getParent()->getParent(); - const MachineRegisterInfo *MRI = &MF->getRegInfo(); - - // If we know this instruction returns sign- or zero-extended result, - // return true. - if (SignExt ? isSignExtendingOp(MI): - isZeroExtendingOp(MI)) - return true; +std::pair +PPCInstrInfo::isSignOrZeroExtended(const unsigned Reg, const unsigned BinOpDepth, + const MachineRegisterInfo *MRI) const { + if (!TargetRegisterInfo::isVirtualRegister(Reg)) + return std::pair(false, false); - switch (MI.getOpcode()) { + MachineInstr *MI = MRI->getVRegDef(Reg); + if (!MI) + return std::pair(false, false); + + bool IsSExt = definedBySignExtendingOp(Reg, MRI); + bool IsZExt = definedByZeroExtendingOp(Reg, MRI); + + // If we know the instruction always returns sign- and zero-extended result, + // return here. + if (IsSExt && IsZExt) + return std::pair(IsSExt, IsZExt); + + switch (MI->getOpcode()) { case PPC::COPY: { - unsigned SrcReg = MI.getOperand(1).getReg(); + unsigned SrcReg = MI->getOperand(1).getReg(); // In both ELFv1 and v2 ABI, method parameters and the return value // are sign- or zero-extended. + const MachineFunction *MF = MI->getParent()->getParent(); if (MF->getSubtarget().isSVR4ABI()) { const PPCFunctionInfo *FuncInfo = MF->getInfo(); // We check the ZExt/SExt flags for a method parameter. - if (MI.getParent()->getBasicBlock() == + if (MI->getParent()->getBasicBlock() == &MF->getFunction().getEntryBlock()) { - unsigned VReg = MI.getOperand(0).getReg(); - if (MF->getRegInfo().isLiveIn(VReg)) - return SignExt ? FuncInfo->isLiveInSExt(VReg) : - FuncInfo->isLiveInZExt(VReg); + unsigned VReg = MI->getOperand(0).getReg(); + if (MF->getRegInfo().isLiveIn(VReg)) { + IsSExt |= FuncInfo->isLiveInSExt(VReg); + IsZExt |= FuncInfo->isLiveInZExt(VReg); + return std::pair(IsSExt, IsZExt); + } } // For a method return value, we check the ZExt/SExt flags in attribute. @@ -3195,9 +3222,9 @@ // ADJCALLSTACKUP 32, 0, implicit dead %r1, implicit %r1 // %5 = COPY %x3; G8RC:%5 if (SrcReg == PPC::X3) { - const MachineBasicBlock *MBB = MI.getParent(); + const MachineBasicBlock *MBB = MI->getParent(); MachineBasicBlock::const_instr_iterator II = - MachineBasicBlock::const_instr_iterator(&MI); + MachineBasicBlock::const_instr_iterator(MI); if (II != MBB->instr_begin() && (--II)->getOpcode() == PPC::ADJCALLSTACKUP) { const MachineInstr &CallMI = *(--II); @@ -3205,51 +3232,52 @@ const Function *CalleeFn = dyn_cast(CallMI.getOperand(0).getGlobal()); if (!CalleeFn) - return false; + return std::pair(IsSExt, IsZExt); const IntegerType *IntTy = dyn_cast(CalleeFn->getReturnType()); - const AttributeSet &Attrs = - CalleeFn->getAttributes().getRetAttributes(); - if (IntTy && IntTy->getBitWidth() <= 32) - return Attrs.hasAttribute(SignExt ? Attribute::SExt : - Attribute::ZExt); + if (IntTy && IntTy->getBitWidth() <= 32) { + const AttributeSet &Attrs = + CalleeFn->getAttributes().getRetAttributes(); + IsSExt |= Attrs.hasAttribute(Attribute::SExt); + IsZExt |= Attrs.hasAttribute(Attribute::ZExt); + return std::pair(IsSExt, IsZExt); + } } } } } // If this is a copy from another register, we recursively check source. - if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) - return false; - const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg); - if (SrcMI != NULL) - return isSignOrZeroExtended(*SrcMI, SignExt, Depth); - - return false; + auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth, MRI); + return std::pair(SrcExt.first | IsSExt, SrcExt.second | IsZExt); } - case PPC::ANDIo: - case PPC::ANDISo: + // OR, XOR with 16-bit immediate does not change the upper 48 bits. + // So, we track the operand register as we do for register copy. case PPC::ORI: - case PPC::ORIS: case PPC::XORI: - case PPC::XORIS: - case PPC::ANDIo8: - case PPC::ANDISo8: case PPC::ORI8: + case PPC::XORI8: { + unsigned SrcReg = MI->getOperand(1).getReg(); + auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth, MRI); + return std::pair(SrcExt.first | IsSExt, SrcExt.second | IsZExt); + } + + // OR, XOR with shifted 16-bit immediate does not change the upper + // 32 bits. So, we track the operand register for zero extension. + // For sign extension when the MSB of the immediate is zero, we also + // track the operand register since the upper 33 bits are unchanged. + case PPC::ORIS: + case PPC::XORIS: case PPC::ORIS8: - case PPC::XORI8: case PPC::XORIS8: { - // logical operation with 16-bit immediate does not change the upper bits. - // So, we track the operand register as we do for register copy. - unsigned SrcReg = MI.getOperand(1).getReg(); - if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) - return false; - const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg); - if (SrcMI != NULL) - return isSignOrZeroExtended(*SrcMI, SignExt, Depth); - - return false; + unsigned SrcReg = MI->getOperand(1).getReg(); + auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth, MRI); + uint16_t Imm = MI->getOperand(2).getImm(); + if (Imm & 0x8000) + return std::pair(false, SrcExt.second | IsZExt); + else + return std::pair(SrcExt.first | IsSExt, SrcExt.second | IsZExt); } // If all incoming values are sign-/zero-extended, @@ -3258,30 +3286,31 @@ case PPC::OR8: case PPC::ISEL: case PPC::PHI: { - if (Depth >= MAX_DEPTH) - return false; + if (BinOpDepth >= MAX_BINOP_DEPTH) + return std::pair(false, false); // The input registers for PHI are operand 1, 3, ... // The input registers for others are operand 1 and 2. unsigned E = 3, D = 1; - if (MI.getOpcode() == PPC::PHI) { - E = MI.getNumOperands(); + if (MI->getOpcode() == PPC::PHI) { + E = MI->getNumOperands(); D = 2; } + IsSExt = true; + IsZExt = true; for (unsigned I = 1; I != E; I += D) { - if (MI.getOperand(I).isReg()) { - unsigned SrcReg = MI.getOperand(I).getReg(); - if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) - return false; - const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg); - if (SrcMI == NULL || !isSignOrZeroExtended(*SrcMI, SignExt, Depth+1)) - return false; + if (!MI->getOperand(I).isReg()) { + // todo: check imm + return std::pair(false, false); } - else - return false; + + unsigned SrcReg = MI->getOperand(I).getReg(); + auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth+1, MRI); + IsSExt &= SrcExt.first; + IsZExt &= SrcExt.second; } - return true; + return std::pair(IsSExt, IsZExt); } // If at least one of the incoming values of an AND is zero extended @@ -3289,33 +3318,18 @@ // are sign-extended then the output is also sign extended. case PPC::AND: case PPC::AND8: { - if (Depth >= MAX_DEPTH) - return false; - - assert(MI.getOperand(1).isReg() && MI.getOperand(2).isReg()); + if (BinOpDepth >= MAX_BINOP_DEPTH) + return std::pair(false, false); - unsigned SrcReg1 = MI.getOperand(1).getReg(); - unsigned SrcReg2 = MI.getOperand(2).getReg(); - - if (!TargetRegisterInfo::isVirtualRegister(SrcReg1) || - !TargetRegisterInfo::isVirtualRegister(SrcReg2)) - return false; - - const MachineInstr *MISrc1 = MRI->getVRegDef(SrcReg1); - const MachineInstr *MISrc2 = MRI->getVRegDef(SrcReg2); - if (!MISrc1 || !MISrc2) - return false; - - if(SignExt) - return isSignOrZeroExtended(*MISrc1, SignExt, Depth+1) && - isSignOrZeroExtended(*MISrc2, SignExt, Depth+1); - else - return isSignOrZeroExtended(*MISrc1, SignExt, Depth+1) || - isSignOrZeroExtended(*MISrc2, SignExt, Depth+1); + unsigned SrcReg1 = MI->getOperand(1).getReg(); + unsigned SrcReg2 = MI->getOperand(2).getReg(); + auto Src1Ext = isSignOrZeroExtended(SrcReg1, BinOpDepth+1, MRI); + auto Src2Ext = isSignOrZeroExtended(SrcReg2, BinOpDepth+1, MRI); + return std::pair(Src1Ext.first && Src1Ext.first, Src1Ext.second || Src2Ext.second); } default: break; } - return false; + return std::pair(IsSExt, IsZExt); } Index: lib/Target/PowerPC/PPCMIPeephole.cpp =================================================================== --- lib/Target/PowerPC/PPCMIPeephole.cpp +++ lib/Target/PowerPC/PPCMIPeephole.cpp @@ -139,7 +139,9 @@ // This function returns number of known zero bits in output of MI // starting from the most significant bit. static unsigned -getKnownLeadingZeroCount(MachineInstr *MI, const PPCInstrInfo *TII) { +getKnownLeadingZeroCount(const unsigned Reg, const PPCInstrInfo *TII, + const MachineRegisterInfo *MRI) { + MachineInstr *MI = MRI->getVRegDef(Reg); unsigned Opcode = MI->getOpcode(); if (Opcode == PPC::RLDICL || Opcode == PPC::RLDICLo || Opcode == PPC::RLDCL || Opcode == PPC::RLDCLo) @@ -183,7 +185,7 @@ Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8) return 56; - if (TII->isZeroExtended(*MI)) + if (TII->isZeroExtended(Reg, MRI)) return 32; return 0; @@ -569,6 +571,7 @@ case PPC::EXTSW_32: case PPC::EXTSW_32_64: { if (!EnableSExtElimination) break; + unsigned NarrowReg = MI.getOperand(1).getReg(); if (!TargetRegisterInfo::isVirtualRegister(NarrowReg)) break; @@ -607,7 +610,7 @@ Simplified = true; NumEliminatedSExt++; } else if (MI.getOpcode() == PPC::EXTSW_32_64 && - TII->isSignExtended(*SrcMI)) { + TII->isSignExtended(NarrowReg, MRI)) { // We can eliminate EXTSW if the input is known to be already // sign-extended. DEBUG(dbgs() << "Removing redundant sign-extension\n"); @@ -658,8 +661,10 @@ if (TargetRegisterInfo::isVirtualRegister(CopyReg)) SrcMI = MRI->getVRegDef(CopyReg); } + if (!SrcMI->getOperand(0).isReg()) break; - unsigned KnownZeroCount = getKnownLeadingZeroCount(SrcMI, TII); + unsigned KnownZeroCount = getKnownLeadingZeroCount( + SrcMI->getOperand(0).getReg(), TII, MRI); if (MI.getOperand(3).getImm() <= KnownZeroCount) { DEBUG(dbgs() << "Removing redundant zero-extension\n"); BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::COPY), Index: test/CodeGen/PowerPC/sext_elimination.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/sext_elimination.mir @@ -0,0 +1,67 @@ +# RUN: llc -run-pass ppc-mi-peepholes -ppc-eliminate-signext -ppc-eliminate-zeroext -verify-machineinstrs -o - %s | FileCheck %s + +--- | + target datalayout = "E-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + define i8* @func(i8* %a) { + entry: + ret i8* %a + } + +... +--- +name: func +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: + - { reg: '$x3', virtual-reg: '%0' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: $x3 + + ; CHECK-LABEL: bb.0.entry: + ; CHECK: %4:g8rc = EXTSW_32_64 %3 + ; CHECK: %5:g8rc = INSERT_SUBREG %15, %1, %subreg.sub_32 + ; CHECK: %7:g8rc = EXTSW_32_64 %6 + ; CHECK: %9:g8rc = INSERT_SUBREG %16, %8, %subreg.sub_32 + ; CHECK: %11:g8rc = INSERT_SUBREG %17, %10, %subreg.sub_32 + ; CHECK: %14:g8rc = COPY %1 + + %0:g8rc_nox0 = COPY $x3 + %1:gprc, %2:g8rc_nox0 = LBZU 0, %0:g8rc_nox0 + %3:gprc = COPY %2:g8rc_nox0 + %4:g8rc = EXTSW_32_64 %3:gprc ; should not be eliminated + %5:g8rc = EXTSW_32_64 %1:gprc + + %6:gprc = ORIS %1:gprc, 32768 ; should not be eliminated + %7:g8rc = EXTSW_32_64 %6:gprc + + %8:gprc = ORIS %1:gprc, 32767 + %9:g8rc = EXTSW_32_64 %8:gprc + + %10:gprc = ORI %1:gprc, 32768 + %11:g8rc = EXTSW_32_64 %10:gprc + + %12:g8rc = IMPLICIT_DEF + %13:g8rc = INSERT_SUBREG %12:g8rc, %1:gprc, %subreg.sub_32 + %14:g8rc = RLDICL %13:g8rc, 0, 32 + +...