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 @@ -10632,11 +10632,33 @@ if (N->getValueType(0) != Subtarget.getXLenVT()) return SDValue(); - SDValue TrueVal = N->getOperand(1); - SDValue FalseVal = N->getOperand(2); - if (SDValue V = tryFoldSelectIntoOp(N, DAG, TrueVal, FalseVal, /*Swapped*/false)) + SDValue TrueV = N->getOperand(1); + SDValue FalseV = N->getOperand(2); + if (SDValue V = tryFoldSelectIntoOp(N, DAG, TrueV, FalseV, /*Swapped*/ false)) return V; - return tryFoldSelectIntoOp(N, DAG, FalseVal, TrueVal, /*Swapped*/true); + if (SDValue V = tryFoldSelectIntoOp(N, DAG, FalseV, TrueV, /*Swapped*/ true)) + return V; + + SDValue CondV = N->getOperand(0); + if ((!Subtarget.hasVendorXVentanaCondOps() && + !Subtarget.hasVendorXTHeadCondMov()) && + CondV->hasOneUse() && CondV->getOpcode() == ISD::SETCC) { + SDValue CondL = CondV->getOperand(0); + SDValue CondR = CondV->getOperand(1); + ISD::CondCode CC = cast(CondV.getOperand(2))->get(); + if (CondL->getOpcode() == ISD::AND && isNullConstant(CondR) && + isIntEqualitySetCC(CC)) { + uint64_t Mask = CondL.getConstantOperandVal(1); + if (isPowerOf2_64(Mask) && !isInt<12>(Mask)) { + SDLoc DL(N); + SDValue Ops[] = {CondL, CondR, N->getOperand(1) /*TrueV*/, + N->getOperand(2) /*FalseV*/, CondV->getOperand(2)}; + return DAG.getNode(ISD::SELECT_CC, DL, N->getValueType(0), Ops); + } + } + } + + return SDValue(); } SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, diff --git a/llvm/test/CodeGen/RISCV/bittest.ll b/llvm/test/CodeGen/RISCV/bittest.ll --- a/llvm/test/CodeGen/RISCV/bittest.ll +++ b/llvm/test/CodeGen/RISCV/bittest.ll @@ -724,12 +724,11 @@ define signext i32 @bit_31_nz_select_i32(i32 signext %a, i32 signext %b, i32 signext %c) { ; RV32-LABEL: bit_31_nz_select_i32: ; RV32: # %bb.0: -; RV32-NEXT: srli a3, a0, 31 -; RV32-NEXT: mv a0, a1 -; RV32-NEXT: bnez a3, .LBB22_2 +; RV32-NEXT: bltz a0, .LBB22_2 ; RV32-NEXT: # %bb.1: -; RV32-NEXT: mv a0, a2 +; RV32-NEXT: mv a1, a2 ; RV32-NEXT: .LBB22_2: +; RV32-NEXT: mv a0, a1 ; RV32-NEXT: ret ; ; RV64-LABEL: bit_31_nz_select_i32: @@ -1224,12 +1223,11 @@ ; ; RV64-LABEL: bit_63_nz_select_i64: ; RV64: # %bb.0: -; RV64-NEXT: srli a3, a0, 63 -; RV64-NEXT: mv a0, a1 -; RV64-NEXT: bnez a3, .LBB36_2 +; RV64-NEXT: bltz a0, .LBB36_2 ; RV64-NEXT: # %bb.1: -; RV64-NEXT: mv a0, a2 +; RV64-NEXT: mv a1, a2 ; RV64-NEXT: .LBB36_2: +; RV64-NEXT: mv a0, a1 ; RV64-NEXT: ret %1 = and i64 %a, 9223372036854775808 %2 = icmp ne i64 %1, 0