diff options
Diffstat (limited to 'test/Transforms/InstCombine/and2.ll')
-rw-r--r-- | test/Transforms/InstCombine/and2.ll | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/test/Transforms/InstCombine/and2.ll b/test/Transforms/InstCombine/and2.ll index 001ac58891e46..15772d158f624 100644 --- a/test/Transforms/InstCombine/and2.ll +++ b/test/Transforms/InstCombine/and2.ll @@ -98,8 +98,7 @@ define i64 @test9(i64 %x) { ; combine -x & 1 into x & 1 define <2 x i64> @test9vec(<2 x i64> %x) { ; CHECK-LABEL: @test9vec( -; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i64> zeroinitializer, [[X:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[SUB]], <i64 1, i64 1> +; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> %x, <i64 1, i64 1> ; CHECK-NEXT: ret <2 x i64> [[AND]] ; %sub = sub nsw <2 x i64> <i64 0, i64 0>, %x @@ -119,6 +118,88 @@ define i64 @test10(i64 %x) { ret i64 %add } +; (1 << x) & 1 --> zext(x == 0) + +define i8 @and1_shl1_is_cmp_eq_0(i8 %x) { +; CHECK-LABEL: @and1_shl1_is_cmp_eq_0( +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 %x, 0 +; CHECK-NEXT: [[AND:%.*]] = zext i1 [[TMP1]] to i8 +; CHECK-NEXT: ret i8 [[AND]] +; + %sh = shl i8 1, %x + %and = and i8 %sh, 1 + ret i8 %and +} + +; Don't do it if the shift has another use. + +define i8 @and1_shl1_is_cmp_eq_0_multiuse(i8 %x) { +; CHECK-LABEL: @and1_shl1_is_cmp_eq_0_multiuse( +; CHECK-NEXT: [[SH:%.*]] = shl i8 1, %x +; CHECK-NEXT: [[AND:%.*]] = and i8 [[SH]], 1 +; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SH]], [[AND]] +; CHECK-NEXT: ret i8 [[ADD]] +; + %sh = shl i8 1, %x + %and = and i8 %sh, 1 + %add = add i8 %sh, %and + ret i8 %add +} + +; (1 << x) & 1 --> zext(x == 0) + +define <2 x i8> @and1_shl1_is_cmp_eq_0_vec(<2 x i8> %x) { +; CHECK-LABEL: @and1_shl1_is_cmp_eq_0_vec( +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> %x, zeroinitializer +; CHECK-NEXT: [[AND:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> +; CHECK-NEXT: ret <2 x i8> [[AND]] +; + %sh = shl <2 x i8> <i8 1, i8 1>, %x + %and = and <2 x i8> %sh, <i8 1, i8 1> + ret <2 x i8> %and +} + +; (1 >> x) & 1 --> zext(x == 0) + +define i8 @and1_lshr1_is_cmp_eq_0(i8 %x) { +; CHECK-LABEL: @and1_lshr1_is_cmp_eq_0( +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 %x, 0 +; CHECK-NEXT: [[AND:%.*]] = zext i1 [[TMP1]] to i8 +; CHECK-NEXT: ret i8 [[AND]] +; + %sh = lshr i8 1, %x + %and = and i8 %sh, 1 + ret i8 %and +} + +; Don't do it if the shift has another use. + +define i8 @and1_lshr1_is_cmp_eq_0_multiuse(i8 %x) { +; CHECK-LABEL: @and1_lshr1_is_cmp_eq_0_multiuse( +; CHECK-NEXT: [[SH:%.*]] = lshr i8 1, %x +; CHECK-NEXT: [[AND:%.*]] = and i8 [[SH]], 1 +; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SH]], [[AND]] +; CHECK-NEXT: ret i8 [[ADD]] +; + %sh = lshr i8 1, %x + %and = and i8 %sh, 1 + %add = add i8 %sh, %and + ret i8 %add +} + +; (1 >> x) & 1 --> zext(x == 0) + +define <2 x i8> @and1_lshr1_is_cmp_eq_0_vec(<2 x i8> %x) { +; CHECK-LABEL: @and1_lshr1_is_cmp_eq_0_vec( +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> %x, zeroinitializer +; CHECK-NEXT: [[AND:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> +; CHECK-NEXT: ret <2 x i8> [[AND]] +; + %sh = lshr <2 x i8> <i8 1, i8 1>, %x + %and = and <2 x i8> %sh, <i8 1, i8 1> + ret <2 x i8> %and +} + ; The add in this test is unnecessary because the LSBs of the LHS are 0 and the 'and' only consumes bits from those LSBs. It doesn't matter what happens to the upper bits. define i32 @test11(i32 %a, i32 %b) { ; CHECK-LABEL: @test11( |