diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 3711e5226bfe..e23844d8ec7c 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -6206,6 +6206,13 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, // Transform SDValue LHS = N->getOperand(0); SDValue RHS = N->getOperand(1); + SDValue TrueV = N->getOperand(3); + SDValue FalseV = N->getOperand(4); + + // If the True and False values are the same, we don't need a select_cc. + if (TrueV == FalseV) + return TrueV; + ISD::CondCode CCVal = cast(N->getOperand(2))->get(); if (!ISD::isIntEqualitySetCC(CCVal)) break; @@ -6228,9 +6235,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, translateSetCCForBranch(DL, LHS, RHS, CCVal, DAG); SDValue TargetCC = DAG.getCondCode(CCVal); - return DAG.getNode( - RISCVISD::SELECT_CC, DL, N->getValueType(0), - {LHS, RHS, TargetCC, N->getOperand(3), N->getOperand(4)}); + return DAG.getNode(RISCVISD::SELECT_CC, DL, N->getValueType(0), + {LHS, RHS, TargetCC, TrueV, FalseV}); } // Fold (select_cc (xor X, Y), 0, eq/ne, trueV, falseV) -> @@ -6238,8 +6244,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, if (LHS.getOpcode() == ISD::XOR && isNullConstant(RHS)) return DAG.getNode(RISCVISD::SELECT_CC, SDLoc(N), N->getValueType(0), {LHS.getOperand(0), LHS.getOperand(1), - N->getOperand(2), N->getOperand(3), - N->getOperand(4)}); + N->getOperand(2), TrueV, FalseV}); // (select_cc X, 1, setne, trueV, falseV) -> // (select_cc X, 0, seteq, trueV, falseV) if we can prove X is 0/1. // This can occur when legalizing some floating point comparisons. @@ -6249,9 +6254,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, CCVal = ISD::getSetCCInverse(CCVal, LHS.getValueType()); SDValue TargetCC = DAG.getCondCode(CCVal); RHS = DAG.getConstant(0, DL, LHS.getValueType()); - return DAG.getNode( - RISCVISD::SELECT_CC, DL, N->getValueType(0), - {LHS, RHS, TargetCC, N->getOperand(3), N->getOperand(4)}); + return DAG.getNode(RISCVISD::SELECT_CC, DL, N->getValueType(0), + {LHS, RHS, TargetCC, TrueV, FalseV}); } break; diff --git a/llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll b/llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll index 9384b4a3e523..8ff72b3ead29 100644 --- a/llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll +++ b/llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll @@ -81,4 +81,29 @@ entry: ret i64 %1 } +; vscale will always be a positive number, but we don't know that until after op +; legalization. The and will be considered a NOP and replaced with its input, +; but not until after the select becomes RISCVISD::SELECT_CC. Make sure we +; simplify this and don't leave behind any code for calculating the select +; condition. +define i64 @vscale_select(i32 %x, i32 %y) { +; RV64-LABEL: vscale_select: +; RV64: # %bb.0: +; RV64-NEXT: csrr a0, vlenb +; RV64-NEXT: srli a0, a0, 3 +; RV64-NEXT: ret +; +; RV32-LABEL: vscale_select: +; RV32: # %bb.0: +; RV32-NEXT: csrr a0, vlenb +; RV32-NEXT: srli a0, a0, 3 +; RV32-NEXT: mv a1, zero +; RV32-NEXT: ret + %a = call i64 @llvm.vscale.i64() + %b = and i64 %a, 4294967295 + %c = icmp eq i32 %x, %y + %d = select i1 %c, i64 %a, i64 %b + ret i64 %d +} + declare i64 @llvm.vscale.i64()