diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -9022,12 +9022,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 diff --git a/llvm/test/CodeGen/RISCV/select-binop-identity.ll b/llvm/test/CodeGen/RISCV/select-binop-identity.ll --- a/llvm/test/CodeGen/RISCV/select-binop-identity.ll +++ b/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