[llvm] [InstSimplify] Simplify select if it combinated `and/or/xor` (PR #73362)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 27 09:36:50 PST 2023
================
@@ -1652,3 +1652,149 @@ define i8 @select_xor_cmp_unmatched_operands(i8 %0, i8 %1, i8 %c) {
%5 = select i1 %3, i8 0, i8 %4
ret i8 %5
}
+
+; Select icmp and/or/xor
+; X&Y==0 ? X|Y : X^Y -> X|Y
+define i32 @src_select_and0_or_xor(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_and0_or_xor(
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[XOR:%.*]]
+ %and = and i32 %x, %y
+ %and0 = icmp eq i32 %and, 0
+ %xor = xor i32 %x, %y
+ %or = or i32 %x, %y
+ %cond = select i1 %and0, i32 %or, i32 %xor
+ ret i32 %cond
+}
+; X&Y==0 ? X^Y : X|Y -> X|Y
+define i32 @src_select_and0_xor_or(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_and0_xor_or(
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[OR:%.*]]
+ %and = and i32 %x, %y
+ %and0 = icmp eq i32 %and, 0
+ %xor = xor i32 %x, %y
+ %or = or i32 %x, %y
+ %cond = select i1 %and0, i32 %xor, i32 %or
+ ret i32 %cond
+}
+; X&Y!=0 ? X|Y : X^Y -> X|Y
+define i32 @src_select_and1_or_xor(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_and1_or_xor(
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[OR:%.*]]
+ %and = and i32 %x, %y
+ %and1 = icmp ne i32 %and, 0
+ %xor = xor i32 %x, %y
+ %or = or i32 %x, %y
+ %cond = select i1 %and1, i32 %or, i32 %xor
+ ret i32 %cond
+}
+; X&Y!=0 ? X^Y : X|Y -> X^Y
+define i32 @src_select_and1_xor_or(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_and1_xor_or(
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[XOR:%.*]]
+ %and = and i32 %x, %y
+ %and1 = icmp ne i32 %and, 0
+ %xor = xor i32 %x, %y
+ %or = or i32 %x, %y
+ %cond = select i1 %and1, i32 %xor, i32 %or
+ ret i32 %cond
+}
+; X|Y==0 ? X&Y : X^Y -> X^Y
+define i32 @src_select_or0_and_xor(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_or0_and_xor(
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[XOR:%.*]]
+ %or = or i32 %x, %y
+ %or0 = icmp eq i32 %or, 0
+ %xor = xor i32 %x, %y
+ %and = and i32 %x, %y
+ %cond = select i1 %or0, i32 %and, i32 %xor
+ ret i32 %cond
+}
+; X|Y!=0 ? X&Y : X^Y -> X&Y
+define i32 @src_select_or1_and_xor(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_or1_and_xor(
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[AND:%.*]]
+ %or = or i32 %x, %y
+ %or1 = icmp ne i32 %or, 0
+ %xor = xor i32 %x, %y
+ %and = and i32 %x, %y
+ %cond = select i1 %or1, i32 %and, i32 %xor
+ ret i32 %cond
+}
+; X|Y==0 ? X^Y : X&Y -> X&Y
+define i32 @src_select_or0_xor_and(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_or0_xor_and(
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[AND:%.*]]
+ %or = or i32 %x, %y
+ %or0 = icmp eq i32 %or, 0
+ %xor = xor i32 %x, %y
+ %and = and i32 %x, %y
+ %cond = select i1 %or0, i32 %xor, i32 %and
+ ret i32 %cond
+}
+; X|Y==0 ? X^Y : X&Y -> X&Y
+define i32 @src_select_or1_xor_and(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_or1_xor_and(
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[XOR:%.*]]
+ %or = or i32 %x, %y
+ %or1 = icmp ne i32 %or, 0
+ %xor = xor i32 %x, %y
+ %and = and i32 %x, %y
+ %cond = select i1 %or1, i32 %xor, i32 %and
+ ret i32 %cond
+}
+; X^Y==0 ? X&Y : X|Y -> X|Y
+define i32 @src_select_xor0_and_or(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_xor0_and_or(
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[OR:%.*]]
+ %xor = xor i32 %x, %y
+ %xor0 = icmp eq i32 %xor, 0
+ %or = or i32 %x, %y
+ %and = and i32 %x, %y
+ %cond = select i1 %xor0, i32 %and, i32 %or
+ ret i32 %cond
+}
+; X^Y==0 ? X|Y : X&Y -> X|Y
+define i32 @src_select_xor0_or_and(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_xor0_or_and(
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[AND:%.*]]
+ %xor = xor i32 %x, %y
+ %xor0 = icmp eq i32 %xor, 0
+ %or = or i32 %x, %y
+ %and = and i32 %x, %y
+ %cond = select i1 %xor0, i32 %or, i32 %and
+ ret i32 %cond
+}
+; X^Y!=0 ? X&Y : X|Y -> X&Y
+define i32 @src_select_xor1_and_or(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_xor1_and_or(
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[AND:%.*]]
+ %xor = xor i32 %x, %y
+ %xor1 = icmp ne i32 %xor, 0
+ %or = or i32 %x, %y
+ %and = and i32 %x, %y
+ %cond = select i1 %xor1, i32 %and, i32 %or
+ ret i32 %cond
+}
+; X^Y!=0 ? X|Y : X&Y -> X|Y
+define i32 @src_select_xor1_or_and(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_xor1_or_and(
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i32 [[OR:%.*]]
+ %xor = xor i32 %x, %y
+ %xor1 = icmp ne i32 %xor, 0
+ %or = or i32 %x, %y
+ %and = and i32 %x, %y
+ %cond = select i1 %xor1, i32 %or, i32 %and
+ ret i32 %cond
+}
----------------
ParkHanbum wrote:
sure, I was worried about many tests would be not welcome.
I will add tests to enough that nothing worry about it. :smile:
https://github.com/llvm/llvm-project/pull/73362
More information about the llvm-commits
mailing list