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 @@ -5921,6 +5921,8 @@ assert(VT.isInteger() && "This operator does not apply to FP types!"); assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!"); + if (N1 == N2) + return N1; if (VT.isVector() && VT.getVectorElementType() == MVT::i1) return getNode(ISD::OR, DL, VT, N1, N2); break; @@ -5929,6 +5931,8 @@ assert(VT.isInteger() && "This operator does not apply to FP types!"); assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!"); + if (N1 == N2) + return N1; if (VT.isVector() && VT.getVectorElementType() == MVT::i1) return getNode(ISD::AND, DL, VT, N1, N2); break; 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 @@ -480,8 +480,7 @@ ret i64 %c } -; Tests with the same operand used twice. -; FIXME: These should fold away. +; Tests with the same operand used twice. These should fold away. define signext i32 @smin_same_op_i32(i32 signext %a) { ; NOZBB-LABEL: smin_same_op_i32: @@ -490,7 +489,6 @@ ; ; ZBB-LABEL: smin_same_op_i32: ; ZBB: # %bb.0: -; ZBB-NEXT: min a0, a0, a0 ; ZBB-NEXT: ret %c = call i32 @llvm.smin.i32(i32 %a, i32 %a) ret i32 %c @@ -503,7 +501,6 @@ ; ; ZBB-LABEL: smax_same_op_i32: ; ZBB: # %bb.0: -; ZBB-NEXT: max a0, a0, a0 ; ZBB-NEXT: ret %c = call i32 @llvm.smax.i32(i32 %a, i32 %a) ret i32 %c @@ -516,7 +513,6 @@ ; ; ZBB-LABEL: umin_same_op_i32: ; ZBB: # %bb.0: -; ZBB-NEXT: minu a0, a0, a0 ; ZBB-NEXT: ret %c = call i32 @llvm.umin.i32(i32 %a, i32 %a) ret i32 %c @@ -529,15 +525,12 @@ ; ; ZBB-LABEL: umax_same_op_i32: ; ZBB: # %bb.0: -; ZBB-NEXT: maxu a0, a0, a0 ; ZBB-NEXT: ret %c = call i32 @llvm.umax.i32(i32 %a, i32 %a) ret i32 %c } -; Tests with undef operands. -; FIXME: These should fold to undef for RV32 or 0 for RV64. -; FIXME: The RV64ZBB cases are hitting pr55178. +; Tests with undef operands. These should fold to undef for RV32 or 0 for RV64. define signext i32 @smin_undef_i32() { ; RV32I-LABEL: smin_undef_i32: @@ -551,13 +544,11 @@ ; ; RV32ZBB-LABEL: smin_undef_i32: ; RV32ZBB: # %bb.0: -; RV32ZBB-NEXT: min a0, a0, a0 ; RV32ZBB-NEXT: ret ; ; RV64ZBB-LABEL: smin_undef_i32: ; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: min a0, a0, a0 -; RV64ZBB-NEXT: sext.w a0, a0 +; RV64ZBB-NEXT: li a0, 0 ; RV64ZBB-NEXT: ret %c = call i32 @llvm.smin.i32(i32 undef, i32 undef) ret i32 %c @@ -575,13 +566,11 @@ ; ; RV32ZBB-LABEL: smax_undef_i32: ; RV32ZBB: # %bb.0: -; RV32ZBB-NEXT: max a0, a0, a0 ; RV32ZBB-NEXT: ret ; ; RV64ZBB-LABEL: smax_undef_i32: ; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: max a0, a0, a0 -; RV64ZBB-NEXT: sext.w a0, a0 +; RV64ZBB-NEXT: li a0, 0 ; RV64ZBB-NEXT: ret %c = call i32 @llvm.smax.i32(i32 undef, i32 undef) ret i32 %c @@ -599,13 +588,11 @@ ; ; RV32ZBB-LABEL: umin_undef_i32: ; RV32ZBB: # %bb.0: -; RV32ZBB-NEXT: minu a0, a0, a0 ; RV32ZBB-NEXT: ret ; ; RV64ZBB-LABEL: umin_undef_i32: ; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: minu a0, a0, a0 -; RV64ZBB-NEXT: sext.w a0, a0 +; RV64ZBB-NEXT: li a0, 0 ; RV64ZBB-NEXT: ret %c = call i32 @llvm.umin.i32(i32 undef, i32 undef) ret i32 %c @@ -623,13 +610,11 @@ ; ; RV32ZBB-LABEL: umax_undef_i32: ; RV32ZBB: # %bb.0: -; RV32ZBB-NEXT: maxu a0, a0, a0 ; RV32ZBB-NEXT: ret ; ; RV64ZBB-LABEL: umax_undef_i32: ; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: maxu a0, a0, a0 -; RV64ZBB-NEXT: sext.w a0, a0 +; RV64ZBB-NEXT: li a0, 0 ; RV64ZBB-NEXT: ret %c = call i32 @llvm.umax.i32(i32 undef, i32 undef) ret i32 %c diff --git a/llvm/test/CodeGen/RISCV/pr55271.ll b/llvm/test/CodeGen/RISCV/pr55271.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/pr55271.ll @@ -0,0 +1,17 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=riscv32 -mattr=+m | FileCheck %s + +; This previously miscompiled to undef. It should produce +; value between 0 and 2. + +declare i32 @llvm.umax.i32(i32, i32) + +define i32 @umax(i32 %in) { +; CHECK-LABEL: umax: +; CHECK: # %bb.0: +; CHECK-NEXT: li a0, 0 +; CHECK-NEXT: ret + %x = call i32 @llvm.umax.i32(i32 undef, i32 undef) + %y = urem i32 %x, 3 + ret i32 %y +}