From e88432414517c8f2e6efa9f02828053e6e25bc6a Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Mon, 3 Oct 2022 12:54:38 -0700 Subject: [PATCH] [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 --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 11 ++++---- llvm/test/CodeGen/RISCV/select-binop-identity.ll | 36 +++++++++--------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 3b36521..78eca13 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 3449a33..b22988a 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 -- 2.7.4