[DAGCombiner] Propagate FMF flags in FMA folding

DAG combiner folds (fma a 1.0 b) into (fadd a b) but the flag isn't
propagated into new fadd. This patch fixes that.

Some code in visitFMA is redundant and such support for vector constants
is missing. Need follow-up patch to clean.

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D87037
This commit is contained in:
Qiu Chaofan 2020-09-14 00:19:06 +08:00
parent 9237fde481
commit a4c5351986
2 changed files with 61 additions and 11 deletions

View File

@ -13185,11 +13185,11 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
if (N1CFP && N1CFP->isZero())
return N2;
}
// TODO: The FMA node should have flags that propagate to these nodes.
if (N0CFP && N0CFP->isExactlyValue(1.0))
return DAG.getNode(ISD::FADD, SDLoc(N), VT, N1, N2);
return DAG.getNode(ISD::FADD, SDLoc(N), VT, N1, N2, Flags);
if (N1CFP && N1CFP->isExactlyValue(1.0))
return DAG.getNode(ISD::FADD, SDLoc(N), VT, N0, N2);
return DAG.getNode(ISD::FADD, SDLoc(N), VT, N0, N2, Flags);
// Canonicalize (fma c, x, y) -> (fma x, c, y)
if (isConstantFPBuildVectorOrConstantFP(N0) &&
@ -13218,19 +13218,16 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
}
}
// (fma x, 1, y) -> (fadd x, y)
// (fma x, -1, y) -> (fadd (fneg x), y)
if (N1CFP) {
if (N1CFP->isExactlyValue(1.0))
// TODO: The FMA node should have flags that propagate to this node.
return DAG.getNode(ISD::FADD, DL, VT, N0, N2);
return DAG.getNode(ISD::FADD, DL, VT, N0, N2, Flags);
if (N1CFP->isExactlyValue(-1.0) &&
(!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))) {
SDValue RHSNeg = DAG.getNode(ISD::FNEG, DL, VT, N0);
AddToWorklist(RHSNeg.getNode());
// TODO: The FMA node should have flags that propagate to this node.
return DAG.getNode(ISD::FADD, DL, VT, N2, RHSNeg);
return DAG.getNode(ISD::FADD, DL, VT, N2, RHSNeg, Flags);
}
// fma (fneg x), K, y -> fma x -K, y

View File

@ -243,17 +243,18 @@ define double @getNegatedExpression_crash(double %x, double %y) {
define double @fma_flag_propagation(double %a) {
; CHECK-FAST-LABEL: fma_flag_propagation:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: xssubdp 1, 1, 1
; CHECK-FAST-NEXT: xxlxor 1, 1, 1
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: fma_flag_propagation:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: fsub 1, 1, 1
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI6_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI6_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: fma_flag_propagation:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xssubdp 1, 1, 1
; CHECK-NEXT: xxlxor 1, 1, 1
; CHECK-NEXT: blr
entry:
%0 = fneg double %a
@ -261,4 +262,56 @@ entry:
ret double %1
}
define double @neg_fma_flag_propagation(double %a) {
; CHECK-FAST-LABEL: neg_fma_flag_propagation:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: xxlxor 1, 1, 1
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: neg_fma_flag_propagation:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI7_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI7_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: neg_fma_flag_propagation:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor 1, 1, 1
; CHECK-NEXT: blr
entry:
%0 = call reassoc nnan double @llvm.fma.f64(double %a, double -1.0, double %a)
ret double %0
}
define <2 x double> @vec_neg_fma_flag_propagation(<2 x double> %a) {
; CHECK-FAST-LABEL: vec_neg_fma_flag_propagation:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: addis 3, 2, .LCPI8_0@toc@ha
; CHECK-FAST-NEXT: addi 3, 3, .LCPI8_0@toc@l
; CHECK-FAST-NEXT: lxvd2x 0, 0, 3
; CHECK-FAST-NEXT: xxswapd 0, 0
; CHECK-FAST-NEXT: xvmaddadp 34, 34, 0
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: vec_neg_fma_flag_propagation:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI8_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI8_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: fmr 2, 1
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: vec_neg_fma_flag_propagation:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addis 3, 2, .LCPI8_0@toc@ha
; CHECK-NEXT: addi 3, 3, .LCPI8_0@toc@l
; CHECK-NEXT: lxvd2x 0, 0, 3
; CHECK-NEXT: xxswapd 0, 0
; CHECK-NEXT: xvmaddadp 34, 34, 0
; CHECK-NEXT: blr
entry:
%0 = call reassoc nnan <2 x double> @llvm.fma.v2f64(<2 x double> %a, <2 x double> <double -1.0, double -1.0>, <2 x double> %a)
ret <2 x double> %0
}
declare double @llvm.fma.f64(double, double, double) nounwind readnone
declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone