[llvm] [InstSimplify] Simplify select if it combinated `and/or/xor` (PR #73362)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 28 04:34:31 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:

I added tests! :smile: 

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


More information about the llvm-commits mailing list