diff --git a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp --- a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -347,6 +347,7 @@ Known = Known.sext(BitWidth); break; } + case TargetOpcode::G_ASSERT_SEXT: case TargetOpcode::G_SEXT_INREG: { computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts, Depth + 1); diff --git a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp --- a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp @@ -842,6 +842,77 @@ EXPECT_EQ(1u, Res.Zero.getZExtValue()); } +TEST_F(AArch64GISelMITest, TestKnownBitsAssertSext) { + StringRef MIRString = R"( + ; 000...0001 + %one:_(s32) = G_CONSTANT i32 1 + + ; 000...0010 + %two:_(s32) = G_CONSTANT i32 2 + + ; 000...1010 + %ten:_(s32) = G_CONSTANT i32 10 + + ; ???...???? + %w0:_(s32) = COPY $w0 + + ; ???...?1? + %or:_(s32) = G_OR %w0, %two + + ; All bits are known. + %assert_sext1:_(s32) = G_ASSERT_SEXT %one, 1 + %copy_assert_sext1:_(s32) = COPY %assert_sext1 + + ; All bits unknown + %assert_sext2:_(s32) = G_ASSERT_SEXT %or, 1 + %copy_assert_sext2:_(s32) = COPY %assert_sext2 + + ; Extending from the only (known) set bit + ; 111...11? + %assert_sext3:_(s32) = G_ASSERT_SEXT %or, 2 + %copy_assert_sext3:_(s32) = COPY %assert_sext3 + + ; Extending from a known set bit, overwriting all of the high set bits. + ; 111...1110 + %assert_sext4:_(s32) = G_ASSERT_SEXT %ten, 2 + %copy_assert_sext4:_(s32) = COPY %assert_sext4 +)"; + setUp(MIRString); + if (!TM) + return; + GISelKnownBits Info(*MF); + KnownBits Res; + auto GetKB = [&](unsigned Idx) { + Register CopyReg = Copies[Idx]; + auto *Copy = MRI->getVRegDef(CopyReg); + return Info.getKnownBits(Copy->getOperand(1).getReg()); + }; + + // Every bit is known to be a 1. + Res = GetKB(Copies.size() - 4); + EXPECT_EQ(32u, Res.getBitWidth()); + EXPECT_TRUE(Res.isAllOnes()); + + // All bits are unknown + Res = GetKB(Copies.size() - 3); + EXPECT_EQ(32u, Res.getBitWidth()); + EXPECT_TRUE(Res.isUnknown()); + + // Extending from the only known set bit + // 111...11? + Res = GetKB(Copies.size() - 2); + EXPECT_EQ(32u, Res.getBitWidth()); + EXPECT_EQ(0xFFFFFFFEu, Res.One.getZExtValue()); + EXPECT_EQ(0u, Res.Zero.getZExtValue()); + + // Extending from a known set bit, overwriting all of the high set bits. + // 111...1110 + Res = GetKB(Copies.size() - 1); + EXPECT_EQ(32u, Res.getBitWidth()); + EXPECT_EQ(0xFFFFFFFEu, Res.One.getZExtValue()); + EXPECT_EQ(1u, Res.Zero.getZExtValue()); +} + TEST_F(AArch64GISelMITest, TestKnownBitsMergeValues) { StringRef MIRString = R"( %val0:_(s16) = G_CONSTANT i16 35224