Skip to content

Commit 1309dbf

Browse files
committed
[DAGCombiner] Fold freeze(fmul) + fadd/fsub into FMA combine
1 parent 1e81e80 commit 1309dbf

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16729,6 +16729,28 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
1672916729
}
1673016730
}
1673116731

16732+
// fold (fadd (freeze (fmul x, y)), z) -> (fma x, y, z).
16733+
if ((Options.UnsafeFPMath || N->getFlags().hasAllowContract()) &&
16734+
N0.getOpcode() == ISD::FREEZE) {
16735+
SDValue FrozenMul = N0.getOperand(0);
16736+
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
16737+
SDValue X = FrozenMul.getOperand(0);
16738+
SDValue Y = FrozenMul.getOperand(1);
16739+
return matcher.getNode(PreferredFusedOpcode, SL, VT, X, Y, N1);
16740+
}
16741+
}
16742+
16743+
// fold (fadd x, (freeze (fmul y, z))) -> (fma y, z, x)
16744+
if ((Options.UnsafeFPMath || N->getFlags().hasAllowContract()) &&
16745+
N1.getOpcode() == ISD::FREEZE) {
16746+
SDValue FrozenMul = N1.getOperand(0);
16747+
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
16748+
SDValue X = FrozenMul.getOperand(0);
16749+
SDValue Y = FrozenMul.getOperand(1);
16750+
return matcher.getNode(PreferredFusedOpcode, SL, VT, X, Y, N0);
16751+
}
16752+
}
16753+
1673216754
// More folding opportunities when target permits.
1673316755
if (Aggressive) {
1673416756
// fold (fadd (fma x, y, (fpext (fmul u, v))), z)
@@ -17006,6 +17028,30 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
1700617028
}
1700717029
}
1700817030

17031+
// fold (fsub (freeze (fmul x, y)), z) -> (fma x, y, (fneg z))
17032+
if ((Options.UnsafeFPMath || N->getFlags().hasAllowContract()) &&
17033+
N0.getOpcode() == ISD::FREEZE) {
17034+
SDValue FrozenMul = N0.getOperand(0);
17035+
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
17036+
SDValue X = FrozenMul.getOperand(0);
17037+
SDValue Y = FrozenMul.getOperand(1);
17038+
SDValue NegZ = matcher.getNode(ISD::FNEG, SL, VT, N1);
17039+
return matcher.getNode(PreferredFusedOpcode, SL, VT, X, Y, NegZ);
17040+
}
17041+
}
17042+
17043+
// fold (fsub z, (freeze(fmul x, y))) -> (fma (fneg x), y, z)
17044+
if ((Options.UnsafeFPMath || N->getFlags().hasAllowContract()) &&
17045+
N1.getOpcode() == ISD::FREEZE) {
17046+
SDValue FrozenMul = N1.getOperand(0);
17047+
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
17048+
SDValue X = FrozenMul.getOperand(0);
17049+
SDValue Y = FrozenMul.getOperand(1);
17050+
SDValue NegX = matcher.getNode(ISD::FNEG, SL, VT, X);
17051+
return matcher.getNode(PreferredFusedOpcode, SL, VT, NegX, Y, N0);
17052+
}
17053+
}
17054+
1700917055
auto isReassociable = [&Options](SDNode *N) {
1701017056
return Options.UnsafeFPMath || N->getFlags().hasAllowReassociation();
1701117057
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs < %s | FileCheck %s -check-prefix GFX11
3+
4+
define float @fma_from_freeze_mul_add_left(float %x, float %y) {
5+
; GFX11-LABEL: fma_from_freeze_mul_add_left:
6+
; GFX11: ; %bb.0: ; %bb
7+
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
8+
; GFX11-NEXT: v_fma_f32 v0, v0, v1, 1.0
9+
; GFX11-NEXT: s_setpc_b64 s[30:31]
10+
bb:
11+
%mul = fmul contract float %x, %y
12+
%mul.fr = freeze float %mul
13+
%add = fadd contract float %mul.fr, 1.000000e+00
14+
ret float %add
15+
}
16+
17+
define float @fma_from_freeze_mul_add_right(float %x, float %y) {
18+
; GFX11-LABEL: fma_from_freeze_mul_add_right:
19+
; GFX11: ; %bb.0: ; %bb
20+
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
21+
; GFX11-NEXT: v_fma_f32 v0, v0, v1, 1.0
22+
; GFX11-NEXT: s_setpc_b64 s[30:31]
23+
bb:
24+
%mul = fmul contract float %x, %y
25+
%mul.fr = freeze float %mul
26+
%add = fadd contract float 1.000000e+00, %mul.fr
27+
ret float %add
28+
}
29+
30+
define float @fma_from_freeze_mul_sub_left(float %x, float %y) {
31+
; GFX11-LABEL: fma_from_freeze_mul_sub_left:
32+
; GFX11: ; %bb.0: ; %bb
33+
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
34+
; GFX11-NEXT: v_fma_f32 v0, v0, v1, -1.0
35+
; GFX11-NEXT: s_setpc_b64 s[30:31]
36+
bb:
37+
%mul = fmul contract float %x, %y
38+
%mul.fr = freeze float %mul
39+
%sub = fsub contract float %mul.fr, 1.000000e+00
40+
ret float %sub
41+
}
42+
43+
define float @fma_from_freeze_mul_sub_right(float %x, float %y) {
44+
; GFX11-LABEL: fma_from_freeze_mul_sub_right:
45+
; GFX11: ; %bb.0: ; %bb
46+
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
47+
; GFX11-NEXT: v_fma_f32 v0, -v0, v1, 1.0
48+
; GFX11-NEXT: s_setpc_b64 s[30:31]
49+
bb:
50+
%mul = fmul contract float %x, %y
51+
%mul.fr = freeze float %mul
52+
%sub = fsub contract float 1.000000e+00, %mul.fr
53+
ret float %sub
54+
}

0 commit comments

Comments
 (0)