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

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 10 00:41:42 PST 2024


================
@@ -1752,3 +1752,555 @@ define <4 x i32> @select_vector_cmp_with_bitcasts(<2 x i64> %x, <4 x i32> %y) {
   %sel = select <4 x i1> %cmp, <4 x i32> %sub.bc, <4 x i32> zeroinitializer
   ret <4 x i32> %sel
 }
+
+; Select icmp and/or/xor
+; https://alive2.llvm.org/ce/z/g7wzzm
+; X&Y==0 ? X|Y : X^Y  -> X^Y
+define i32 @src_select_and_eq0_or_xor(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_and_eq0_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_and_eq0_xor_or(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_and_eq0_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_or_eq0_and_xor(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_or_eq0_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_or_eq0_xor_and(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_or_eq0_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_xor_eq0_and_or(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_xor_eq0_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_xor_eq0_or_and(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_xor_eq0_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
+}
+
+; Extend Xor
+; (X ^ Y) == 0 could be transformed to X == Y
+; (X ^ Y) != 0 could be transformed to X != Y
+; https://alive2.llvm.org/ce/z/KJTA_5
+; X==Y ? X|Y : X&Y  -> X&Y
+define i32 @src_select_x_eq_y_or_and(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_x_eq_y_or_and(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i32 [[AND]]
+;
+  %eq = icmp eq i32 %x, %y
+  %or = or i32 %x, %y
+  %and = and i32 %x, %y
+  %cond = select i1 %eq, i32 %or, i32 %and
+  ret i32 %cond
+}
+
+; X==Y ? X|Y : X&Y  -> X|Y
+define i32 @src_select_x_eq_y_and_or(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_x_eq_y_and_or(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i32 [[OR]]
+;
+  %eq = icmp eq i32 %x, %y
+  %or = or i32 %x, %y
+  %and = and i32 %x, %y
+  %cond = select i1 %eq, i32 %and, i32 %or
+  ret i32 %cond
+}
+
+; X!=Y ? X|Y : X&Y  -> X&Y
----------------
dtcxzyw wrote:

```suggestion
; X!=Y ? X|Y : X&Y  -> X|Y
```

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


More information about the llvm-commits mailing list