Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -2004,6 +2004,10 @@ if (const Operator *I = dyn_cast(V)) computeKnownBitsFromOperator(I, DemandedElts, Known, Depth, Q); + else if (const GlobalValue *GV = dyn_cast(V)) { + if (std::optional CR = GV->getAbsoluteSymbolRange()) + Known = CR->toKnownBits(); + } // Aligned pointers have trailing zeros - refine Known.Zero set if (isa(V->getType())) { Index: llvm/unittests/Analysis/ValueTrackingTest.cpp =================================================================== --- llvm/unittests/Analysis/ValueTrackingTest.cpp +++ llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -2449,6 +2449,93 @@ EXPECT_EQ(Known.getMaxValue(), 575); } +TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAbsoluteSymbol) { + auto M = parseModule(R"( + @absolute_0_255 = external global [128 x i32], align 1, !absolute_symbol !0 + @absolute_0_256 = external global [128 x i32], align 1, !absolute_symbol !1 + @absolute_256_512 = external global [128 x i32], align 1, !absolute_symbol !2 + @absolute_0_neg1 = external global [128 x i32], align 1, !absolute_symbol !3 + @absolute_neg32_32 = external global [128 x i32], align 1, !absolute_symbol !4 + @absolute_neg32_33 = external global [128 x i32], align 1, !absolute_symbol !5 + @absolute_neg64_neg32 = external global [128 x i32], align 1, !absolute_symbol !6 + @absolute_0_256_align8 = external global [128 x i32], align 8, !absolute_symbol !1 + + !0 = !{i64 0, i64 255} + !1 = !{i64 0, i64 256} + !2 = !{i64 256, i64 512} + !3 = !{i64 0, i64 -1} + !4 = !{i64 -32, i64 32} + !5 = !{i64 -32, i64 33} + !6 = !{i64 -64, i64 -32} + )"); + + GlobalValue *Absolute_0_255 = M->getNamedValue("absolute_0_255"); + GlobalValue *Absolute_0_256 = M->getNamedValue("absolute_0_256"); + GlobalValue *Absolute_256_512 = M->getNamedValue("absolute_256_512"); + GlobalValue *Absolute_0_Neg1 = M->getNamedValue("absolute_0_neg1"); + GlobalValue *Absolute_Neg32_32 = M->getNamedValue("absolute_neg32_32"); + GlobalValue *Absolute_Neg32_33 = M->getNamedValue("absolute_neg32_33"); + GlobalValue *Absolute_Neg64_Neg32 = M->getNamedValue("absolute_neg64_neg32"); + GlobalValue *Absolute_0_256_Align8 = M->getNamedValue("absolute_0_256_align8"); + + KnownBits Known_0_255 = computeKnownBits(Absolute_0_255, M->getDataLayout()); + EXPECT_EQ(64u - 8u, Known_0_255.countMinLeadingZeros()); + EXPECT_EQ(0u, Known_0_255.countMinTrailingZeros()); + EXPECT_EQ(0u, Known_0_255.countMinLeadingOnes()); + EXPECT_EQ(0u, Known_0_255.countMinTrailingOnes()); + + KnownBits Known_0_256 = computeKnownBits(Absolute_0_256, M->getDataLayout()); + EXPECT_EQ(64u - 8u, Known_0_256.countMinLeadingZeros()); + EXPECT_EQ(0u, Known_0_256.countMinTrailingZeros()); + EXPECT_EQ(0u, Known_0_256.countMinLeadingOnes()); + EXPECT_EQ(0u, Known_0_256.countMinTrailingOnes()); + + KnownBits Known_256_512 = + computeKnownBits(Absolute_256_512, M->getDataLayout()); + EXPECT_EQ(64u - 8u, Known_0_255.countMinLeadingZeros()); + EXPECT_EQ(0u, Known_0_255.countMinTrailingZeros()); + EXPECT_EQ(0u, Known_0_255.countMinLeadingOnes()); + EXPECT_EQ(0u, Known_0_255.countMinTrailingOnes()); + + KnownBits Known_0_Neg1 = + computeKnownBits(Absolute_0_Neg1, M->getDataLayout()); + EXPECT_EQ(0u, Known_0_Neg1.countMinLeadingZeros()); + EXPECT_EQ(0u, Known_0_Neg1.countMinTrailingZeros()); + EXPECT_EQ(0u, Known_0_Neg1.countMinLeadingOnes()); + EXPECT_EQ(0u, Known_0_Neg1.countMinTrailingOnes()); + + KnownBits Known_Neg32_32 = + computeKnownBits(Absolute_Neg32_32, M->getDataLayout()); + EXPECT_EQ(0u, Known_Neg32_32.countMinLeadingZeros()); + EXPECT_EQ(0u, Known_Neg32_32.countMinTrailingZeros()); + EXPECT_EQ(0u, Known_Neg32_32.countMinLeadingOnes()); + EXPECT_EQ(0u, Known_Neg32_32.countMinTrailingOnes()); + EXPECT_EQ(1u, Known_Neg32_32.countMinSignBits()); + + KnownBits Known_Neg32_33 = + computeKnownBits(Absolute_Neg32_33, M->getDataLayout()); + EXPECT_EQ(0u, Known_Neg32_33.countMinLeadingZeros()); + EXPECT_EQ(0u, Known_Neg32_33.countMinTrailingZeros()); + EXPECT_EQ(0u, Known_Neg32_33.countMinLeadingOnes()); + EXPECT_EQ(0u, Known_Neg32_33.countMinTrailingOnes()); + EXPECT_EQ(1u, Known_Neg32_33.countMinSignBits()); + + KnownBits Known_Neg32_Neg32 = + computeKnownBits(Absolute_Neg64_Neg32, M->getDataLayout()); + EXPECT_EQ(0u, Known_Neg32_Neg32.countMinLeadingZeros()); + EXPECT_EQ(0u, Known_Neg32_Neg32.countMinTrailingZeros()); + EXPECT_EQ(58u, Known_Neg32_Neg32.countMinLeadingOnes()); + EXPECT_EQ(0u, Known_Neg32_Neg32.countMinTrailingOnes()); + EXPECT_EQ(58u, Known_Neg32_Neg32.countMinSignBits()); + + + KnownBits Known_0_256_Align8 = computeKnownBits(Absolute_0_256_Align8, M->getDataLayout()); + EXPECT_EQ(64u - 8u, Known_0_256_Align8.countMinLeadingZeros()); + EXPECT_EQ(3u, Known_0_256_Align8.countMinTrailingZeros()); + EXPECT_EQ(0u, Known_0_256_Align8.countMinLeadingOnes()); + EXPECT_EQ(0u, Known_0_256_Align8.countMinTrailingOnes()); +} + TEST_F(ValueTrackingTest, HaveNoCommonBitsSet) { { // Check for an inverted mask: (X & ~M) op (Y & M).