forked from OSchip/llvm-project
[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:
parent
9237fde481
commit
a4c5351986
|
@ -13185,11 +13185,11 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
|
||||||
if (N1CFP && N1CFP->isZero())
|
if (N1CFP && N1CFP->isZero())
|
||||||
return N2;
|
return N2;
|
||||||
}
|
}
|
||||||
// TODO: The FMA node should have flags that propagate to these nodes.
|
|
||||||
if (N0CFP && N0CFP->isExactlyValue(1.0))
|
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))
|
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)
|
// Canonicalize (fma c, x, y) -> (fma x, c, y)
|
||||||
if (isConstantFPBuildVectorOrConstantFP(N0) &&
|
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)
|
// (fma x, -1, y) -> (fadd (fneg x), y)
|
||||||
if (N1CFP) {
|
if (N1CFP) {
|
||||||
if (N1CFP->isExactlyValue(1.0))
|
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, Flags);
|
||||||
return DAG.getNode(ISD::FADD, DL, VT, N0, N2);
|
|
||||||
|
|
||||||
if (N1CFP->isExactlyValue(-1.0) &&
|
if (N1CFP->isExactlyValue(-1.0) &&
|
||||||
(!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))) {
|
(!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))) {
|
||||||
SDValue RHSNeg = DAG.getNode(ISD::FNEG, DL, VT, N0);
|
SDValue RHSNeg = DAG.getNode(ISD::FNEG, DL, VT, N0);
|
||||||
AddToWorklist(RHSNeg.getNode());
|
AddToWorklist(RHSNeg.getNode());
|
||||||
// TODO: The FMA node should have flags that propagate to this node.
|
return DAG.getNode(ISD::FADD, DL, VT, N2, RHSNeg, Flags);
|
||||||
return DAG.getNode(ISD::FADD, DL, VT, N2, RHSNeg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fma (fneg x), K, y -> fma x -K, y
|
// fma (fneg x), K, y -> fma x -K, y
|
||||||
|
|
|
@ -243,17 +243,18 @@ define double @getNegatedExpression_crash(double %x, double %y) {
|
||||||
define double @fma_flag_propagation(double %a) {
|
define double @fma_flag_propagation(double %a) {
|
||||||
; CHECK-FAST-LABEL: fma_flag_propagation:
|
; CHECK-FAST-LABEL: fma_flag_propagation:
|
||||||
; CHECK-FAST: # %bb.0: # %entry
|
; 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-NEXT: blr
|
||||||
;
|
;
|
||||||
; CHECK-FAST-NOVSX-LABEL: fma_flag_propagation:
|
; CHECK-FAST-NOVSX-LABEL: fma_flag_propagation:
|
||||||
; CHECK-FAST-NOVSX: # %bb.0: # %entry
|
; 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-FAST-NOVSX-NEXT: blr
|
||||||
;
|
;
|
||||||
; CHECK-LABEL: fma_flag_propagation:
|
; CHECK-LABEL: fma_flag_propagation:
|
||||||
; CHECK: # %bb.0: # %entry
|
; CHECK: # %bb.0: # %entry
|
||||||
; CHECK-NEXT: xssubdp 1, 1, 1
|
; CHECK-NEXT: xxlxor 1, 1, 1
|
||||||
; CHECK-NEXT: blr
|
; CHECK-NEXT: blr
|
||||||
entry:
|
entry:
|
||||||
%0 = fneg double %a
|
%0 = fneg double %a
|
||||||
|
@ -261,4 +262,56 @@ entry:
|
||||||
ret double %1
|
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 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
|
||||||
|
|
Loading…
Reference in New Issue