[llvm] [InstCombine] Combine and->cmp->sel->or-disjoint into and->mul (PR #135274)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 11 09:16:44 PDT 2025
================
@@ -2035,3 +2035,109 @@ define i32 @or_xor_and_commuted3(i32 %x, i32 %y, i32 %z) {
%or1 = or i32 %xor, %yy
ret i32 %or1
}
+
+define i32 @add_select_cmp_and1(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and1(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and2(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and2(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 5
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 4
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 288
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and3(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and3(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[TEMP:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: [[BITOP2:%.*]] = and i32 [[IN]], 4
+; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[BITOP2]], 0
+; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 0, i32 288
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[TEMP]], [[SEL2]]
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %temp = or disjoint i32 %sel0, %sel1
+ %bitop2 = and i32 %in, 4
+ %cmp2 = icmp eq i32 %bitop2, 0
+ %sel2 = select i1 %cmp2, i32 0, i32 288
+ %out = or disjoint i32 %temp, %sel2
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and4(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and4(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[TEMP:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[IN]], 12
+; CHECK-NEXT: [[TEMP2:%.*]] = mul nuw nsw i32 [[TMP2]], 72
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[TEMP]], [[TEMP2]]
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %temp = or disjoint i32 %sel0, %sel1
+ %bitop2 = and i32 %in, 4
+ %cmp2 = icmp eq i32 %bitop2, 0
+ %bitop3 = and i32 %in, 8
+ %cmp3 = icmp eq i32 %bitop3, 0
+ %sel2 = select i1 %cmp2, i32 0, i32 288
+ %sel3 = select i1 %cmp3, i32 0, i32 576
+ %temp2 = or disjoint i32 %sel2, %sel3
+ %out = or disjoint i32 %temp, %temp2
+ ret i32 %out
+}
+
+
+
+define i32 @add_select_cmp_and_mismatch(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and_mismatch(
+; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 3
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 288
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 3
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 288
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
----------------
arsenm wrote:
Test vector cases
https://github.com/llvm/llvm-project/pull/135274
More information about the llvm-commits
mailing list