[llvm] e884324 - [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 llvm-commits llvm-commits at lists.llvm.org
Mon Oct 3 13:57:50 PDT 2022


Author: Philip Reames
Date: 2022-10-03T13:57:38-07:00
New Revision: e88432414517c8f2e6efa9f02828053e6e25bc6a

URL: https://github.com/llvm/llvm-project/commit/e88432414517c8f2e6efa9f02828053e6e25bc6a
DIFF: https://github.com/llvm/llvm-project/commit/e88432414517c8f2e6efa9f02828053e6e25bc6a.diff

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

These transforms were recently added (by me) in 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.

Differential Revision: https://reviews.llvm.org/D135081

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 3b36521463d0..78eca13e13ee 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -9022,12 +9022,13 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
     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

diff  --git a/llvm/test/CodeGen/RISCV/select-binop-identity.ll b/llvm/test/CodeGen/RISCV/select-binop-identity.ll
index 3449a33edf0f..b22988a7ec86 100644
--- a/llvm/test/CodeGen/RISCV/select-binop-identity.ll
+++ b/llvm/test/CodeGen/RISCV/select-binop-identity.ll
@@ -61,20 +61,16 @@ define i64 @and_select_all_ones_i64(i1 zeroext %c, i64 %x, i64 %y) {
 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 signext i32 @xor_select_all_zeros_i32(i1 zeroext %c, i32 signext %x, i32
 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


        


More information about the llvm-commits mailing list