[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