diff --git a/llvm/test/Transforms/InstCombine/select_and_icmpeq.ll b/llvm/test/Transforms/InstCombine/select_and_icmpeq.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/select_and_icmpeq.ll @@ -0,0 +1,187 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define i1 @select_and_icmpeq_i32(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i32( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i32 2, i32 1 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i32 2, i32 1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i32 2, i32 1 + %s2 = select i1 %y, i32 2, i32 1 + %and = and i32 %s1, %s2 + %icmp = icmp eq i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i9(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i9( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i9 3, i9 16 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i9 3, i9 16 +; CHECK-NEXT: [[AND:%.*]] = and i9 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i9 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i9 3, i9 16 + %s2 = select i1 %y, i9 3, i9 16 + %and = and i9 %s2, %s1 + %icmp = icmp eq i9 %and, 0 + ret i1 %icmp +} + +define <5 x i1> @select_and_icmpeq_i1vec(<5 x i1> %x, <5 x i1> %y) { +; CHECK-LABEL: @select_and_icmpeq_i1vec( +; CHECK-NEXT: [[S1:%.*]] = select <5 x i1> [[X:%.*]], <5 x i32> , <5 x i32> +; CHECK-NEXT: [[S2:%.*]] = select <5 x i1> [[Y:%.*]], <5 x i32> , <5 x i32> +; CHECK-NEXT: [[AND:%.*]] = and <5 x i32> [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq <5 x i32> [[AND]], zeroinitializer +; CHECK-NEXT: ret <5 x i1> [[ICMP]] +; + %s1 = select <5 x i1> %x, <5 x i32> , <5 x i32> + %s2 = select <5 x i1> %y, <5 x i32> , <5 x i32> + %and = and <5 x i32> %s2, %s1 + %icmp = icmp eq <5 x i32> %and, + ret <5 x i1> %icmp +} + +define i1 @select_and_icmpeq_i8_negative_other_pred(i1 %x, i1 %y, i8 %u) { +; CHECK-LABEL: @select_and_icmpeq_i8_negative_other_pred( +; CHECK-NEXT: ret i1 false +; + %u0 = or i8 %u, 3 ; set two LSB + %v = and i8 %u0, 1 ; clear all bits, except LSB + + %s1 = select i1 %x, i8 %v, i8 8 + %s2 = select i1 %y, i8 %v, i8 8 + %and = and i8 %s1, %s2 + %icmp = icmp ult i8 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i16_negative_select_arm1_zero(i1 %x, i1 %y, i16 %z) { +; CHECK-LABEL: @select_and_icmpeq_i16_negative_select_arm1_zero( +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] +; + %z0 = and i16 %z, -2 ; LSB must be clear + %t = or i16 %z0, 42 ; set some other bits + + %s1 = select i1 %x, i16 0, i16 %t + %s2 = select i1 %y, i16 0, i16 %t + %and = and i16 %s1, %s2 + %icmp = icmp eq i16 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i16_negative_select_arm2_zero(i1 %x, i1 %y, i16 %z) { +; CHECK-LABEL: @select_and_icmpeq_i16_negative_select_arm2_zero( +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false +; CHECK-NEXT: [[NOT_:%.*]] = xor i1 [[TMP1]], true +; CHECK-NEXT: ret i1 [[NOT_]] +; + %z0 = and i16 %z, -2 ; LSB must be clear + %t = or i16 %z0, 42 ; set some other bits + + %s1 = select i1 %x, i16 %t, i16 0 + %s2 = select i1 %y, i16 %t, i16 0 + %and = and i16 %s1, %s2 + %icmp = icmp eq i16 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i12_negative_one_select_pair_matching1(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i12_negative_one_select_pair_matching1( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i12 0, i12 4 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i12 2, i12 4 +; CHECK-NEXT: [[AND:%.*]] = and i12 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i12 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i12 1, i12 4 + %s2 = select i1 %y, i12 2, i12 4 + %and = and i12 %s1, %s2 + %icmp = icmp eq i12 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i13_negative_one_select_pair_matching2(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i13_negative_one_select_pair_matching2( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i13 2, i13 0 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i13 2, i13 4 +; CHECK-NEXT: [[AND:%.*]] = and i13 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i13 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i13 2, i13 8 + %s2 = select i1 %y, i13 2, i13 4 + %and = and i13 %s1, %s2 + %icmp = icmp eq i13 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_negative_non_imm_no_common_bits_set_i32(i1 %x, i1 %y, i32 %z, i32 %u) { +; CHECK-LABEL: @select_and_icmpeq_negative_non_imm_no_common_bits_set_i32( +; CHECK-NEXT: ret i1 false +; + %z0 = or i32 %z, 1 ; LSB is set + %t = or i32 %z0, 42 ; set some other bits + + %u0 = or i32 %u, 3 ; set two LSB + %v = and i32 %u0, 1 ; only keep rightmost bit + + %s1 = select i1 %x, i32 %t, i32 %v ; the LSB is set + %s2 = select i1 %y, i32 %t, i32 %v ; the LSB is set + %and = and i32 %s1, %s2 + %icmp = icmp eq i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_negative_non_imm_is_known_non_zero_lhs_i12(i1 %x, i1 %y, i12 %z, i12 %u) { +; CHECK-LABEL: @select_and_icmpeq_negative_non_imm_is_known_non_zero_lhs_i12( +; CHECK-NEXT: [[Z0:%.*]] = and i12 [[Z:%.*]], -2 +; CHECK-NEXT: [[T:%.*]] = xor i12 [[Z0]], 42 +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i12 [[T]], i12 1 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i12 [[T]], i12 1 +; CHECK-NEXT: [[AND:%.*]] = and i12 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i12 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %z0 = and i12 %z, -2 ; LSB is clear + %t = xor i12 %z0, 42 ; set some other bits + + %u0 = or i12 %u, 3 ; set two LSB + %v = and i12 %u0, 1 ; only keep rightmost bit + + %s1 = select i1 %x, i12 %t, i12 %v + %s2 = select i1 %y, i12 %t, i12 %v + %and = and i12 %s2, %s1 + %icmp = icmp eq i12 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_negative_non_imm_is_known_non_zero_rhs_i12(i1 %x, i1 %y, i12 %z, i12 %u) { +; CHECK-LABEL: @select_and_icmpeq_negative_non_imm_is_known_non_zero_rhs_i12( +; CHECK-NEXT: [[Z0:%.*]] = and i12 [[Z:%.*]], -44 +; CHECK-NEXT: [[T:%.*]] = or i12 [[Z0]], 42 +; CHECK-NEXT: [[U0:%.*]] = and i12 [[U:%.*]], 1 +; CHECK-NEXT: [[V:%.*]] = xor i12 [[U0]], 1 +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i12 [[T]], i12 [[V]] +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i12 [[T]], i12 [[V]] +; CHECK-NEXT: [[AND:%.*]] = and i12 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i12 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %z0 = and i12 %z, -2 ; LSB is clear + %t = or i12 %z0, 42 ; set some other bits + + %u0 = xor i12 %u, 3 ; set two LSB + %v = and i12 %u0, 1 ; clear all bits + + %s1 = select i1 %x, i12 %t, i12 %v + %s2 = select i1 %y, i12 %t, i12 %v + %and = and i12 %s2, %s1 + %icmp = icmp eq i12 %and, 0 + ret i1 %icmp +} diff --git a/llvm/test/Transforms/InstCombine/select_and_icmpne.ll b/llvm/test/Transforms/InstCombine/select_and_icmpne.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/select_and_icmpne.ll @@ -0,0 +1,155 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define i1 @select_and_icmpne_i32(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpne_i32( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i32 2, i32 1 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i32 2, i32 1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i32 2, i32 1 + %s2 = select i1 %y, i32 2, i32 1 + %and = and i32 %s1, %s2 + %icmp = icmp ne i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpne_i9(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpne_i9( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i9 3, i9 16 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i9 3, i9 16 +; CHECK-NEXT: [[AND:%.*]] = and i9 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i9 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i9 3, i9 16 + %s2 = select i1 %y, i9 3, i9 16 + %and = and i9 %s2, %s1 + %icmp = icmp ne i9 %and, 0 + ret i1 %icmp +} + +define <5 x i1> @select_and_icmpne_i1vec(<5 x i1> %x, <5 x i1> %y) { +; CHECK-LABEL: @select_and_icmpne_i1vec( +; CHECK-NEXT: [[S1:%.*]] = select <5 x i1> [[X:%.*]], <5 x i32> , <5 x i32> +; CHECK-NEXT: [[S2:%.*]] = select <5 x i1> [[Y:%.*]], <5 x i32> , <5 x i32> +; CHECK-NEXT: [[AND:%.*]] = and <5 x i32> [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne <5 x i32> [[AND]], zeroinitializer +; CHECK-NEXT: ret <5 x i1> [[ICMP]] +; + %s1 = select <5 x i1> %x, <5 x i32> , <5 x i32> + %s2 = select <5 x i1> %y, <5 x i32> , <5 x i32> + %and = and <5 x i32> %s2, %s1 + %icmp = icmp ne <5 x i32> %and, + ret <5 x i1> %icmp +} + +define i1 @select_and_icmpne_i8_negative_other_pred(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpne_i8_negative_other_pred( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i8 1, i8 8 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i8 1, i8 8 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i8 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i8 1, i8 8 + %s2 = select i1 %y, i8 1, i8 8 + %and = and i8 %s1, %s2 + %icmp = icmp ugt i8 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpne_i4_negative_select_arm1_zero(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpne_i4_negative_select_arm1_zero( +; CHECK-NEXT: [[AND1_DEMORGAN:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[AND1:%.*]] = xor i1 [[AND1_DEMORGAN]], true +; CHECK-NEXT: ret i1 [[AND1]] +; + %s1 = select i1 %x, i4 0, i4 1 + %s2 = select i1 %y, i4 0, i4 1 + %and = and i4 %s1, %s2 + %icmp = icmp ne i4 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpne_i4_negative_select_arm2_zero(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpne_i4_negative_select_arm2_zero( +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false +; CHECK-NEXT: ret i1 [[TMP1]] +; + %s1 = select i1 %x, i4 2, i4 0 + %s2 = select i1 %y, i4 2, i4 0 + %and = and i4 %s1, %s2 + %icmp = icmp ne i4 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpne_i12_negative_one_select_pair_matching1(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpne_i12_negative_one_select_pair_matching1( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i12 0, i12 4 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i12 2, i12 4 +; CHECK-NEXT: [[AND:%.*]] = and i12 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i12 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i12 1, i12 4 + %s2 = select i1 %y, i12 2, i12 4 + %and = and i12 %s1, %s2 + %icmp = icmp ne i12 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpne_i13_negative_one_select_pair_matching2(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpne_i13_negative_one_select_pair_matching2( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i13 2, i13 0 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i13 2, i13 4 +; CHECK-NEXT: [[AND:%.*]] = and i13 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i13 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i13 2, i13 8 + %s2 = select i1 %y, i13 2, i13 4 + %and = and i13 %s1, %s2 + %icmp = icmp ne i13 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpne_negative_non_imm_no_common_bits_set_i32(i1 %x, i1 %y, i32 %z, i32 %u) { +; CHECK-LABEL: @select_and_icmpne_negative_non_imm_no_common_bits_set_i32( +; CHECK-NEXT: ret i1 true +; + %z0 = or i32 %z, 1 ; LSB is set + %t = or i32 %z0, 42 ; set some other bits + + %u0 = or i32 %u, 3 ; set two LSB + %v = and i32 %u0, 1 ; only keep rightmost bit + + %s1 = select i1 %x, i32 %t, i32 %v ; the LSB is set + %s2 = select i1 %y, i32 %t, i32 %v ; the LSB is set + %and = and i32 %s1, %s2 + %icmp = icmp ne i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpne_negative_non_imm_is_known_non_zero_i12(i1 %x, i1 %y, i12 %z, i12 %u) { +; CHECK-LABEL: @select_and_icmpne_negative_non_imm_is_known_non_zero_i12( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i12 [[Z:%.*]], i12 5 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i12 [[Z]], i12 5 +; CHECK-NEXT: [[AND:%.*]] = and i12 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i12 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %z0 = and i12 %z, -2 ; LSB is clear + %t = or i12 %z0, 42 ; set some other bits + + %u0 = xor i12 %u, 3 ; set two LSB + %v = and i12 %u0, 1 ; clear all bits + + %s1 = select i1 %x, i12 %z, i12 5 + %s2 = select i1 %y, i12 %z, i12 5 + %and = and i12 %s2, %s1 + %icmp = icmp ne i12 %and, 0 + ret i1 %icmp +}