diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3697,6 +3697,18 @@ } } } + // For SMAX, if CstLow is non-negative we know the result will be + // non-negative and thus all sign bits are 0. + // TODO: There's an equivalent of this for smin with negative constant for + // known ones. + if (IsMax && CstLow) { + const APInt &ValueLow = CstLow->getAPIntValue(); + if (ValueLow.isNonNegative()) { + unsigned SignBits = ComputeNumSignBits(Op.getOperand(0), Depth + 1); + Known.Zero.setHighBits(std::min(SignBits, ValueLow.getNumSignBits())); + break; + } + } Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1); Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1); diff --git a/llvm/test/CodeGen/RISCV/min-max.ll b/llvm/test/CodeGen/RISCV/min-max.ll --- a/llvm/test/CodeGen/RISCV/min-max.ll +++ b/llvm/test/CodeGen/RISCV/min-max.ll @@ -621,39 +621,20 @@ } define signext i32 @smax_i32_pos_constant(i32 signext %a) { -; RV32I-LABEL: smax_i32_pos_constant: -; RV32I: # %bb.0: -; RV32I-NEXT: li a1, 10 -; RV32I-NEXT: blt a1, a0, .LBB24_2 -; RV32I-NEXT: # %bb.1: -; RV32I-NEXT: li a0, 10 -; RV32I-NEXT: .LBB24_2: -; RV32I-NEXT: ret -; -; RV64I-LABEL: smax_i32_pos_constant: -; RV64I: # %bb.0: -; RV64I-NEXT: li a1, 10 -; RV64I-NEXT: blt a1, a0, .LBB24_2 -; RV64I-NEXT: # %bb.1: -; RV64I-NEXT: li a0, 10 -; RV64I-NEXT: .LBB24_2: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: ret -; -; RV32ZBB-LABEL: smax_i32_pos_constant: -; RV32ZBB: # %bb.0: -; RV32ZBB-NEXT: li a1, 10 -; RV32ZBB-NEXT: max a0, a0, a1 -; RV32ZBB-NEXT: ret +; NOZBB-LABEL: smax_i32_pos_constant: +; NOZBB: # %bb.0: +; NOZBB-NEXT: li a1, 10 +; NOZBB-NEXT: blt a1, a0, .LBB24_2 +; NOZBB-NEXT: # %bb.1: +; NOZBB-NEXT: li a0, 10 +; NOZBB-NEXT: .LBB24_2: +; NOZBB-NEXT: ret ; -; RV64ZBB-LABEL: smax_i32_pos_constant: -; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: li a1, 10 -; RV64ZBB-NEXT: max a0, a0, a1 -; RV64ZBB-NEXT: slli a0, a0, 32 -; RV64ZBB-NEXT: srli a0, a0, 32 -; RV64ZBB-NEXT: ret +; ZBB-LABEL: smax_i32_pos_constant: +; ZBB: # %bb.0: +; ZBB-NEXT: li a1, 10 +; ZBB-NEXT: max a0, a0, a1 +; ZBB-NEXT: ret %c = call i32 @llvm.smax.i32(i32 %a, i32 10) ret i32 %c }