Skip to content

Commit c1340b9

Browse files
committed
[DAG] Improve FMINNUM/FMAXNUM/FMINIMUM/FMAXIMUM constant folding
Merge the node combines into a common DAGCombiner::visitFMinMax (like we do for IMINMAX). Move the constant folding into SelectionDAG::foldConstantFPMath. This allows us to fold the vecreduce-propagate-sd-flags.ll test as it reduces constants - so I've refactored it to take variables instead. Differential Revision: https://reviews.llvm.org/D115952
1 parent 56b2b1b commit c1340b9

File tree

3 files changed

+28
-42
lines changed

3 files changed

+28
-42
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -487,10 +487,7 @@ namespace {
487487
SDValue visitFCEIL(SDNode *N);
488488
SDValue visitFTRUNC(SDNode *N);
489489
SDValue visitFFLOOR(SDNode *N);
490-
SDValue visitFMINNUM(SDNode *N);
491-
SDValue visitFMAXNUM(SDNode *N);
492-
SDValue visitFMINIMUM(SDNode *N);
493-
SDValue visitFMAXIMUM(SDNode *N);
490+
SDValue visitFMinMax(SDNode *N);
494491
SDValue visitBRCOND(SDNode *N);
495492
SDValue visitBR_CC(SDNode *N);
496493
SDValue visitLOAD(SDNode *N);
@@ -1701,10 +1698,10 @@ SDValue DAGCombiner::visit(SDNode *N) {
17011698
case ISD::FNEG: return visitFNEG(N);
17021699
case ISD::FABS: return visitFABS(N);
17031700
case ISD::FFLOOR: return visitFFLOOR(N);
1704-
case ISD::FMINNUM: return visitFMINNUM(N);
1705-
case ISD::FMAXNUM: return visitFMAXNUM(N);
1706-
case ISD::FMINIMUM: return visitFMINIMUM(N);
1707-
case ISD::FMAXIMUM: return visitFMAXIMUM(N);
1701+
case ISD::FMINNUM:
1702+
case ISD::FMAXNUM:
1703+
case ISD::FMINIMUM:
1704+
case ISD::FMAXIMUM: return visitFMinMax(N);
17081705
case ISD::FCEIL: return visitFCEIL(N);
17091706
case ISD::FTRUNC: return visitFTRUNC(N);
17101707
case ISD::BRCOND: return visitBRCOND(N);
@@ -15244,31 +15241,26 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) {
1524415241
return SDValue();
1524515242
}
1524615243

15247-
static SDValue visitFMinMax(SelectionDAG &DAG, SDNode *N,
15248-
APFloat (*Op)(const APFloat &, const APFloat &)) {
15244+
SDValue DAGCombiner::visitFMinMax(SDNode *N) {
1524915245
SDValue N0 = N->getOperand(0);
1525015246
SDValue N1 = N->getOperand(1);
1525115247
EVT VT = N->getValueType(0);
15252-
const ConstantFPSDNode *N0CFP = isConstOrConstSplatFP(N0);
15253-
const ConstantFPSDNode *N1CFP = isConstOrConstSplatFP(N1);
1525415248
const SDNodeFlags Flags = N->getFlags();
1525515249
unsigned Opc = N->getOpcode();
1525615250
bool PropagatesNaN = Opc == ISD::FMINIMUM || Opc == ISD::FMAXIMUM;
1525715251
bool IsMin = Opc == ISD::FMINNUM || Opc == ISD::FMINIMUM;
1525815252
SelectionDAG::FlagInserter FlagsInserter(DAG, N);
1525915253

15260-
if (N0CFP && N1CFP) {
15261-
const APFloat &C0 = N0CFP->getValueAPF();
15262-
const APFloat &C1 = N1CFP->getValueAPF();
15263-
return DAG.getConstantFP(Op(C0, C1), SDLoc(N), VT);
15264-
}
15254+
// Constant fold.
15255+
if (SDValue C = DAG.FoldConstantArithmetic(Opc, SDLoc(N), VT, {N0, N1}))
15256+
return C;
1526515257

1526615258
// Canonicalize to constant on RHS.
1526715259
if (DAG.isConstantFPBuildVectorOrConstantFP(N0) &&
1526815260
!DAG.isConstantFPBuildVectorOrConstantFP(N1))
1526915261
return DAG.getNode(N->getOpcode(), SDLoc(N), VT, N1, N0);
1527015262

15271-
if (N1CFP) {
15263+
if (const ConstantFPSDNode *N1CFP = isConstOrConstSplatFP(N1)) {
1527215264
const APFloat &AF = N1CFP->getValueAPF();
1527315265

1527415266
// minnum(X, nan) -> X
@@ -15300,22 +15292,6 @@ static SDValue visitFMinMax(SelectionDAG &DAG, SDNode *N,
1530015292
return SDValue();
1530115293
}
1530215294

15303-
SDValue DAGCombiner::visitFMINNUM(SDNode *N) {
15304-
return visitFMinMax(DAG, N, minnum);
15305-
}
15306-
15307-
SDValue DAGCombiner::visitFMAXNUM(SDNode *N) {
15308-
return visitFMinMax(DAG, N, maxnum);
15309-
}
15310-
15311-
SDValue DAGCombiner::visitFMINIMUM(SDNode *N) {
15312-
return visitFMinMax(DAG, N, minimum);
15313-
}
15314-
15315-
SDValue DAGCombiner::visitFMAXIMUM(SDNode *N) {
15316-
return visitFMinMax(DAG, N, maximum);
15317-
}
15318-
1531915295
SDValue DAGCombiner::visitFABS(SDNode *N) {
1532015296
SDValue N0 = N->getOperand(0);
1532115297
EVT VT = N->getValueType(0);

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5505,6 +5505,14 @@ SDValue SelectionDAG::foldConstantFPMath(unsigned Opcode, const SDLoc &DL,
55055505
case ISD::FCOPYSIGN:
55065506
C1.copySign(C2);
55075507
return getConstantFP(C1, DL, VT);
5508+
case ISD::FMINNUM:
5509+
return getConstantFP(minnum(C1, C2), DL, VT);
5510+
case ISD::FMAXNUM:
5511+
return getConstantFP(maxnum(C1, C2), DL, VT);
5512+
case ISD::FMINIMUM:
5513+
return getConstantFP(minimum(C1, C2), DL, VT);
5514+
case ISD::FMAXIMUM:
5515+
return getConstantFP(maximum(C1, C2), DL, VT);
55085516
default: break;
55095517
}
55105518
}

llvm/test/CodeGen/AArch64/vecreduce-propagate-sd-flags.ll

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,23 @@
99
; CHECK-NEXT: Analyzing result type: v4f64
1010
; CHECK-NEXT: Split node result: [[VFOUR]]: v4f64 = BUILD_VECTOR
1111

12-
; CHECK: Legalizing node: [[VTWO:t.*]]: v2f64 = BUILD_VECTOR
13-
; CHECK: Legally typed node: [[VTWO]]: v2f64 = BUILD_VECTOR
14-
; CHECK: Legalizing node: t26: v2f64 = fmaxnum nnan reassoc [[VTWO]], [[VTWO]]
12+
; CHECK: Legalizing node: [[VTWOA:t.*]]: v2f64 = BUILD_VECTOR
13+
; CHECK: Legally typed node: [[VTWOA]]: v2f64 = BUILD_VECTOR
14+
; CHECK: Legalizing node: [[VTWOB:t.*]]: v2f64 = BUILD_VECTOR
15+
; CHECK: Legally typed node: [[VTWOB]]: v2f64 = BUILD_VECTOR
16+
; CHECK: Legalizing node: t34: v2f64 = fmaxnum nnan reassoc [[VTWOB]], [[VTWOA]]
1517

1618
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
1719
target triple = "aarch64--linux-gnu"
1820

1921

2022
; Function Attrs: norecurse nounwind
21-
define fastcc double @test() unnamed_addr #1 {
23+
define fastcc double @test(double %a0, double %a1, double %a2, double %a3) unnamed_addr #1 {
2224
entry:
23-
%0 = insertelement <4 x double> undef, double 1.0, i32 0
24-
%1 = insertelement <4 x double> %0, double 1.0, i32 1
25-
%2 = insertelement <4 x double> %1, double 1.0, i32 2
26-
%3 = insertelement <4 x double> %2, double 1.0, i32 3
25+
%0 = insertelement <4 x double> undef, double %a0, i32 0
26+
%1 = insertelement <4 x double> %0, double %a1, i32 1
27+
%2 = insertelement <4 x double> %1, double %a2, i32 2
28+
%3 = insertelement <4 x double> %2, double %a3, i32 3
2729
%4 = call nnan reassoc double @llvm.vector.reduce.fmax.v4f64(<4 x double> %3)
2830
ret double %4
2931
}

0 commit comments

Comments
 (0)