Skip to content

Commit dd0ab15

Browse files
committed
[DAGCombiner] Allow freeze to sink through fmul by adding it to AllowMultipleMaybePoisonOperands
1 parent 591717e commit dd0ab15

File tree

1 file changed

+13
-52
lines changed

1 file changed

+13
-52
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 13 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16392,12 +16392,11 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
1639216392
return SDValue();
1639316393

1639416394
bool AllowMultipleMaybePoisonOperands =
16395-
N0.getOpcode() == ISD::SELECT_CC ||
16396-
N0.getOpcode() == ISD::SETCC ||
16395+
N0.getOpcode() == ISD::SELECT_CC || N0.getOpcode() == ISD::SETCC ||
1639716396
N0.getOpcode() == ISD::BUILD_VECTOR ||
1639816397
N0.getOpcode() == ISD::BUILD_PAIR ||
1639916398
N0.getOpcode() == ISD::VECTOR_SHUFFLE ||
16400-
N0.getOpcode() == ISD::CONCAT_VECTORS;
16399+
N0.getOpcode() == ISD::CONCAT_VECTORS || N0.getOpcode() == ISD::FMUL;
1640116400

1640216401
// Avoid turning a BUILD_VECTOR that can be recognized as "all zeros", "all
1640316402
// ones" or "constant" into something that depends on FrozenUndef. We can
@@ -16495,7 +16494,17 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
1649516494
SVN->getMask());
1649616495
} else {
1649716496
// NOTE: this strips poison generating flags.
16498-
R = DAG.getNode(N0.getOpcode(), SDLoc(N0), N0->getVTList(), Ops);
16497+
// Folding freeze(op(x, ...)) -> op(freeze(x), ...) does not require nnan,
16498+
// ninf, nsz, or fast.
16499+
// However, contract, reassoc, afn, and arcp should be preserved,
16500+
// as these fast-math flags do not introduce poison values.
16501+
SDNodeFlags SrcFlags = N0->getFlags();
16502+
SDNodeFlags SafeFlags;
16503+
SafeFlags.setAllowContract(SrcFlags.hasAllowContract());
16504+
SafeFlags.setAllowReassociation(SrcFlags.hasAllowReassociation());
16505+
SafeFlags.setApproximateFuncs(SrcFlags.hasApproximateFuncs());
16506+
SafeFlags.setAllowReciprocal(SrcFlags.hasAllowReciprocal());
16507+
R = DAG.getNode(N0.getOpcode(), SDLoc(N0), N0->getVTList(), Ops, SafeFlags);
1649916508
}
1650016509
assert(DAG.isGuaranteedNotToBeUndefOrPoison(R, /*PoisonOnly*/ false) &&
1650116510
"Can't create node that may be undef/poison!");
@@ -16736,29 +16745,6 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
1673616745
}
1673716746
}
1673816747

16739-
// fold (fadd (freeze (fmul x, y)), z) -> (fma x, y, z).
16740-
bool CanContract =
16741-
(Options.UnsafeFPMath || N->getFlags().hasAllowContract()) &&
16742-
(Options.NoSignedZerosFPMath || N->getFlags().hasNoSignedZeros());
16743-
if (CanContract && N0.getOpcode() == ISD::FREEZE) {
16744-
SDValue FrozenMul = N0.getOperand(0);
16745-
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
16746-
SDValue X = FrozenMul.getOperand(0);
16747-
SDValue Y = FrozenMul.getOperand(1);
16748-
return matcher.getNode(PreferredFusedOpcode, SL, VT, X, Y, N1);
16749-
}
16750-
}
16751-
16752-
// fold (fadd x, (freeze (fmul y, z))) -> (fma y, z, x)
16753-
if (CanContract && N1.getOpcode() == ISD::FREEZE) {
16754-
SDValue FrozenMul = N1.getOperand(0);
16755-
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
16756-
SDValue X = FrozenMul.getOperand(0);
16757-
SDValue Y = FrozenMul.getOperand(1);
16758-
return matcher.getNode(PreferredFusedOpcode, SL, VT, X, Y, N0);
16759-
}
16760-
}
16761-
1676216748
// More folding opportunities when target permits.
1676316749
if (Aggressive) {
1676416750
// fold (fadd (fma x, y, (fpext (fmul u, v))), z)
@@ -17036,31 +17022,6 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
1703617022
}
1703717023
}
1703817024

17039-
// fold (fsub (freeze (fmul x, y)), z) -> (fma x, y, (fneg z))
17040-
bool CanContract =
17041-
(Options.UnsafeFPMath || N->getFlags().hasAllowContract()) &&
17042-
(Options.NoSignedZerosFPMath || N->getFlags().hasNoSignedZeros());
17043-
if (CanContract && N0.getOpcode() == ISD::FREEZE) {
17044-
SDValue FrozenMul = N0.getOperand(0);
17045-
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
17046-
SDValue X = FrozenMul.getOperand(0);
17047-
SDValue Y = FrozenMul.getOperand(1);
17048-
SDValue NegZ = matcher.getNode(ISD::FNEG, SL, VT, N1);
17049-
return matcher.getNode(PreferredFusedOpcode, SL, VT, X, Y, NegZ);
17050-
}
17051-
}
17052-
17053-
// fold (fsub z, (freeze(fmul x, y))) -> (fma (fneg x), y, z)
17054-
if (CanContract && N1.getOpcode() == ISD::FREEZE) {
17055-
SDValue FrozenMul = N1.getOperand(0);
17056-
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
17057-
SDValue X = FrozenMul.getOperand(0);
17058-
SDValue Y = FrozenMul.getOperand(1);
17059-
SDValue NegX = matcher.getNode(ISD::FNEG, SL, VT, X);
17060-
return matcher.getNode(PreferredFusedOpcode, SL, VT, NegX, Y, N0);
17061-
}
17062-
}
17063-
1706417025
auto isReassociable = [&Options](SDNode *N) {
1706517026
return Options.UnsafeFPMath || N->getFlags().hasAllowReassociation();
1706617027
};

0 commit comments

Comments
 (0)