Skip to content

Commit 2e74dd2

Browse files
committed
[DAGCombiner] Fold freeze(fmul) + fadd/fsub into FMA combine
1 parent 2e70da3 commit 2e74dd2

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
@@ -16736,6 +16736,28 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
1673616736
}
1673716737
}
1673816738

16739+
// fold (fadd (freeze (fmul x, y)), z) -> (fma x, y, z).
16740+
if ((Options.UnsafeFPMath || N->getFlags().hasAllowContract()) &&
16741+
N0.getOpcode() == ISD::FREEZE) {
16742+
SDValue FrozenMul = N0.getOperand(0);
16743+
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
16744+
SDValue X = FrozenMul.getOperand(0);
16745+
SDValue Y = FrozenMul.getOperand(1);
16746+
return matcher.getNode(PreferredFusedOpcode, SL, VT, X, Y, N1);
16747+
}
16748+
}
16749+
16750+
// fold (fadd x, (freeze (fmul y, z))) -> (fma y, z, x)
16751+
if ((Options.UnsafeFPMath || N->getFlags().hasAllowContract()) &&
16752+
N1.getOpcode() == ISD::FREEZE) {
16753+
SDValue FrozenMul = N1.getOperand(0);
16754+
if (matcher.match(FrozenMul, ISD::FMUL) && isContractableFMUL(FrozenMul)) {
16755+
SDValue X = FrozenMul.getOperand(0);
16756+
SDValue Y = FrozenMul.getOperand(1);
16757+
return matcher.getNode(PreferredFusedOpcode, SL, VT, X, Y, N0);
16758+
}
16759+
}
16760+
1673916761
// More folding opportunities when target permits.
1674016762
if (Aggressive) {
1674116763
// fold (fadd (fma x, y, (fpext (fmul u, v))), z)
@@ -17013,6 +17035,30 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
1701317035
}
1701417036
}
1701517037

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