831 changes: 831 additions & 0 deletions llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion llvm/test/Transforms/InstCombine/ctpop-pow2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ define <2 x i64> @ctpop_x_and_negx_vec(<2 x i64> %x) {

define <2 x i32> @ctpop_x_and_negx_vec_nz(<2 x i32> %x) {
; CHECK-LABEL: @ctpop_x_and_negx_vec_nz(
; CHECK-NEXT: ret <2 x i32> <i32 1, i32 1>
; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1>
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]]
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X1]], [[SUB]]
; CHECK-NEXT: ret <2 x i32> [[AND]]
;
%x1 = or <2 x i32> %x, <i32 1 ,i32 1>
%sub = sub <2 x i32> <i32 0 ,i32 0>, %x1
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/Transforms/InstSimplify/ctpop-pow2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ define i8 @ctpop_x_nz_and_negx(i8 %x) {
; CHECK-NEXT: [[X1:%.*]] = or i8 [[X:%.*]], 1
; CHECK-NEXT: [[V0:%.*]] = sub i8 0, [[X1]]
; CHECK-NEXT: [[V1:%.*]] = and i8 [[X1]], [[V0]]
; CHECK-NEXT: [[CNT:%.*]] = call i8 @llvm.ctpop.i8(i8 [[V1]])
; CHECK-NEXT: ret i8 [[CNT]]
; CHECK-NEXT: ret i8 [[V1]]
;
%x1 = or i8 %x, 1
%v0 = sub i8 0, %x1
Expand Down
20 changes: 20 additions & 0 deletions llvm/unittests/Support/KnownBitsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,12 @@ TEST(KnownBitsTest, UnaryExhaustive) {
KnownAbs.Zero.setAllBits();
KnownAbs.One.setAllBits();
KnownBits KnownAbsPoison(KnownAbs);
KnownBits KnownBlsi(Bits);
KnownBlsi.Zero.setAllBits();
KnownBlsi.One.setAllBits();
KnownBits KnownBlsmsk(Bits);
KnownBlsmsk.Zero.setAllBits();
KnownBlsmsk.One.setAllBits();

ForeachNumInKnownBits(Known, [&](const APInt &N) {
APInt Res = N.abs();
Expand All @@ -294,6 +300,14 @@ TEST(KnownBitsTest, UnaryExhaustive) {
KnownAbsPoison.One &= Res;
KnownAbsPoison.Zero &= ~Res;
}

Res = N & -N;
KnownBlsi.One &= Res;
KnownBlsi.Zero &= ~Res;

Res = N ^ (N - 1);
KnownBlsmsk.One &= Res;
KnownBlsmsk.Zero &= ~Res;
});

// abs() is conservatively correct, but not guaranteed to be precise.
Expand All @@ -304,6 +318,12 @@ TEST(KnownBitsTest, UnaryExhaustive) {
KnownBits ComputedAbsPoison = Known.abs(true);
EXPECT_TRUE(ComputedAbsPoison.Zero.isSubsetOf(KnownAbsPoison.Zero));
EXPECT_TRUE(ComputedAbsPoison.One.isSubsetOf(KnownAbsPoison.One));

KnownBits ComputedBlsi = Known.blsi();
EXPECT_EQ(KnownBlsi, ComputedBlsi);

KnownBits ComputedBlsmsk = Known.blsmsk();
EXPECT_EQ(KnownBlsmsk, ComputedBlsmsk);
});
}

Expand Down