diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp index bee0605bd556..bdf5c3b03663 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -4587,6 +4587,29 @@ unsigned AMDGPUTargetLowering::ComputeNumSignBitsForTargetNode( } } +unsigned AMDGPUTargetLowering::computeNumSignBitsForTargetInstr( + GISelKnownBits &Analysis, Register R, + const APInt &DemandedElts, const MachineRegisterInfo &MRI, + unsigned Depth) const { + const MachineInstr *MI = MRI.getVRegDef(R); + if (!MI) + return 1; + + // TODO: Check range metadata on MMO. + switch (MI->getOpcode()) { + case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE: + return 25; + case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT: + return 17; + case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE: + return 24; + case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT: + return 16; + default: + return 1; + } +} + bool AMDGPUTargetLowering::isKnownNeverNaNForTargetNode(SDValue Op, const SelectionDAG &DAG, bool SNaN, diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h index 54747b57f6f4..7d0b17f7e816 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h @@ -269,6 +269,12 @@ public: const SelectionDAG &DAG, unsigned Depth = 0) const override; + unsigned computeNumSignBitsForTargetInstr(GISelKnownBits &Analysis, + Register R, + const APInt &DemandedElts, + const MachineRegisterInfo &MRI, + unsigned Depth = 0) const override; + bool isKnownNeverNaNForTargetNode(SDValue Op, const SelectionDAG &DAG, bool SNaN = false, diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp index 5b59ee74852a..ef50a0f281f0 100644 --- a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp @@ -66,3 +66,41 @@ body: | Twine(MIRFunc) + Twine("...\n")) .toNullTerminatedStringRef(S); } + +std::unique_ptr +AMDGPUGISelMITest::createTargetMachine() const { + Triple TargetTriple("amdgcn-amd-amdhsa"); + std::string Error; + const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); + if (!T) + return nullptr; + + TargetOptions Options; + return std::unique_ptr( + static_cast(T->createTargetMachine( + "amdgcn-amd-amdhsa", "gfx900", "", Options, None, None, + CodeGenOpt::Aggressive))); +} + +void AMDGPUGISelMITest::getTargetTestModuleString( + SmallString<512> &S, StringRef MIRFunc) const { + (Twine(R"MIR( +--- +... +name: func +tracksRegLiveness: true +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } + - { id: 2, class: _ } + - { id: 3, class: _ } +body: | + bb.1: + liveins: $vgpr0, $vgpr1, $vgpr2 + + %0(s32) = COPY $vgpr0 + %1(s32) = COPY $vgpr1 + %2(s32) = COPY $vgpr2 +)MIR") + Twine(MIRFunc) + Twine("...\n")) + .toNullTerminatedStringRef(S); +} diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h index 53f5a1c4cd8c..db3f2b9531c9 100644 --- a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h +++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h @@ -146,6 +146,12 @@ class AArch64GISelMITest : public GISelMITest { StringRef MIRFunc) const override; }; +class AMDGPUGISelMITest : public GISelMITest { + std::unique_ptr createTargetMachine() const override; + void getTargetTestModuleString(SmallString<512> &S, + StringRef MIRFunc) const override; +}; + #define DefineLegalizerInfo(Name, SettingUpActionsBlock) \ class Name##Info : public LegalizerInfo { \ public: \ diff --git a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp index e2479b93e730..fe0c14270ecf 100644 --- a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp @@ -398,3 +398,36 @@ TEST_F(AArch64GISelMITest, TestNumSignBitsTrunc) { EXPECT_EQ(8u, Info.computeNumSignBits(CopyTruncNeg1)); EXPECT_EQ(5u, Info.computeNumSignBits(CopyTrunc7)); } + +TEST_F(AMDGPUGISelMITest, TestNumSignBitsTrunc) { + StringRef MIRString = + " %3:_(<4 x s32>) = G_IMPLICIT_DEF\n" + " %4:_(s32) = G_IMPLICIT_DEF\n" + " %5:_(s32) = G_AMDGPU_BUFFER_LOAD_UBYTE %3, %4, %4, %4, 0, 0, 0 :: (load 1)\n" + " %6:_(s32) = COPY %5\n" + + " %7:_(s32) = G_AMDGPU_BUFFER_LOAD_SBYTE %3, %4, %4, %4, 0, 0, 0 :: (load 1)\n" + " %8:_(s32) = COPY %7\n" + + " %9:_(s32) = G_AMDGPU_BUFFER_LOAD_USHORT %3, %4, %4, %4, 0, 0, 0 :: (load 2)\n" + " %10:_(s32) = COPY %9\n" + + " %11:_(s32) = G_AMDGPU_BUFFER_LOAD_SSHORT %3, %4, %4, %4, 0, 0, 0 :: (load 2)\n" + " %12:_(s32) = COPY %11\n"; + + setUp(MIRString); + if (!TM) + return; + + Register CopyLoadUByte = Copies[Copies.size() - 4]; + Register CopyLoadSByte = Copies[Copies.size() - 3]; + Register CopyLoadUShort = Copies[Copies.size() - 2]; + Register CopyLoadSShort = Copies[Copies.size() - 1]; + + GISelKnownBits Info(*MF); + + EXPECT_EQ(24u, Info.computeNumSignBits(CopyLoadUByte)); + EXPECT_EQ(25u, Info.computeNumSignBits(CopyLoadSByte)); + EXPECT_EQ(16u, Info.computeNumSignBits(CopyLoadUShort)); + EXPECT_EQ(17u, Info.computeNumSignBits(CopyLoadSShort)); +}