[PATCH] D135081: [RISCV] Generalize select (and (x , 0x1) == 0), y, (z ^ y) ) and select (and (x , 0x1) == 0), y, (z | y) ) transforms by removing and-clause

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 3 09:01:03 PDT 2022


reames created this revision.
reames added reviewers: craig.topper, asb, frasercrmck.
Herald added subscribers: sunshaoce, VincentWu, StephenFan, vkmr, evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, bollu, simoncook, johnrusso, rbar, hiraditya, arichardson, mcrosier.
Herald added a project: All.
reames requested review of this revision.
Herald added subscribers: pcwang-thead, eopXD, MaskRay.
Herald added a project: LLVM.

These transforms were recently added (by me) in D134881 <https://reviews.llvm.org/D134881>.  Looking at the code again, I realized we don't need the (and x, 0x1) portion of the pattern, we just need to know that the result of that sub-tree is either 0 or 1.  Checking for this directly allows us to match slightly more broadly.  The test changes are zext i1 arguments, but this could also kick in for e.g. shifts of high bits, or any other source of known bits.

As an aside, the tests reveal some odd inconsistencies in canonicalization existing in tree.  I am not planning to pursue those, just noting that it's quite odd that xor_select_all_zeros_i64 gets recognized, but xor_select_all_zeros_i32 (on RV32 even) doesn't.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D135081

Files:
  llvm/lib/Target/RISCV/RISCVISelLowering.cpp
  llvm/test/CodeGen/RISCV/select-binop-identity.ll


Index: llvm/test/CodeGen/RISCV/select-binop-identity.ll
===================================================================
--- llvm/test/CodeGen/RISCV/select-binop-identity.ll
+++ llvm/test/CodeGen/RISCV/select-binop-identity.ll
@@ -61,20 +61,16 @@
 define signext i32 @or_select_all_zeros_i32(i1 zeroext %c, i32 signext %x, i32 signext %y) {
 ; RV32I-LABEL: or_select_all_zeros_i32:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    beqz a0, .LBB2_2
-; RV32I-NEXT:  # %bb.1:
-; RV32I-NEXT:    or a2, a2, a1
-; RV32I-NEXT:  .LBB2_2:
-; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    neg a0, a0
+; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    or a0, a0, a2
 ; RV32I-NEXT:    ret
 ;
 ; RV64I-LABEL: or_select_all_zeros_i32:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    beqz a0, .LBB2_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    or a2, a2, a1
-; RV64I-NEXT:  .LBB2_2:
-; RV64I-NEXT:    mv a0, a2
+; RV64I-NEXT:    neg a0, a0
+; RV64I-NEXT:    and a0, a0, a1
+; RV64I-NEXT:    or a0, a0, a2
 ; RV64I-NEXT:    ret
   %a = select i1 %c, i32 %x, i32 0
   %b = or i32 %y, %a
@@ -132,22 +128,18 @@
 define i64 @xor_select_all_zeros_i64(i1 zeroext %c, i64 %x, i64 %y) {
 ; RV32I-LABEL: xor_select_all_zeros_i64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    beqz a0, .LBB5_2
-; RV32I-NEXT:  # %bb.1:
-; RV32I-NEXT:    xor a3, a3, a1
-; RV32I-NEXT:    xor a4, a4, a2
-; RV32I-NEXT:  .LBB5_2:
-; RV32I-NEXT:    mv a0, a3
-; RV32I-NEXT:    mv a1, a4
+; RV32I-NEXT:    neg a5, a0
+; RV32I-NEXT:    and a0, a5, a1
+; RV32I-NEXT:    xor a0, a0, a3
+; RV32I-NEXT:    and a1, a5, a2
+; RV32I-NEXT:    xor a1, a1, a4
 ; RV32I-NEXT:    ret
 ;
 ; RV64I-LABEL: xor_select_all_zeros_i64:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    beqz a0, .LBB5_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    xor a2, a2, a1
-; RV64I-NEXT:  .LBB5_2:
-; RV64I-NEXT:    mv a0, a2
+; RV64I-NEXT:    neg a0, a0
+; RV64I-NEXT:    and a0, a0, a1
+; RV64I-NEXT:    xor a0, a0, a2
 ; RV64I-NEXT:    ret
   %a = select i1 %c, i64 %x, i64 0
   %b = xor i64 %a, %y
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -9021,12 +9021,13 @@
     if (TrueV == FalseV)
       return TrueV;
 
-    // (select (and (x , 0x1) == 0), y, (z ^ y) ) -> (-(and (x , 0x1)) & z ) ^ y
-    // (select (and (x , 0x1) != 0), (z ^ y) ), y -> (-(and (x , 0x1)) & z ) ^ y
-    // (select (and (x , 0x1) == 0), y, (z | y) ) -> (-(and (x , 0x1)) & z ) | y
-    // (select (and (x , 0x1) != 0), (z | y) ), y -> (-(and (x , 0x1)) & z ) | y
+    // (select (x in [0,1] == 0), y, (z ^ y) ) -> (-x & z ) ^ y
+    // (select (x in [0,1] != 0), (z ^ y) ), y -> (-x & z ) ^ y
+    // (select (x in [0,1] == 0), y, (z | y) ) -> (-x & z ) | y
+    // (select (x in [0,1] != 0), (z | y) ), y -> (-x & z ) | y
+    APInt Mask = APInt::getBitsSetFrom(LHS.getValueSizeInBits(), 1);
     if (isNullConstant(RHS) && ISD::isIntEqualitySetCC(CCVal) &&
-        LHS.getOpcode() == ISD::AND && isOneConstant(LHS.getOperand(1))) {
+        DAG.MaskedValueIsZero(LHS, Mask)) {
       unsigned Opcode;
       SDValue Src1, Src2;
       // true if FalseV is XOR or OR operator and one of its operands


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D135081.464704.patch
Type: text/x-patch
Size: 3256 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221003/dfbaf1db/attachment.bin>


More information about the llvm-commits mailing list