Index: llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -470,6 +470,13 @@ unsigned Tmp = DstTy.getScalarSizeInBits() - SrcTy.getScalarSizeInBits(); return computeNumSignBits(Src, DemandedElts, Depth + 1) + Tmp; } + case TargetOpcode::G_SEXT_INREG: { + // Max of the input and what this extends. + Register Src = MI.getOperand(1).getReg(); + unsigned SrcBits = MI.getOperand(2).getImm(); + unsigned InRegBits = TyBits - SrcBits + 1; + return std::max(computeNumSignBits(Src, DemandedElts, Depth + 1), InRegBits); + } case TargetOpcode::G_TRUNC: { Register Src = MI.getOperand(1).getReg(); LLT SrcTy = MRI.getType(Src); Index: llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp =================================================================== --- llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp +++ llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp @@ -373,6 +373,70 @@ EXPECT_EQ(32u, Info.computeNumSignBits(CopySextNeg1)); } +TEST_F(AArch64GISelMITest, TestNumSignBitsSextInReg) { + StringRef MIRString = R"( + %ptr:_(p0) = G_IMPLICIT_DEF + %load4:_(s32) = G_LOAD %ptr :: (load 4) + + %inreg7:_(s32) = G_SEXT_INREG %load4, 7 + %copy_inreg7:_(s32) = COPY %inreg7 + + %inreg8:_(s32) = G_SEXT_INREG %load4, 8 + %copy_inreg8:_(s32) = COPY %inreg8 + + %inreg9:_(s32) = G_SEXT_INREG %load4, 9 + %copy_inreg9:_(s32) = COPY %inreg9 + + %inreg31:_(s32) = G_SEXT_INREG %load4, 31 + %copy_inreg31:_(s32) = COPY %inreg31 + + %load1:_(s8) = G_LOAD %ptr :: (load 1) + %sext_load1:_(s32) = G_SEXT %load1 + + %inreg6_sext:_(s32) = G_SEXT_INREG %sext_load1, 6 + %copy_inreg6_sext:_(s32) = COPY %inreg6_sext + + %inreg7_sext:_(s32) = G_SEXT_INREG %sext_load1, 7 + %copy_inreg7_sext:_(s32) = COPY %inreg7_sext + + %inreg8_sext:_(s32) = G_SEXT_INREG %sext_load1, 8 + %copy_inreg8_sext:_(s32) = COPY %inreg8_sext + + %inreg9_sext:_(s32) = G_SEXT_INREG %sext_load1, 9 + %copy_inreg9_sext:_(s32) = COPY %inreg9_sext + + %inreg31_sext:_(s32) = G_SEXT_INREG %sext_load1, 31 + %copy_inreg31_sext:_(s32) = COPY %inreg31_sext +)"; + + setUp(MIRString); + if (!TM) + return; + + Register CopyInReg7 = Copies[Copies.size() - 9]; + Register CopyInReg8 = Copies[Copies.size() - 8]; + Register CopyInReg9 = Copies[Copies.size() - 7]; + Register CopyInReg31 = Copies[Copies.size() - 6]; + + Register CopyInReg6Sext = Copies[Copies.size() - 5]; + Register CopyInReg7Sext = Copies[Copies.size() - 4]; + Register CopyInReg8Sext = Copies[Copies.size() - 3]; + Register CopyInReg9Sext = Copies[Copies.size() - 2]; + Register CopyInReg31Sext = Copies[Copies.size() - 1]; + + GISelKnownBits Info(*MF); + EXPECT_EQ(26u, Info.computeNumSignBits(CopyInReg7)); + EXPECT_EQ(25u, Info.computeNumSignBits(CopyInReg8)); + EXPECT_EQ(24u, Info.computeNumSignBits(CopyInReg9)); + EXPECT_EQ(2u, Info.computeNumSignBits(CopyInReg31)); + + EXPECT_EQ(27u, Info.computeNumSignBits(CopyInReg6Sext)); + EXPECT_EQ(26u, Info.computeNumSignBits(CopyInReg7Sext)); + EXPECT_EQ(25u, Info.computeNumSignBits(CopyInReg8Sext)); + EXPECT_EQ(25u, Info.computeNumSignBits(CopyInReg9Sext)); + EXPECT_EQ(25u, Info.computeNumSignBits(CopyInReg31Sext)); +} + TEST_F(AArch64GISelMITest, TestNumSignBitsTrunc) { StringRef MIRString = " %3:_(p0) = G_IMPLICIT_DEF\n" " %4:_(s32) = G_LOAD %3 :: (load 4)\n"