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 @@ -4022,10 +4022,20 @@ translateSetCCForBranch(DL, LHS, RHS, CCVal, DAG); // x > 1 ? x : 1 -> x > 0 ? x : 1 - if (isOneConstant(LHS) && !isa(RHS) && - (CCVal == ISD::SETLT || CCVal == ISD::SETULT) && RHS == TrueV && - isOneConstant(FalseV)) { + if (isOneConstant(LHS) && (CCVal == ISD::SETLT || CCVal == ISD::SETULT) && + RHS == TrueV && LHS == FalseV) { LHS = DAG.getConstant(0, DL, VT); + // 0 x < 0 ? x : -1 + if (isAllOnesConstant(RHS) && CCVal == ISD::SETLT && LHS == TrueV && + RHS == FalseV) { + RHS = DAG.getConstant(0, DL, VT); } SDValue TargetCC = DAG.getCondCode(CCVal); diff --git a/llvm/test/CodeGen/RISCV/forced-atomics.ll b/llvm/test/CodeGen/RISCV/forced-atomics.ll --- a/llvm/test/CodeGen/RISCV/forced-atomics.ll +++ b/llvm/test/CodeGen/RISCV/forced-atomics.ll @@ -1183,7 +1183,7 @@ ; RV32-NO-ATOMIC-NEXT: .LBB25_2: # %atomicrmw.start ; RV32-NO-ATOMIC-NEXT: # =>This Inner Loop Header: Depth=1 ; RV32-NO-ATOMIC-NEXT: mv a2, a1 -; RV32-NO-ATOMIC-NEXT: bltu zero, a1, .LBB25_1 +; RV32-NO-ATOMIC-NEXT: bnez a1, .LBB25_1 ; RV32-NO-ATOMIC-NEXT: # %bb.3: # %atomicrmw.start ; RV32-NO-ATOMIC-NEXT: # in Loop: Header=BB25_2 Depth=1 ; RV32-NO-ATOMIC-NEXT: li a2, 1 @@ -2754,7 +2754,7 @@ ; RV64-NO-ATOMIC-NEXT: .LBB51_2: # %atomicrmw.start ; RV64-NO-ATOMIC-NEXT: # =>This Inner Loop Header: Depth=1 ; RV64-NO-ATOMIC-NEXT: mv a2, a1 -; RV64-NO-ATOMIC-NEXT: bltu zero, a1, .LBB51_1 +; RV64-NO-ATOMIC-NEXT: bnez a1, .LBB51_1 ; RV64-NO-ATOMIC-NEXT: # %bb.3: # %atomicrmw.start ; RV64-NO-ATOMIC-NEXT: # in Loop: Header=BB51_2 Depth=1 ; RV64-NO-ATOMIC-NEXT: li a2, 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 @@ -661,3 +661,78 @@ %d = and i32 %c, -4 ret i32 %d } + +define signext i32 @smin_i32_negone(i32 signext %a) { +; NOZBB-LABEL: smin_i32_negone: +; NOZBB: # %bb.0: +; NOZBB-NEXT: bltz a0, .LBB26_2 +; NOZBB-NEXT: # %bb.1: +; NOZBB-NEXT: li a0, -1 +; NOZBB-NEXT: .LBB26_2: +; NOZBB-NEXT: ret +; +; ZBB-LABEL: smin_i32_negone: +; ZBB: # %bb.0: +; ZBB-NEXT: li a1, -1 +; ZBB-NEXT: min a0, a0, a1 +; ZBB-NEXT: ret + %c = call i32 @llvm.smin.i32(i32 %a, i32 -1) + ret i32 %c +} + +define i64 @smin_i64_negone(i64 %a) { +; RV32I-LABEL: smin_i64_negone: +; RV32I: # %bb.0: +; RV32I-NEXT: li a2, -1 +; RV32I-NEXT: mv a3, a0 +; RV32I-NEXT: bge a1, a2, .LBB27_4 +; RV32I-NEXT: # %bb.1: +; RV32I-NEXT: bne a1, a2, .LBB27_5 +; RV32I-NEXT: .LBB27_2: +; RV32I-NEXT: bgez a1, .LBB27_6 +; RV32I-NEXT: .LBB27_3: +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB27_4: +; RV32I-NEXT: li a3, -1 +; RV32I-NEXT: beq a1, a2, .LBB27_2 +; RV32I-NEXT: .LBB27_5: +; RV32I-NEXT: mv a0, a3 +; RV32I-NEXT: bltz a1, .LBB27_3 +; RV32I-NEXT: .LBB27_6: +; RV32I-NEXT: li a1, -1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: smin_i64_negone: +; RV64I: # %bb.0: +; RV64I-NEXT: bltz a0, .LBB27_2 +; RV64I-NEXT: # %bb.1: +; RV64I-NEXT: li a0, -1 +; RV64I-NEXT: .LBB27_2: +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: smin_i64_negone: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: li a2, -1 +; RV32ZBB-NEXT: mv a3, a0 +; RV32ZBB-NEXT: bge a1, a2, .LBB27_3 +; RV32ZBB-NEXT: # %bb.1: +; RV32ZBB-NEXT: bne a1, a2, .LBB27_4 +; RV32ZBB-NEXT: .LBB27_2: +; RV32ZBB-NEXT: min a1, a1, a2 +; RV32ZBB-NEXT: ret +; RV32ZBB-NEXT: .LBB27_3: +; RV32ZBB-NEXT: li a3, -1 +; RV32ZBB-NEXT: beq a1, a2, .LBB27_2 +; RV32ZBB-NEXT: .LBB27_4: +; RV32ZBB-NEXT: mv a0, a3 +; RV32ZBB-NEXT: min a1, a1, a2 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: smin_i64_negone: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: li a1, -1 +; RV64ZBB-NEXT: min a0, a0, a1 +; RV64ZBB-NEXT: ret + %c = call i64 @llvm.smin.i64(i64 %a, i64 -1) + ret i64 %c +}