[llvm] [InstCombine] Fold `select (a == b | other_cond), a, b` to `select (other_cond), a, b` (PR #76203)

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 22 23:49:22 PST 2023


================
@@ -965,3 +965,139 @@ define i1 @or_and3_wrong_operand(i1 %a, i1 %b, i32 %x, i32 %y, i1 %d) {
   %r = select i1 %cond, i1 %d, i1 %b
   ret i1 %r
 }
+
+define i32 @or_eq_a_b(i1 %other_cond, i32 %a, i32 %b)  {
+; CHECK-LABEL: @or_eq_a_b(
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+;
+  %cmp = icmp eq i32 %a, %b
+  %cond = or i1 %other_cond, %cmp
+  %select = select i1 %cond, i32 %a, i32 %b
+  ret i32 %select
+}
+
+define i32 @and_ne_a_b(i1 %other_cond, i32 %a, i32 %b)  {
+; CHECK-LABEL: @and_ne_a_b(
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+;
+  %cmp = icmp ne i32 %a, %b
+  %cond = and i1 %other_cond, %cmp
+  %select = select i1 %cond, i32 %a, i32 %b
+  ret i32 %select
+}
+
+define i32 @or_eq_a_b_commuted(i1 %other_cond, i32 %a, i32 %b)  {
+; CHECK-LABEL: @or_eq_a_b_commuted(
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i32 [[B:%.*]], i32 [[A:%.*]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+;
+  %cmp = icmp eq i32 %a, %b
+  %cond = or i1 %other_cond, %cmp
+  %select = select i1 %cond, i32 %b, i32 %a
+  ret i32 %select
+}
+
+define i32 @and_ne_a_b_commuted(i1 %other_cond, i32 %a, i32 %b)  {
+; CHECK-LABEL: @and_ne_a_b_commuted(
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i32 [[B:%.*]], i32 [[A:%.*]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+;
+  %cmp = icmp ne i32 %a, %b
+  %cond = and i1 %other_cond, %cmp
+  %select = select i1 %cond, i32 %b, i32 %a
+  ret i32 %select
+}
+
+define i32 @or_eq_different_operands(i32 %a, i32 %b, i32 %c)  {
+; CHECK-LABEL: @or_eq_different_operands(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+;
+entry:
+  %cmp = icmp eq i32 %a, %c
+  %cmp1 = icmp eq i32 %b, %a
+  %cond = or i1 %cmp, %cmp1
+  %select = select i1 %cond, i32 %a, i32 %b
+  ret i32 %select
+}
+
+define i32 @or_eq_a_b_multi_use(i1 %other_cond, i32 %a, i32 %b)  {
+; CHECK-LABEL: @or_eq_a_b_multi_use(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[COND:%.*]] = or i1 [[CMP]], [[OTHER_COND:%.*]]
+; CHECK-NEXT:    call void @use(i1 [[CMP]])
+; CHECK-NEXT:    call void @use(i1 [[COND]])
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND]], i32 [[A]], i32 [[B]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+;
+  %cmp = icmp eq i32 %a, %b
+  %cond = or i1 %other_cond, %cmp
+  call void @use(i1 %cmp)
+  call void @use(i1 %cond)
+  %select = select i1 %cond, i32 %a, i32 %b
+  ret i32 %select
+}
+
+define <2 x i32> @or_eq_a_b_vec(<2 x i1> %other_cond ,<2 x i32> %a, <2 x i32> %b)  {
+; CHECK-LABEL: @or_eq_a_b_vec(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SELECT:%.*]] = select <2 x i1> [[OTHER_COND:%.*]], <2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]
+; CHECK-NEXT:    ret <2 x i32> [[SELECT]]
+;
+entry:
+  %cmp = icmp eq <2 x i32> %a, %b
+  %cond = or <2 x i1> %other_cond, %cmp
+  %select = select <2 x i1> %cond, <2 x i32> %a, <2 x i32> %b
+  ret <2 x i32> %select
+}
+
+define i32 @or_slt_a_b_fail(i1 %other_cond ,i32 %a, i32 %b)  {
+; CHECK-LABEL: @or_slt_a_b_fail(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[COND:%.*]] = or i1 [[CMP]], [[OTHER_COND:%.*]]
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+; CHECK:       0:
----------------
XChy wrote:

I don't know why there are extra checks, but utils/update_test_checks.py indeed generates it.

https://github.com/llvm/llvm-project/pull/76203


More information about the llvm-commits mailing list