Skip to content

Commit d23e4f6

Browse files
committed
[RISCV] Add support for fmin/fmax vector reductions
Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D101518
1 parent cdeb4a8 commit d23e4f6

6 files changed

+1261
-14
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
550550

551551
setOperationAction(ISD::VECREDUCE_FADD, VT, Custom);
552552
setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Custom);
553+
setOperationAction(ISD::VECREDUCE_FMIN, VT, Custom);
554+
setOperationAction(ISD::VECREDUCE_FMAX, VT, Custom);
553555
setOperationAction(ISD::FCOPYSIGN, VT, Legal);
554556

555557
setOperationAction(ISD::MLOAD, VT, Custom);
@@ -746,6 +748,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
746748

747749
setOperationAction(ISD::VECREDUCE_FADD, VT, Custom);
748750
setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Custom);
751+
setOperationAction(ISD::VECREDUCE_FMIN, VT, Custom);
752+
setOperationAction(ISD::VECREDUCE_FMAX, VT, Custom);
749753
}
750754

751755
// Custom-legalize bitcasts from fixed-length vectors to scalar types.
@@ -2226,6 +2230,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
22262230
return lowerVECREDUCE(Op, DAG);
22272231
case ISD::VECREDUCE_FADD:
22282232
case ISD::VECREDUCE_SEQ_FADD:
2233+
case ISD::VECREDUCE_FMIN:
2234+
case ISD::VECREDUCE_FMAX:
22292235
return lowerFPVECREDUCE(Op, DAG);
22302236
case ISD::INSERT_SUBVECTOR:
22312237
return lowerINSERT_SUBVECTOR(Op, DAG);
@@ -3476,7 +3482,10 @@ SDValue RISCVTargetLowering::lowerVECREDUCE(SDValue Op,
34763482
static std::tuple<unsigned, SDValue, SDValue>
34773483
getRVVFPReductionOpAndOperands(SDValue Op, SelectionDAG &DAG, EVT EltVT) {
34783484
SDLoc DL(Op);
3479-
switch (Op.getOpcode()) {
3485+
auto Flags = Op->getFlags();
3486+
unsigned Opcode = Op.getOpcode();
3487+
unsigned BaseOpcode = ISD::getVecReduceBaseOpcode(Opcode);
3488+
switch (Opcode) {
34803489
default:
34813490
llvm_unreachable("Unhandled reduction");
34823491
case ISD::VECREDUCE_FADD:
@@ -3485,6 +3494,12 @@ getRVVFPReductionOpAndOperands(SDValue Op, SelectionDAG &DAG, EVT EltVT) {
34853494
case ISD::VECREDUCE_SEQ_FADD:
34863495
return std::make_tuple(RISCVISD::VECREDUCE_SEQ_FADD_VL, Op.getOperand(1),
34873496
Op.getOperand(0));
3497+
case ISD::VECREDUCE_FMIN:
3498+
return std::make_tuple(RISCVISD::VECREDUCE_FMIN_VL, Op.getOperand(0),
3499+
DAG.getNeutralElement(BaseOpcode, DL, EltVT, Flags));
3500+
case ISD::VECREDUCE_FMAX:
3501+
return std::make_tuple(RISCVISD::VECREDUCE_FMAX_VL, Op.getOperand(0),
3502+
DAG.getNeutralElement(BaseOpcode, DL, EltVT, Flags));
34883503
}
34893504
}
34903505

@@ -7762,6 +7777,8 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
77627777
NODE_NAME_CASE(VECREDUCE_XOR_VL)
77637778
NODE_NAME_CASE(VECREDUCE_FADD_VL)
77647779
NODE_NAME_CASE(VECREDUCE_SEQ_FADD_VL)
7780+
NODE_NAME_CASE(VECREDUCE_FMIN_VL)
7781+
NODE_NAME_CASE(VECREDUCE_FMAX_VL)
77657782
NODE_NAME_CASE(ADD_VL)
77667783
NODE_NAME_CASE(AND_VL)
77677784
NODE_NAME_CASE(MUL_VL)

llvm/lib/Target/RISCV/RISCVISelLowering.h

+2
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ enum NodeType : unsigned {
172172
VECREDUCE_XOR_VL,
173173
VECREDUCE_FADD_VL,
174174
VECREDUCE_SEQ_FADD_VL,
175+
VECREDUCE_FMIN_VL,
176+
VECREDUCE_FMAX_VL,
175177

176178
// Vector binary and unary ops with a mask as a third operand, and VL as a
177179
// fourth operand.

llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td

+3-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ def SDTRVVVecReduce : SDTypeProfile<1, 4, [
226226
]>;
227227

228228
foreach kind = ["ADD", "UMAX", "SMAX", "UMIN", "SMIN", "AND", "OR", "XOR",
229-
"FADD", "SEQ_FADD"] in
229+
"FADD", "SEQ_FADD", "FMIN", "FMAX"] in
230230
def rvv_vecreduce_#kind#_vl : SDNode<"RISCVISD::VECREDUCE_"#kind#"_VL", SDTRVVVecReduce>;
231231

232232
// Ignore the vl operand.
@@ -736,6 +736,8 @@ defm : VPatReductionVL<rvv_vecreduce_XOR_vl, "PseudoVREDXOR", /*is_float*/0>;
736736
let Predicates = [HasStdExtV, HasStdExtF] in {
737737
defm : VPatReductionVL<rvv_vecreduce_SEQ_FADD_vl, "PseudoVFREDOSUM", /*is_float*/1>;
738738
defm : VPatReductionVL<rvv_vecreduce_FADD_vl, "PseudoVFREDSUM", /*is_float*/1>;
739+
defm : VPatReductionVL<rvv_vecreduce_FMIN_vl, "PseudoVFREDMIN", /*is_float*/1>;
740+
defm : VPatReductionVL<rvv_vecreduce_FMAX_vl, "PseudoVFREDMAX", /*is_float*/1>;
739741
} // Predicates = [HasStdExtV, HasStdExtF]
740742

741743
let Predicates = [HasStdExtV, HasStdExtF] in {

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp

-12
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,6 @@ bool RISCVTTIImpl::shouldExpandReduction(const IntrinsicInst *II) const {
112112
// These reductions have no equivalent in RVV
113113
case Intrinsic::vector_reduce_mul:
114114
case Intrinsic::vector_reduce_fmul:
115-
// The fmin and fmax intrinsics are not currently supported due to a
116-
// discrepancy between the LLVM semantics and the RVV 0.10 ISA behaviour with
117-
// regards to signaling NaNs: the vector fmin/fmax reduction intrinsics match
118-
// the behaviour minnum/maxnum intrinsics, whereas the vfredmin/vfredmax
119-
// instructions match the vfmin/vfmax instructions which match the equivalent
120-
// scalar fmin/fmax instructions as defined in 2.2 F/D/Q extension (see
121-
// https://bugs.llvm.org/show_bug.cgi?id=27363).
122-
// This behaviour is likely fixed in version 2.3 of the RISC-V F/D/Q
123-
// extension, where fmin/fmax behave like minnum/maxnum, but until then the
124-
// intrinsics are left unsupported.
125-
case Intrinsic::vector_reduce_fmax:
126-
case Intrinsic::vector_reduce_fmin:
127115
return true;
128116
}
129117
}

0 commit comments

Comments
 (0)