From 581d13f8aeb66c040d5ea69ad4385f766e1f97c9 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 3 Nov 2020 09:50:17 -0500 Subject: [PATCH] GlobalISel: Return APInt from getConstantVRegVal Returning int64_t was arbitrarily limiting for wide integer types, and the functions should handle the full generality of the IR. Also changes the full form which returns the originally defined vreg. Add another wrapper for the common case of just immediately converting to int64_t (arguably this would be useful for the full return value case as well). One possible issue with this change is some of the existing uses did break without conversion to getConstantVRegSExtVal, and it's possible some without adequate test coverage are now broken. --- .../llvm/CodeGen/GlobalISel/MIPatternMatch.h | 2 +- llvm/include/llvm/CodeGen/GlobalISel/Utils.h | 11 +++-- .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 28 +++++------ .../GlobalISel/InstructionSelector.cpp | 2 +- llvm/lib/CodeGen/GlobalISel/Utils.cpp | 30 +++++++----- .../GISel/AArch64InstructionSelector.cpp | 47 ++++++++++--------- .../AArch64/GISel/AArch64LegalizerInfo.cpp | 2 +- .../GISel/AArch64PostLegalizerCombiner.cpp | 2 +- .../GISel/AArch64PostLegalizerLowering.cpp | 2 +- .../AMDGPU/AMDGPUInstructionSelector.cpp | 20 ++++---- .../lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp | 24 +++++----- .../Target/AMDGPU/AMDGPURegisterBankInfo.cpp | 2 +- .../lib/Target/X86/X86InstructionSelector.cpp | 2 +- 13 files changed, 96 insertions(+), 78 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h index 3357b0e1a6eb..427906db6696 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -43,7 +43,7 @@ struct ConstantMatch { int64_t &CR; ConstantMatch(int64_t &C) : CR(C) {} bool match(const MachineRegisterInfo &MRI, Register Reg) { - if (auto MaybeCst = getConstantVRegVal(Reg, MRI)) { + if (auto MaybeCst = getConstantVRegSExtVal(Reg, MRI)) { CR = *MaybeCst; return true; } diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h index 9fad903ea16b..446aaf8c3551 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h @@ -121,14 +121,19 @@ void reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R); +/// If \p VReg is defined by a G_CONSTANT, return the corresponding value. +Optional getConstantVRegVal(Register VReg, + const MachineRegisterInfo &MRI); + /// If \p VReg is defined by a G_CONSTANT fits in int64_t /// returns it. -Optional getConstantVRegVal(Register VReg, - const MachineRegisterInfo &MRI); +Optional getConstantVRegSExtVal(Register VReg, + const MachineRegisterInfo &MRI); + /// Simple struct used to hold a constant integer value and a virtual /// register. struct ValueAndVReg { - int64_t Value; + APInt Value; Register VReg; }; /// If \p VReg is defined by a statically evaluable chain of diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 79f74a47d83c..90b1dcea2648 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -1029,8 +1029,7 @@ static Register getMemsetValue(Register Val, LLT Ty, MachineIRBuilder &MIB) { unsigned NumBits = Ty.getScalarSizeInBits(); auto ValVRegAndVal = getConstantVRegValWithLookThrough(Val, MRI); if (!Ty.isVector() && ValVRegAndVal) { - unsigned KnownVal = ValVRegAndVal->Value; - APInt Scalar = APInt(8, KnownVal); + APInt Scalar = ValVRegAndVal->Value.truncOrSelf(8); APInt SplatVal = APInt::getSplat(NumBits, Scalar); return MIB.buildConstant(Ty, SplatVal).getReg(0); } @@ -1411,7 +1410,7 @@ bool CombinerHelper::tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen) { auto LenVRegAndVal = getConstantVRegValWithLookThrough(Len, MRI); if (!LenVRegAndVal) return false; // Leave it to the legalizer to lower it to a libcall. - unsigned KnownLen = LenVRegAndVal->Value; + unsigned KnownLen = LenVRegAndVal->Value.getZExtValue(); if (KnownLen == 0) { MI.eraseFromParent(); @@ -1521,7 +1520,7 @@ bool CombinerHelper::matchPtrAddImmedChain(MachineInstr &MI, return false; // Pass the combined immediate to the apply function. - MatchInfo.Imm = MaybeImmVal->Value + MaybeImm2Val->Value; + MatchInfo.Imm = (MaybeImmVal->Value + MaybeImm2Val->Value).getSExtValue(); MatchInfo.Base = Base; return true; } @@ -1571,7 +1570,7 @@ bool CombinerHelper::matchShiftImmedChain(MachineInstr &MI, return false; // Pass the combined immediate to the apply function. - MatchInfo.Imm = MaybeImmVal->Value + MaybeImm2Val->Value; + MatchInfo.Imm = (MaybeImmVal->Value + MaybeImm2Val->Value).getSExtValue(); MatchInfo.Reg = Base; // There is no simple replacement for a saturating unsigned left shift that @@ -1654,7 +1653,7 @@ bool CombinerHelper::matchShiftOfShiftedLogic(MachineInstr &MI, if (!MaybeImmVal) return false; - const uint64_t C1Val = MaybeImmVal->Value; + const uint64_t C1Val = MaybeImmVal->Value.getZExtValue(); auto matchFirstShift = [&](const MachineInstr *MI, uint64_t &ShiftVal) { // Shift should match previous one and should be a one-use. @@ -1668,7 +1667,7 @@ bool CombinerHelper::matchShiftOfShiftedLogic(MachineInstr &MI, if (!MaybeImmVal) return false; - ShiftVal = MaybeImmVal->Value; + ShiftVal = MaybeImmVal->Value.getSExtValue(); return true; }; @@ -1738,10 +1737,11 @@ bool CombinerHelper::matchCombineMulToShl(MachineInstr &MI, assert(MI.getOpcode() == TargetOpcode::G_MUL && "Expected a G_MUL"); auto MaybeImmVal = getConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI); - if (!MaybeImmVal || !isPowerOf2_64(MaybeImmVal->Value)) + if (!MaybeImmVal) return false; - ShiftVal = Log2_64(MaybeImmVal->Value); - return true; + + ShiftVal = MaybeImmVal->Value.exactLogBase2(); + return (static_cast(ShiftVal) != -1); } bool CombinerHelper::applyCombineMulToShl(MachineInstr &MI, @@ -1787,7 +1787,7 @@ bool CombinerHelper::matchCombineShlOfExtend(MachineInstr &MI, return false; } - int64_t ShiftAmt = MaybeShiftAmtVal->Value; + int64_t ShiftAmt = MaybeShiftAmtVal->Value.getSExtValue(); MatchData.Reg = ExtSrc; MatchData.Imm = ShiftAmt; @@ -2026,7 +2026,7 @@ bool CombinerHelper::matchCombineShiftToUnmerge(MachineInstr &MI, if (!MaybeImmVal) return false; - ShiftVal = MaybeImmVal->Value; + ShiftVal = MaybeImmVal->Value.getSExtValue(); return ShiftVal >= Size / 2 && ShiftVal < Size; } @@ -2200,7 +2200,7 @@ bool CombinerHelper::matchCombineConstPtrAddToI2P(MachineInstr &MI, Register RHS = MI.getOperand(2).getReg(); MachineRegisterInfo &MRI = Builder.getMF().getRegInfo(); - if (auto RHSCst = getConstantVRegVal(RHS, MRI)) { + if (auto RHSCst = getConstantVRegSExtVal(RHS, MRI)) { int64_t Cst; if (mi_match(LHS, MRI, m_GIntToPtr(m_ICst(Cst)))) { NewCst = Cst + *RHSCst; @@ -2441,7 +2441,7 @@ bool CombinerHelper::matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) { assert(MI.getOpcode() == TargetOpcode::G_SELECT); if (auto MaybeCstCmp = getConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI)) { - OpIdx = MaybeCstCmp->Value ? 2 : 3; + OpIdx = MaybeCstCmp->Value.isNullValue() ? 3 : 2; return true; } return false; diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp index 2fedc034d315..3eca16808ea6 100644 --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp @@ -50,7 +50,7 @@ bool InstructionSelector::isOperandImmEqual( const MachineRegisterInfo &MRI) const { if (MO.isReg() && MO.getReg()) if (auto VRegVal = getConstantVRegValWithLookThrough(MO.getReg(), MRI)) - return VRegVal->Value == Value; + return VRegVal->Value.getSExtValue() == Value; return false; } diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp index 4d9580de3b7b..c19ee2e3860f 100644 --- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -255,8 +255,8 @@ void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, reportGISelFailure(MF, TPC, MORE, R); } -Optional llvm::getConstantVRegVal(Register VReg, - const MachineRegisterInfo &MRI) { +Optional llvm::getConstantVRegVal(Register VReg, + const MachineRegisterInfo &MRI) { Optional ValAndVReg = getConstantVRegValWithLookThrough(VReg, MRI, /*LookThroughInstrs*/ false); assert((!ValAndVReg || ValAndVReg->VReg == VReg) && @@ -266,6 +266,14 @@ Optional llvm::getConstantVRegVal(Register VReg, return ValAndVReg->Value; } +Optional llvm::getConstantVRegSExtVal(Register VReg, + const MachineRegisterInfo &MRI) { + Optional Val = getConstantVRegVal(VReg, MRI); + if (Val && Val->getBitWidth() <= 64) + return Val->getSExtValue(); + return None; +} + Optional llvm::getConstantVRegValWithLookThrough( Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs, bool HandleFConstant) { @@ -337,10 +345,7 @@ Optional llvm::getConstantVRegValWithLookThrough( } } - if (Val.getBitWidth() > 64) - return None; - - return ValueAndVReg{Val.getSExtValue(), VReg}; + return ValueAndVReg{Val, VReg}; } const ConstantFP * @@ -413,9 +418,8 @@ Optional llvm::ConstantFoldBinOp(unsigned Opcode, const Register Op1, if (!MaybeOp1Cst) return None; - LLT Ty = MRI.getType(Op1); - APInt C1(Ty.getSizeInBits(), *MaybeOp1Cst, true); - APInt C2(Ty.getSizeInBits(), *MaybeOp2Cst, true); + const APInt &C1 = *MaybeOp1Cst; + const APInt &C2 = *MaybeOp2Cst; switch (Opcode) { default: break; @@ -535,13 +539,13 @@ Optional llvm::ConstantFoldExtOp(unsigned Opcode, const Register Op1, const MachineRegisterInfo &MRI) { auto MaybeOp1Cst = getConstantVRegVal(Op1, MRI); if (MaybeOp1Cst) { - LLT Ty = MRI.getType(Op1); - APInt C1(Ty.getSizeInBits(), *MaybeOp1Cst, true); switch (Opcode) { default: break; - case TargetOpcode::G_SEXT_INREG: - return C1.trunc(Imm).sext(C1.getBitWidth()); + case TargetOpcode::G_SEXT_INREG: { + LLT Ty = MRI.getType(Op1); + return MaybeOp1Cst->trunc(Imm).sext(Ty.getScalarSizeInBits()); + } } } return None; diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp index 4126017c6fbd..c810fcaca766 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -574,7 +574,7 @@ static Optional getImmedFromMO(const MachineOperand &Root) { getConstantVRegValWithLookThrough(Root.getReg(), MRI, true); if (!ValAndVReg) return None; - Immed = ValAndVReg->Value; + Immed = ValAndVReg->Value.getSExtValue(); } else return None; return Immed; @@ -1109,8 +1109,8 @@ AArch64InstructionSelector::emitSelect(Register Dst, Register True, Register ZReg = Is32Bit ? AArch64::WZR : AArch64::XZR; if (TrueCst && FalseCst) { - auto T = TrueCst->Value; - auto F = FalseCst->Value; + int64_t T = TrueCst->Value.getSExtValue(); + int64_t F = FalseCst->Value.getSExtValue(); if (T == 0 && F == 1) { // G_SELECT cc, 0, 1 -> CSINC zreg, zreg, cc @@ -1130,7 +1130,7 @@ AArch64InstructionSelector::emitSelect(Register Dst, Register True, } if (TrueCst) { - auto T = TrueCst->Value; + int64_t T = TrueCst->Value.getSExtValue(); if (T == 1) { // G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr; @@ -1151,7 +1151,7 @@ AArch64InstructionSelector::emitSelect(Register Dst, Register True, } if (FalseCst) { - auto F = FalseCst->Value; + int64_t F = FalseCst->Value.getSExtValue(); if (F == 1) { // G_SELECT cc, t, 1 -> CSINC t, zreg, cc Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr; @@ -1304,7 +1304,7 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert, VRegAndVal = getConstantVRegValWithLookThrough(ConstantReg, MRI); } if (VRegAndVal) - C = VRegAndVal->Value; + C = VRegAndVal->Value.getSExtValue(); break; } case TargetOpcode::G_ASHR: @@ -1314,7 +1314,7 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert, auto VRegAndVal = getConstantVRegValWithLookThrough(MI->getOperand(2).getReg(), MRI); if (VRegAndVal) - C = VRegAndVal->Value; + C = VRegAndVal->Value.getSExtValue(); break; } } @@ -1442,10 +1442,13 @@ bool AArch64InstructionSelector::tryOptAndIntoCompareBranch( // (e.g, ANDing with 8 == ANDing with 000...100 == testing if bit 3 is set) auto MaybeBit = getConstantVRegValWithLookThrough( AndInst.getOperand(2).getReg(), *MIB.getMRI()); - if (!MaybeBit || !isPowerOf2_64(MaybeBit->Value)) + if (!MaybeBit) + return false; + + int32_t Bit = MaybeBit->Value.exactLogBase2(); + if (Bit < 0) return false; - uint64_t Bit = Log2_64(static_cast(MaybeBit->Value)); Register TestReg = AndInst.getOperand(1).getReg(); // Emit a TB(N)Z. @@ -1522,7 +1525,7 @@ bool AArch64InstructionSelector::tryOptCompareBranchFedByICmp( // Note that we don't want to do this when we have a G_AND because it can // become a tst. The tst will make the test bit in the TB(N)Z redundant. if (VRegAndVal && !AndInst) { - int64_t C = VRegAndVal->Value; + int64_t C = VRegAndVal->Value.getSExtValue(); // When we have a greater-than comparison, we can just test if the msb is // zero. @@ -1654,8 +1657,8 @@ static Optional getVectorShiftImm(Register Reg, return None; if (Idx == 1) - ImmVal = VRegAndVal->Value; - if (ImmVal != VRegAndVal->Value) + ImmVal = VRegAndVal->Value.getSExtValue(); + if (ImmVal != VRegAndVal->Value.getSExtValue()) return None; } @@ -2735,7 +2738,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) { case TargetOpcode::G_PTRMASK: { Register MaskReg = I.getOperand(2).getReg(); - Optional MaskVal = getConstantVRegVal(MaskReg, MRI); + Optional MaskVal = getConstantVRegSExtVal(MaskReg, MRI); // TODO: Implement arbitrary cases if (!MaskVal || !isShiftedMask_64(*MaskVal)) return false; @@ -3749,7 +3752,7 @@ bool AArch64InstructionSelector::selectExtractElt( auto VRegAndVal = getConstantVRegValWithLookThrough(LaneIdxOp.getReg(), MRI); if (!VRegAndVal) return false; - unsigned LaneIdx = VRegAndVal->Value; + unsigned LaneIdx = VRegAndVal->Value.getSExtValue(); MachineIRBuilder MIRBuilder(I); @@ -4116,10 +4119,11 @@ AArch64InstructionSelector::emitTST(MachineOperand &LHS, MachineOperand &RHS, // ANDS needs a logical immediate for its immediate form. Check if we can // fold one in. if (auto ValAndVReg = getConstantVRegValWithLookThrough(RHS.getReg(), MRI)) { - if (AArch64_AM::isLogicalImmediate(ValAndVReg->Value, RegSize)) { + int64_t Imm = ValAndVReg->Value.getSExtValue(); + + if (AArch64_AM::isLogicalImmediate(Imm, RegSize)) { auto TstMI = MIRBuilder.buildInstr(OpcTable[0][Is32Bit], {Ty}, {LHS}); - TstMI.addImm( - AArch64_AM::encodeLogicalImmediate(ValAndVReg->Value, RegSize)); + TstMI.addImm(AArch64_AM::encodeLogicalImmediate(Imm, RegSize)); constrainSelectedInstRegOperands(*TstMI, TII, TRI, RBI); return &*TstMI; } @@ -4658,7 +4662,7 @@ bool AArch64InstructionSelector::selectInsertElt( auto VRegAndVal = getConstantVRegValWithLookThrough(IdxReg, MRI); if (!VRegAndVal) return false; - unsigned LaneIdx = VRegAndVal->Value; + unsigned LaneIdx = VRegAndVal->Value.getSExtValue(); // Perform the lane insert. Register SrcReg = I.getOperand(1).getReg(); @@ -5198,7 +5202,7 @@ AArch64InstructionSelector::selectExtendedSHL( // The value must fit into 3 bits, and must be positive. Make sure that is // true. - int64_t ImmVal = ValAndVReg->Value; + int64_t ImmVal = ValAndVReg->Value.getSExtValue(); // Since we're going to pull this into a shift, the constant value must be // a power of 2. If we got a multiply, then we need to check this. @@ -5362,7 +5366,7 @@ AArch64InstructionSelector::selectAddrModeXRO(MachineOperand &Root, getConstantVRegValWithLookThrough(PtrAdd->getOperand(2).getReg(), MRI); if (ValAndVReg) { unsigned Scale = Log2_32(SizeInBytes); - int64_t ImmOff = ValAndVReg->Value; + int64_t ImmOff = ValAndVReg->Value.getSExtValue(); // Skip immediates that can be selected in the load/store addresing // mode. @@ -5821,7 +5825,8 @@ void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB, const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo(); assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 && "Expected G_CONSTANT"); - Optional CstVal = getConstantVRegVal(MI.getOperand(0).getReg(), MRI); + Optional CstVal = + getConstantVRegSExtVal(MI.getOperand(0).getReg(), MRI); assert(CstVal && "Expected constant value"); MIB.addImm(CstVal.getValue()); } diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp index 73a7b8e7b83f..0774f7b02dd2 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -837,7 +837,7 @@ bool AArch64LegalizerInfo::legalizeShlAshrLshr( if (!VRegAndVal) return true; // Check the shift amount is in range for an immediate form. - int64_t Amount = VRegAndVal->Value; + int64_t Amount = VRegAndVal->Value.getSExtValue(); if (Amount > 31) return true; // This will have to remain a register variant. auto ExtCst = MIRBuilder.buildConstant(LLT::scalar(64), Amount); diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp index ce298c766e41..fdd04cb77fad 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp @@ -130,7 +130,7 @@ bool matchAArch64MulConstCombine( if (!Const) return false; - const APInt &ConstValue = APInt(Ty.getSizeInBits(), Const->Value, true); + const APInt ConstValue = Const->Value.sextOrSelf(Ty.getSizeInBits()); // The following code is ported from AArch64ISelLowering. // Multiplication of a power of two plus/minus one can be done more // cheaply as as shift+add/sub. For now, this is true unilaterally. If diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp index 43f28729baa1..a06ff4b5417a 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp @@ -438,7 +438,7 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P, auto ValAndVReg = getConstantVRegValWithLookThrough(RHS, MRI); if (!ValAndVReg) return None; - uint64_t C = ValAndVReg->Value; + uint64_t C = ValAndVReg->Value.getZExtValue(); if (isLegalArithImmed(C)) return None; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp index 6c2ff0972ae5..ac6ddbae350b 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -611,8 +611,10 @@ bool AMDGPUInstructionSelector::selectG_BUILD_VECTOR_TRUNC( if (ConstSrc1) { auto ConstSrc0 = getConstantVRegValWithLookThrough(Src0, *MRI, true, true); if (ConstSrc0) { - uint32_t Lo16 = static_cast(ConstSrc0->Value) & 0xffff; - uint32_t Hi16 = static_cast(ConstSrc1->Value) & 0xffff; + const int64_t K0 = ConstSrc0->Value.getSExtValue(); + const int64_t K1 = ConstSrc1->Value.getSExtValue(); + uint32_t Lo16 = static_cast(K0) & 0xffff; + uint32_t Hi16 = static_cast(K1) & 0xffff; BuildMI(*BB, &MI, DL, TII.get(AMDGPU::S_MOV_B32), Dst) .addImm(Lo16 | (Hi16 << 16)); @@ -820,7 +822,7 @@ bool AMDGPUInstructionSelector::selectWritelane(MachineInstr &MI) const { // The selector has to be an inline immediate, so we can use whatever for // the other operands. MIB.addReg(Val); - MIB.addImm(ConstSelect->Value & + MIB.addImm(ConstSelect->Value.getSExtValue() & maskTrailingOnes(STI.getWavefrontSizeLog2())); } else { Optional ConstVal = @@ -828,9 +830,9 @@ bool AMDGPUInstructionSelector::selectWritelane(MachineInstr &MI) const { // If the value written is an inline immediate, we can get away without a // copy to m0. - if (ConstVal && AMDGPU::isInlinableLiteral32(ConstVal->Value, + if (ConstVal && AMDGPU::isInlinableLiteral32(ConstVal->Value.getSExtValue(), STI.hasInv2PiInlineImm())) { - MIB.addImm(ConstVal->Value); + MIB.addImm(ConstVal->Value.getSExtValue()); MIB.addReg(LaneSelect); } else { MIB.addReg(Val); @@ -1101,7 +1103,7 @@ bool AMDGPUInstructionSelector::selectBallot(MachineInstr &I) const { getConstantVRegValWithLookThrough(I.getOperand(2).getReg(), *MRI, true); if (Arg.hasValue()) { - const int64_t Value = Arg.getValue().Value; + const int64_t Value = Arg.getValue().Value.getSExtValue(); if (Value == 0) { unsigned Opcode = Is64 ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32; BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg).addImm(0); @@ -3430,7 +3432,7 @@ AMDGPUInstructionSelector::selectFlatOffsetImpl(MachineOperand &Root) const { return Default; Optional Offset = - getConstantVRegVal(OpDef->getOperand(2).getReg(), *MRI); + getConstantVRegSExtVal(OpDef->getOperand(2).getReg(), *MRI); if (!Offset.hasValue()) return Default; @@ -3919,7 +3921,7 @@ AMDGPUInstructionSelector::getPtrBaseWithConstantOffset( = getConstantVRegValWithLookThrough(RHS.getReg(), MRI, true); if (!MaybeOffset) return {Root, 0}; - return {RootI->getOperand(1).getReg(), MaybeOffset->Value}; + return {RootI->getOperand(1).getReg(), MaybeOffset->Value.getSExtValue()}; } static void addZeroImm(MachineInstrBuilder &MIB) { @@ -4247,7 +4249,7 @@ AMDGPUInstructionSelector::selectMUBUFOffsetAtomic(MachineOperand &Root) const { static Optional getConstantZext32Val(Register Reg, const MachineRegisterInfo &MRI) { // getConstantVRegVal sexts any values, so see if that matters. - Optional OffsetVal = getConstantVRegVal(Reg, MRI); + Optional OffsetVal = getConstantVRegSExtVal(Reg, MRI); if (!OffsetVal || !isInt<32>(*OffsetVal)) return None; return Lo_32(*OffsetVal); diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp index 28cd867d40be..8c733a2afa03 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -2087,10 +2087,11 @@ bool AMDGPULegalizerInfo::legalizeExtractVectorElt( // FIXME: Artifact combiner probably should have replaced the truncated // constant before this, so we shouldn't need // getConstantVRegValWithLookThrough. - Optional IdxVal = getConstantVRegValWithLookThrough( - MI.getOperand(2).getReg(), MRI); - if (!IdxVal) // Dynamic case will be selected to register indexing. + Optional MaybeIdxVal = + getConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI); + if (!MaybeIdxVal) // Dynamic case will be selected to register indexing. return true; + const int64_t IdxVal = MaybeIdxVal->Value.getSExtValue(); Register Dst = MI.getOperand(0).getReg(); Register Vec = MI.getOperand(1).getReg(); @@ -2099,8 +2100,8 @@ bool AMDGPULegalizerInfo::legalizeExtractVectorElt( LLT EltTy = VecTy.getElementType(); assert(EltTy == MRI.getType(Dst)); - if (IdxVal->Value < VecTy.getNumElements()) - B.buildExtract(Dst, Vec, IdxVal->Value * EltTy.getSizeInBits()); + if (IdxVal < VecTy.getNumElements()) + B.buildExtract(Dst, Vec, IdxVal * EltTy.getSizeInBits()); else B.buildUndef(Dst); @@ -2118,11 +2119,12 @@ bool AMDGPULegalizerInfo::legalizeInsertVectorElt( // FIXME: Artifact combiner probably should have replaced the truncated // constant before this, so we shouldn't need // getConstantVRegValWithLookThrough. - Optional IdxVal = getConstantVRegValWithLookThrough( - MI.getOperand(3).getReg(), MRI); - if (!IdxVal) // Dynamic case will be selected to register indexing. + Optional MaybeIdxVal = + getConstantVRegValWithLookThrough(MI.getOperand(3).getReg(), MRI); + if (!MaybeIdxVal) // Dynamic case will be selected to register indexing. return true; + int64_t IdxVal = MaybeIdxVal->Value.getSExtValue(); Register Dst = MI.getOperand(0).getReg(); Register Vec = MI.getOperand(1).getReg(); Register Ins = MI.getOperand(2).getReg(); @@ -2131,8 +2133,8 @@ bool AMDGPULegalizerInfo::legalizeInsertVectorElt( LLT EltTy = VecTy.getElementType(); assert(EltTy == MRI.getType(Ins)); - if (IdxVal->Value < VecTy.getNumElements()) - B.buildInsert(Dst, Vec, Ins, IdxVal->Value * EltTy.getSizeInBits()); + if (IdxVal < VecTy.getNumElements()) + B.buildInsert(Dst, Vec, Ins, IdxVal * EltTy.getSizeInBits()); else B.buildUndef(Dst); @@ -2643,7 +2645,7 @@ bool AMDGPULegalizerInfo::legalizeBuildVector( static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI) { if (MI.getOpcode() != TargetOpcode::G_XOR) return false; - auto ConstVal = getConstantVRegVal(MI.getOperand(2).getReg(), MRI); + auto ConstVal = getConstantVRegSExtVal(MI.getOperand(2).getReg(), MRI); return ConstVal && *ConstVal == -1; } diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp index 6168b50f9cef..54124d7b5a6e 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp @@ -1331,7 +1331,7 @@ static unsigned setBufferOffsets(MachineIRBuilder &B, const LLT S32 = LLT::scalar(32); MachineRegisterInfo *MRI = B.getMRI(); - if (Optional Imm = getConstantVRegVal(CombinedOffset, *MRI)) { + if (Optional Imm = getConstantVRegSExtVal(CombinedOffset, *MRI)) { uint32_t SOffset, ImmOffset; if (AMDGPU::splitMUBUFOffset(*Imm, SOffset, ImmOffset, &RBI.Subtarget, Alignment)) { diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp index 5b31b8e09c5c..630df2715b89 100644 --- a/llvm/lib/Target/X86/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp @@ -479,7 +479,7 @@ static void X86SelectAddress(const MachineInstr &I, "unsupported type."); if (I.getOpcode() == TargetOpcode::G_PTR_ADD) { - if (auto COff = getConstantVRegVal(I.getOperand(2).getReg(), MRI)) { + if (auto COff = getConstantVRegSExtVal(I.getOperand(2).getReg(), MRI)) { int64_t Imm = *COff; if (isInt<32>(Imm)) { // Check for displacement overflow. AM.Disp = static_cast(Imm);