Skip to content

Commit 3de0e81

Browse files
committed
[llvm] Ensure that soft float targets don't emit fma() libcalls.
The previous behavior could be harmful in some edge cases, such as emitting a call to fma() in the fma() implementation itself. Do this by just being more accurate in isFMAFasterThanFMulAndFAdd(). This was already done for PowerPC; this commit just extends that to Arm, z/Arch, and x86. MIPS and SPARC already got it right, but I added tests for them too, for good measure.
1 parent 2579b41 commit 3de0e81

File tree

8 files changed

+658
-0
lines changed

8 files changed

+658
-0
lines changed

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19488,6 +19488,9 @@ bool ARMTargetLowering::allowTruncateForTailCall(Type *Ty1, Type *Ty2) const {
1948819488
/// patterns (and we don't have the non-fused floating point instruction).
1948919489
bool ARMTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
1949019490
EVT VT) const {
19491+
if (Subtarget->useSoftFloat())
19492+
return false;
19493+
1949119494
if (!VT.isSimple())
1949219495
return false;
1949319496

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,9 @@ EVT SystemZTargetLowering::getSetCCResultType(const DataLayout &DL,
786786

787787
bool SystemZTargetLowering::isFMAFasterThanFMulAndFAdd(
788788
const MachineFunction &MF, EVT VT) const {
789+
if (useSoftFloat())
790+
return false;
791+
789792
VT = VT.getScalarType();
790793

791794
if (!VT.isSimple())

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34423,6 +34423,9 @@ bool X86TargetLowering::isVectorLoadExtDesirable(SDValue ExtVal) const {
3442334423

3442434424
bool X86TargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
3442534425
EVT VT) const {
34426+
if (Subtarget.useSoftFloat())
34427+
return false;
34428+
3442634429
if (!Subtarget.hasAnyFMA())
3442734430
return false;
3442834431

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=arm < %s | FileCheck %s -check-prefix=SOFT-FLOAT
3+
; RUN: llc -mtriple=arm -mattr=+vfp4d16sp < %s | FileCheck %s -check-prefix=SOFT-FLOAT-VFP32
4+
; RUN: llc -mtriple=arm -mattr=+vfp4d16sp,+fp64 < %s | FileCheck %s -check-prefix=SOFT-FLOAT-VFP64
5+
6+
define float @fma_f32(float %a, float %b, float %c) "use-soft-float"="true" {
7+
; SOFT-FLOAT-LABEL: fma_f32:
8+
; SOFT-FLOAT: @ %bb.0:
9+
; SOFT-FLOAT-NEXT: push {r4, lr}
10+
; SOFT-FLOAT-NEXT: mov r4, r2
11+
; SOFT-FLOAT-NEXT: bl __mulsf3
12+
; SOFT-FLOAT-NEXT: mov r1, r4
13+
; SOFT-FLOAT-NEXT: bl __addsf3
14+
; SOFT-FLOAT-NEXT: pop {r4, lr}
15+
; SOFT-FLOAT-NEXT: mov pc, lr
16+
;
17+
; SOFT-FLOAT-VFP32-LABEL: fma_f32:
18+
; SOFT-FLOAT-VFP32: @ %bb.0:
19+
; SOFT-FLOAT-VFP32-NEXT: push {r4, lr}
20+
; SOFT-FLOAT-VFP32-NEXT: mov r4, r2
21+
; SOFT-FLOAT-VFP32-NEXT: bl __mulsf3
22+
; SOFT-FLOAT-VFP32-NEXT: mov r1, r4
23+
; SOFT-FLOAT-VFP32-NEXT: bl __addsf3
24+
; SOFT-FLOAT-VFP32-NEXT: pop {r4, lr}
25+
; SOFT-FLOAT-VFP32-NEXT: mov pc, lr
26+
;
27+
; SOFT-FLOAT-VFP64-LABEL: fma_f32:
28+
; SOFT-FLOAT-VFP64: @ %bb.0:
29+
; SOFT-FLOAT-VFP64-NEXT: push {r4, lr}
30+
; SOFT-FLOAT-VFP64-NEXT: mov r4, r2
31+
; SOFT-FLOAT-VFP64-NEXT: bl __mulsf3
32+
; SOFT-FLOAT-VFP64-NEXT: mov r1, r4
33+
; SOFT-FLOAT-VFP64-NEXT: bl __addsf3
34+
; SOFT-FLOAT-VFP64-NEXT: pop {r4, lr}
35+
; SOFT-FLOAT-VFP64-NEXT: mov pc, lr
36+
%1 = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
37+
ret float %1
38+
}
39+
40+
define double @fma_f64(double %a, double %b, double %c) "use-soft-float"="true" {
41+
; SOFT-FLOAT-LABEL: fma_f64:
42+
; SOFT-FLOAT: @ %bb.0:
43+
; SOFT-FLOAT-NEXT: push {r11, lr}
44+
; SOFT-FLOAT-NEXT: bl __muldf3
45+
; SOFT-FLOAT-NEXT: ldr r2, [sp, #8]
46+
; SOFT-FLOAT-NEXT: ldr r3, [sp, #12]
47+
; SOFT-FLOAT-NEXT: bl __adddf3
48+
; SOFT-FLOAT-NEXT: pop {r11, lr}
49+
; SOFT-FLOAT-NEXT: mov pc, lr
50+
;
51+
; SOFT-FLOAT-VFP32-LABEL: fma_f64:
52+
; SOFT-FLOAT-VFP32: @ %bb.0:
53+
; SOFT-FLOAT-VFP32-NEXT: push {r11, lr}
54+
; SOFT-FLOAT-VFP32-NEXT: bl __muldf3
55+
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #8]
56+
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #12]
57+
; SOFT-FLOAT-VFP32-NEXT: bl __adddf3
58+
; SOFT-FLOAT-VFP32-NEXT: pop {r11, lr}
59+
; SOFT-FLOAT-VFP32-NEXT: mov pc, lr
60+
;
61+
; SOFT-FLOAT-VFP64-LABEL: fma_f64:
62+
; SOFT-FLOAT-VFP64: @ %bb.0:
63+
; SOFT-FLOAT-VFP64-NEXT: push {r11, lr}
64+
; SOFT-FLOAT-VFP64-NEXT: bl __muldf3
65+
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #8]
66+
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #12]
67+
; SOFT-FLOAT-VFP64-NEXT: bl __adddf3
68+
; SOFT-FLOAT-VFP64-NEXT: pop {r11, lr}
69+
; SOFT-FLOAT-VFP64-NEXT: mov pc, lr
70+
%1 = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
71+
ret double %1
72+
}
73+
74+
declare float @llvm.fmuladd.f32(float %a, float %b, float %c)
75+
declare double @llvm.fmuladd.f64(double %a, double %b, double %c)
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=mips < %s | FileCheck %s -check-prefix=SOFT-FLOAT-32
3+
; RUN: llc -mtriple=mips -mcpu mips32r2 < %s | FileCheck %s -check-prefix=SOFT-FLOAT-32R2
4+
; RUN: llc -mtriple=mips64 < %s | FileCheck %s -check-prefix=SOFT-FLOAT-64
5+
; RUN: llc -mtriple=mips64 -mcpu mips64r2 < %s | FileCheck %s -check-prefix=SOFT-FLOAT-64R2
6+
7+
define float @fma_f32(float %a, float %b, float %c) "use-soft-float"="true" {
8+
; SOFT-FLOAT-32-LABEL: fma_f32:
9+
; SOFT-FLOAT-32: # %bb.0:
10+
; SOFT-FLOAT-32-NEXT: addiu $sp, $sp, -24
11+
; SOFT-FLOAT-32-NEXT: .cfi_def_cfa_offset 24
12+
; SOFT-FLOAT-32-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
13+
; SOFT-FLOAT-32-NEXT: sw $16, 16($sp) # 4-byte Folded Spill
14+
; SOFT-FLOAT-32-NEXT: .cfi_offset 31, -4
15+
; SOFT-FLOAT-32-NEXT: .cfi_offset 16, -8
16+
; SOFT-FLOAT-32-NEXT: jal __mulsf3
17+
; SOFT-FLOAT-32-NEXT: move $16, $6
18+
; SOFT-FLOAT-32-NEXT: move $4, $2
19+
; SOFT-FLOAT-32-NEXT: jal __addsf3
20+
; SOFT-FLOAT-32-NEXT: move $5, $16
21+
; SOFT-FLOAT-32-NEXT: lw $16, 16($sp) # 4-byte Folded Reload
22+
; SOFT-FLOAT-32-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
23+
; SOFT-FLOAT-32-NEXT: jr $ra
24+
; SOFT-FLOAT-32-NEXT: addiu $sp, $sp, 24
25+
;
26+
; SOFT-FLOAT-32R2-LABEL: fma_f32:
27+
; SOFT-FLOAT-32R2: # %bb.0:
28+
; SOFT-FLOAT-32R2-NEXT: addiu $sp, $sp, -24
29+
; SOFT-FLOAT-32R2-NEXT: .cfi_def_cfa_offset 24
30+
; SOFT-FLOAT-32R2-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
31+
; SOFT-FLOAT-32R2-NEXT: sw $16, 16($sp) # 4-byte Folded Spill
32+
; SOFT-FLOAT-32R2-NEXT: .cfi_offset 31, -4
33+
; SOFT-FLOAT-32R2-NEXT: .cfi_offset 16, -8
34+
; SOFT-FLOAT-32R2-NEXT: jal __mulsf3
35+
; SOFT-FLOAT-32R2-NEXT: move $16, $6
36+
; SOFT-FLOAT-32R2-NEXT: move $4, $2
37+
; SOFT-FLOAT-32R2-NEXT: jal __addsf3
38+
; SOFT-FLOAT-32R2-NEXT: move $5, $16
39+
; SOFT-FLOAT-32R2-NEXT: lw $16, 16($sp) # 4-byte Folded Reload
40+
; SOFT-FLOAT-32R2-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
41+
; SOFT-FLOAT-32R2-NEXT: jr $ra
42+
; SOFT-FLOAT-32R2-NEXT: addiu $sp, $sp, 24
43+
;
44+
; SOFT-FLOAT-64-LABEL: fma_f32:
45+
; SOFT-FLOAT-64: # %bb.0:
46+
; SOFT-FLOAT-64-NEXT: daddiu $sp, $sp, -16
47+
; SOFT-FLOAT-64-NEXT: .cfi_def_cfa_offset 16
48+
; SOFT-FLOAT-64-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
49+
; SOFT-FLOAT-64-NEXT: sd $16, 0($sp) # 8-byte Folded Spill
50+
; SOFT-FLOAT-64-NEXT: .cfi_offset 31, -8
51+
; SOFT-FLOAT-64-NEXT: .cfi_offset 16, -16
52+
; SOFT-FLOAT-64-NEXT: move $16, $6
53+
; SOFT-FLOAT-64-NEXT: sll $4, $4, 0
54+
; SOFT-FLOAT-64-NEXT: jal __mulsf3
55+
; SOFT-FLOAT-64-NEXT: sll $5, $5, 0
56+
; SOFT-FLOAT-64-NEXT: sll $4, $2, 0
57+
; SOFT-FLOAT-64-NEXT: jal __addsf3
58+
; SOFT-FLOAT-64-NEXT: sll $5, $16, 0
59+
; SOFT-FLOAT-64-NEXT: ld $16, 0($sp) # 8-byte Folded Reload
60+
; SOFT-FLOAT-64-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
61+
; SOFT-FLOAT-64-NEXT: jr $ra
62+
; SOFT-FLOAT-64-NEXT: daddiu $sp, $sp, 16
63+
;
64+
; SOFT-FLOAT-64R2-LABEL: fma_f32:
65+
; SOFT-FLOAT-64R2: # %bb.0:
66+
; SOFT-FLOAT-64R2-NEXT: daddiu $sp, $sp, -16
67+
; SOFT-FLOAT-64R2-NEXT: .cfi_def_cfa_offset 16
68+
; SOFT-FLOAT-64R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
69+
; SOFT-FLOAT-64R2-NEXT: sd $16, 0($sp) # 8-byte Folded Spill
70+
; SOFT-FLOAT-64R2-NEXT: .cfi_offset 31, -8
71+
; SOFT-FLOAT-64R2-NEXT: .cfi_offset 16, -16
72+
; SOFT-FLOAT-64R2-NEXT: move $16, $6
73+
; SOFT-FLOAT-64R2-NEXT: sll $4, $4, 0
74+
; SOFT-FLOAT-64R2-NEXT: jal __mulsf3
75+
; SOFT-FLOAT-64R2-NEXT: sll $5, $5, 0
76+
; SOFT-FLOAT-64R2-NEXT: sll $4, $2, 0
77+
; SOFT-FLOAT-64R2-NEXT: jal __addsf3
78+
; SOFT-FLOAT-64R2-NEXT: sll $5, $16, 0
79+
; SOFT-FLOAT-64R2-NEXT: ld $16, 0($sp) # 8-byte Folded Reload
80+
; SOFT-FLOAT-64R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
81+
; SOFT-FLOAT-64R2-NEXT: jr $ra
82+
; SOFT-FLOAT-64R2-NEXT: daddiu $sp, $sp, 16
83+
%1 = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
84+
ret float %1
85+
}
86+
87+
define double @fma_f64(double %a, double %b, double %c) "use-soft-float"="true" {
88+
; SOFT-FLOAT-32-LABEL: fma_f64:
89+
; SOFT-FLOAT-32: # %bb.0:
90+
; SOFT-FLOAT-32-NEXT: addiu $sp, $sp, -24
91+
; SOFT-FLOAT-32-NEXT: .cfi_def_cfa_offset 24
92+
; SOFT-FLOAT-32-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
93+
; SOFT-FLOAT-32-NEXT: .cfi_offset 31, -4
94+
; SOFT-FLOAT-32-NEXT: jal __muldf3
95+
; SOFT-FLOAT-32-NEXT: nop
96+
; SOFT-FLOAT-32-NEXT: move $4, $2
97+
; SOFT-FLOAT-32-NEXT: lw $6, 40($sp)
98+
; SOFT-FLOAT-32-NEXT: lw $7, 44($sp)
99+
; SOFT-FLOAT-32-NEXT: jal __adddf3
100+
; SOFT-FLOAT-32-NEXT: move $5, $3
101+
; SOFT-FLOAT-32-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
102+
; SOFT-FLOAT-32-NEXT: jr $ra
103+
; SOFT-FLOAT-32-NEXT: addiu $sp, $sp, 24
104+
;
105+
; SOFT-FLOAT-32R2-LABEL: fma_f64:
106+
; SOFT-FLOAT-32R2: # %bb.0:
107+
; SOFT-FLOAT-32R2-NEXT: addiu $sp, $sp, -24
108+
; SOFT-FLOAT-32R2-NEXT: .cfi_def_cfa_offset 24
109+
; SOFT-FLOAT-32R2-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
110+
; SOFT-FLOAT-32R2-NEXT: .cfi_offset 31, -4
111+
; SOFT-FLOAT-32R2-NEXT: jal __muldf3
112+
; SOFT-FLOAT-32R2-NEXT: nop
113+
; SOFT-FLOAT-32R2-NEXT: move $4, $2
114+
; SOFT-FLOAT-32R2-NEXT: lw $6, 40($sp)
115+
; SOFT-FLOAT-32R2-NEXT: lw $7, 44($sp)
116+
; SOFT-FLOAT-32R2-NEXT: jal __adddf3
117+
; SOFT-FLOAT-32R2-NEXT: move $5, $3
118+
; SOFT-FLOAT-32R2-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
119+
; SOFT-FLOAT-32R2-NEXT: jr $ra
120+
; SOFT-FLOAT-32R2-NEXT: addiu $sp, $sp, 24
121+
;
122+
; SOFT-FLOAT-64-LABEL: fma_f64:
123+
; SOFT-FLOAT-64: # %bb.0:
124+
; SOFT-FLOAT-64-NEXT: daddiu $sp, $sp, -16
125+
; SOFT-FLOAT-64-NEXT: .cfi_def_cfa_offset 16
126+
; SOFT-FLOAT-64-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
127+
; SOFT-FLOAT-64-NEXT: sd $16, 0($sp) # 8-byte Folded Spill
128+
; SOFT-FLOAT-64-NEXT: .cfi_offset 31, -8
129+
; SOFT-FLOAT-64-NEXT: .cfi_offset 16, -16
130+
; SOFT-FLOAT-64-NEXT: jal __muldf3
131+
; SOFT-FLOAT-64-NEXT: move $16, $6
132+
; SOFT-FLOAT-64-NEXT: move $4, $2
133+
; SOFT-FLOAT-64-NEXT: jal __adddf3
134+
; SOFT-FLOAT-64-NEXT: move $5, $16
135+
; SOFT-FLOAT-64-NEXT: ld $16, 0($sp) # 8-byte Folded Reload
136+
; SOFT-FLOAT-64-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
137+
; SOFT-FLOAT-64-NEXT: jr $ra
138+
; SOFT-FLOAT-64-NEXT: daddiu $sp, $sp, 16
139+
;
140+
; SOFT-FLOAT-64R2-LABEL: fma_f64:
141+
; SOFT-FLOAT-64R2: # %bb.0:
142+
; SOFT-FLOAT-64R2-NEXT: daddiu $sp, $sp, -16
143+
; SOFT-FLOAT-64R2-NEXT: .cfi_def_cfa_offset 16
144+
; SOFT-FLOAT-64R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
145+
; SOFT-FLOAT-64R2-NEXT: sd $16, 0($sp) # 8-byte Folded Spill
146+
; SOFT-FLOAT-64R2-NEXT: .cfi_offset 31, -8
147+
; SOFT-FLOAT-64R2-NEXT: .cfi_offset 16, -16
148+
; SOFT-FLOAT-64R2-NEXT: jal __muldf3
149+
; SOFT-FLOAT-64R2-NEXT: move $16, $6
150+
; SOFT-FLOAT-64R2-NEXT: move $4, $2
151+
; SOFT-FLOAT-64R2-NEXT: jal __adddf3
152+
; SOFT-FLOAT-64R2-NEXT: move $5, $16
153+
; SOFT-FLOAT-64R2-NEXT: ld $16, 0($sp) # 8-byte Folded Reload
154+
; SOFT-FLOAT-64R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
155+
; SOFT-FLOAT-64R2-NEXT: jr $ra
156+
; SOFT-FLOAT-64R2-NEXT: daddiu $sp, $sp, 16
157+
%1 = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
158+
ret double %1
159+
}
160+
161+
declare float @llvm.fmuladd.f32(float %a, float %b, float %c)
162+
declare double @llvm.fmuladd.f64(double %a, double %b, double %c)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=sparc < %s | FileCheck %s -check-prefix=SOFT-FLOAT-32
3+
; RUN: llc -mtriple=sparc64 < %s | FileCheck %s -check-prefix=SOFT-FLOAT-64
4+
5+
define float @fma_f32(float %a, float %b, float %c) "use-soft-float"="true" {
6+
; SOFT-FLOAT-32-LABEL: fma_f32:
7+
; SOFT-FLOAT-32: .cfi_startproc
8+
; SOFT-FLOAT-32-NEXT: ! %bb.0:
9+
; SOFT-FLOAT-32-NEXT: save %sp, -96, %sp
10+
; SOFT-FLOAT-32-NEXT: .cfi_def_cfa_register %fp
11+
; SOFT-FLOAT-32-NEXT: .cfi_window_save
12+
; SOFT-FLOAT-32-NEXT: .cfi_register %o7, %i7
13+
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
14+
; SOFT-FLOAT-32-NEXT: call __mulsf3
15+
; SOFT-FLOAT-32-NEXT: mov %i1, %o1
16+
; SOFT-FLOAT-32-NEXT: call __addsf3
17+
; SOFT-FLOAT-32-NEXT: mov %i2, %o1
18+
; SOFT-FLOAT-32-NEXT: ret
19+
; SOFT-FLOAT-32-NEXT: restore %g0, %o0, %o0
20+
;
21+
; SOFT-FLOAT-64-LABEL: fma_f32:
22+
; SOFT-FLOAT-64: .cfi_startproc
23+
; SOFT-FLOAT-64-NEXT: ! %bb.0:
24+
; SOFT-FLOAT-64-NEXT: save %sp, -176, %sp
25+
; SOFT-FLOAT-64-NEXT: .cfi_def_cfa_register %fp
26+
; SOFT-FLOAT-64-NEXT: .cfi_window_save
27+
; SOFT-FLOAT-64-NEXT: .cfi_register %o7, %i7
28+
; SOFT-FLOAT-64-NEXT: srl %i0, 0, %o0
29+
; SOFT-FLOAT-64-NEXT: call __mulsf3
30+
; SOFT-FLOAT-64-NEXT: srl %i1, 0, %o1
31+
; SOFT-FLOAT-64-NEXT: call __addsf3
32+
; SOFT-FLOAT-64-NEXT: srl %i2, 0, %o1
33+
; SOFT-FLOAT-64-NEXT: ret
34+
; SOFT-FLOAT-64-NEXT: restore %g0, %o0, %o0
35+
%1 = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
36+
ret float %1
37+
}
38+
39+
define double @fma_f64(double %a, double %b, double %c) "use-soft-float"="true" {
40+
; SOFT-FLOAT-32-LABEL: fma_f64:
41+
; SOFT-FLOAT-32: .cfi_startproc
42+
; SOFT-FLOAT-32-NEXT: ! %bb.0:
43+
; SOFT-FLOAT-32-NEXT: save %sp, -96, %sp
44+
; SOFT-FLOAT-32-NEXT: .cfi_def_cfa_register %fp
45+
; SOFT-FLOAT-32-NEXT: .cfi_window_save
46+
; SOFT-FLOAT-32-NEXT: .cfi_register %o7, %i7
47+
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
48+
; SOFT-FLOAT-32-NEXT: mov %i1, %o1
49+
; SOFT-FLOAT-32-NEXT: mov %i2, %o2
50+
; SOFT-FLOAT-32-NEXT: call __muldf3
51+
; SOFT-FLOAT-32-NEXT: mov %i3, %o3
52+
; SOFT-FLOAT-32-NEXT: mov %i4, %o2
53+
; SOFT-FLOAT-32-NEXT: call __adddf3
54+
; SOFT-FLOAT-32-NEXT: mov %i5, %o3
55+
; SOFT-FLOAT-32-NEXT: mov %o0, %i0
56+
; SOFT-FLOAT-32-NEXT: ret
57+
; SOFT-FLOAT-32-NEXT: restore %g0, %o1, %o1
58+
;
59+
; SOFT-FLOAT-64-LABEL: fma_f64:
60+
; SOFT-FLOAT-64: .cfi_startproc
61+
; SOFT-FLOAT-64-NEXT: ! %bb.0:
62+
; SOFT-FLOAT-64-NEXT: save %sp, -176, %sp
63+
; SOFT-FLOAT-64-NEXT: .cfi_def_cfa_register %fp
64+
; SOFT-FLOAT-64-NEXT: .cfi_window_save
65+
; SOFT-FLOAT-64-NEXT: .cfi_register %o7, %i7
66+
; SOFT-FLOAT-64-NEXT: mov %i0, %o0
67+
; SOFT-FLOAT-64-NEXT: call __muldf3
68+
; SOFT-FLOAT-64-NEXT: mov %i1, %o1
69+
; SOFT-FLOAT-64-NEXT: call __adddf3
70+
; SOFT-FLOAT-64-NEXT: mov %i2, %o1
71+
; SOFT-FLOAT-64-NEXT: ret
72+
; SOFT-FLOAT-64-NEXT: restore %g0, %o0, %o0
73+
%1 = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
74+
ret double %1
75+
}
76+
77+
declare float @llvm.fmuladd.f32(float %a, float %b, float %c)
78+
declare double @llvm.fmuladd.f64(double %a, double %b, double %c)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=s390x < %s | FileCheck %s -check-prefix=SOFT-FLOAT
3+
4+
define float @fma_f32(float %a, float %b, float %c) "use-soft-float"="true" {
5+
; SOFT-FLOAT-LABEL: fma_f32:
6+
; SOFT-FLOAT: # %bb.0:
7+
; SOFT-FLOAT-NEXT: stmg %r13, %r15, 104(%r15)
8+
; SOFT-FLOAT-NEXT: .cfi_offset %r13, -56
9+
; SOFT-FLOAT-NEXT: .cfi_offset %r14, -48
10+
; SOFT-FLOAT-NEXT: .cfi_offset %r15, -40
11+
; SOFT-FLOAT-NEXT: aghi %r15, -160
12+
; SOFT-FLOAT-NEXT: .cfi_def_cfa_offset 320
13+
; SOFT-FLOAT-NEXT: llgfr %r2, %r2
14+
; SOFT-FLOAT-NEXT: llgfr %r3, %r3
15+
; SOFT-FLOAT-NEXT: lr %r13, %r4
16+
; SOFT-FLOAT-NEXT: brasl %r14, __mulsf3@PLT
17+
; SOFT-FLOAT-NEXT: llgfr %r3, %r13
18+
; SOFT-FLOAT-NEXT: brasl %r14, __addsf3@PLT
19+
; SOFT-FLOAT-NEXT: # kill: def $r2l killed $r2l killed $r2d
20+
; SOFT-FLOAT-NEXT: lmg %r13, %r15, 264(%r15)
21+
; SOFT-FLOAT-NEXT: br %r14
22+
%1 = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
23+
ret float %1
24+
}
25+
26+
define double @fma_f64(double %a, double %b, double %c) "use-soft-float"="true" {
27+
; SOFT-FLOAT-LABEL: fma_f64:
28+
; SOFT-FLOAT: # %bb.0:
29+
; SOFT-FLOAT-NEXT: stmg %r13, %r15, 104(%r15)
30+
; SOFT-FLOAT-NEXT: .cfi_offset %r13, -56
31+
; SOFT-FLOAT-NEXT: .cfi_offset %r14, -48
32+
; SOFT-FLOAT-NEXT: .cfi_offset %r15, -40
33+
; SOFT-FLOAT-NEXT: aghi %r15, -160
34+
; SOFT-FLOAT-NEXT: .cfi_def_cfa_offset 320
35+
; SOFT-FLOAT-NEXT: lgr %r13, %r4
36+
; SOFT-FLOAT-NEXT: brasl %r14, __muldf3@PLT
37+
; SOFT-FLOAT-NEXT: lgr %r3, %r13
38+
; SOFT-FLOAT-NEXT: brasl %r14, __adddf3@PLT
39+
; SOFT-FLOAT-NEXT: lmg %r13, %r15, 264(%r15)
40+
; SOFT-FLOAT-NEXT: br %r14
41+
%1 = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
42+
ret double %1
43+
}
44+
45+
declare float @llvm.fmuladd.f32(float %a, float %b, float %c)
46+
declare double @llvm.fmuladd.f64(double %a, double %b, double %c)

0 commit comments

Comments
 (0)