
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. Note: I don't have commit access.
407 lines
16 KiB
LLVM
407 lines
16 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: llc -mtriple=arm < %s | FileCheck %s -check-prefix=SOFT-FLOAT
|
|
; RUN: llc -mtriple=arm -mattr=+vfp4d16sp < %s | FileCheck %s -check-prefix=SOFT-FLOAT-VFP32
|
|
; RUN: llc -mtriple=arm -mattr=+vfp4d16sp,+fp64 < %s | FileCheck %s -check-prefix=SOFT-FLOAT-VFP64
|
|
|
|
define float @fmuladd_intrinsic_f32(float %a, float %b, float %c) #0 {
|
|
; SOFT-FLOAT-LABEL: fmuladd_intrinsic_f32:
|
|
; SOFT-FLOAT: @ %bb.0:
|
|
; SOFT-FLOAT-NEXT: push {r4, lr}
|
|
; SOFT-FLOAT-NEXT: mov r4, r2
|
|
; SOFT-FLOAT-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-NEXT: mov r1, r4
|
|
; SOFT-FLOAT-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-NEXT: pop {r4, lr}
|
|
; SOFT-FLOAT-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP32-LABEL: fmuladd_intrinsic_f32:
|
|
; SOFT-FLOAT-VFP32: @ %bb.0:
|
|
; SOFT-FLOAT-VFP32-NEXT: push {r4, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r4, r2
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r1, r4
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: pop {r4, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP64-LABEL: fmuladd_intrinsic_f32:
|
|
; SOFT-FLOAT-VFP64: @ %bb.0:
|
|
; SOFT-FLOAT-VFP64-NEXT: push {r4, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r4, r2
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r1, r4
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: pop {r4, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov pc, lr
|
|
%result = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
|
|
ret float %result
|
|
}
|
|
|
|
define double @fmuladd_intrinsic_f64(double %a, double %b, double %c) #0 {
|
|
; SOFT-FLOAT-LABEL: fmuladd_intrinsic_f64:
|
|
; SOFT-FLOAT: @ %bb.0:
|
|
; SOFT-FLOAT-NEXT: push {r11, lr}
|
|
; SOFT-FLOAT-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #8]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #12]
|
|
; SOFT-FLOAT-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-NEXT: pop {r11, lr}
|
|
; SOFT-FLOAT-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP32-LABEL: fmuladd_intrinsic_f64:
|
|
; SOFT-FLOAT-VFP32: @ %bb.0:
|
|
; SOFT-FLOAT-VFP32-NEXT: push {r11, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #8]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #12]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP32-NEXT: pop {r11, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP64-LABEL: fmuladd_intrinsic_f64:
|
|
; SOFT-FLOAT-VFP64: @ %bb.0:
|
|
; SOFT-FLOAT-VFP64-NEXT: push {r11, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #8]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #12]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP64-NEXT: pop {r11, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov pc, lr
|
|
%result = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
|
|
ret double %result
|
|
}
|
|
|
|
define float @fmuladd_contract_f32(float %a, float %b, float %c) #0 {
|
|
; SOFT-FLOAT-LABEL: fmuladd_contract_f32:
|
|
; SOFT-FLOAT: @ %bb.0:
|
|
; SOFT-FLOAT-NEXT: push {r4, lr}
|
|
; SOFT-FLOAT-NEXT: mov r4, r2
|
|
; SOFT-FLOAT-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-NEXT: mov r1, r4
|
|
; SOFT-FLOAT-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-NEXT: pop {r4, lr}
|
|
; SOFT-FLOAT-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP32-LABEL: fmuladd_contract_f32:
|
|
; SOFT-FLOAT-VFP32: @ %bb.0:
|
|
; SOFT-FLOAT-VFP32-NEXT: push {r4, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r4, r2
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r1, r4
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: pop {r4, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP64-LABEL: fmuladd_contract_f32:
|
|
; SOFT-FLOAT-VFP64: @ %bb.0:
|
|
; SOFT-FLOAT-VFP64-NEXT: push {r4, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r4, r2
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r1, r4
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: pop {r4, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov pc, lr
|
|
%product = fmul contract float %a, %b
|
|
%result = fadd contract float %product, %c
|
|
ret float %result
|
|
}
|
|
|
|
define double @fmuladd_contract_f64(double %a, double %b, double %c) #0 {
|
|
; SOFT-FLOAT-LABEL: fmuladd_contract_f64:
|
|
; SOFT-FLOAT: @ %bb.0:
|
|
; SOFT-FLOAT-NEXT: push {r11, lr}
|
|
; SOFT-FLOAT-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #8]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #12]
|
|
; SOFT-FLOAT-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-NEXT: pop {r11, lr}
|
|
; SOFT-FLOAT-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP32-LABEL: fmuladd_contract_f64:
|
|
; SOFT-FLOAT-VFP32: @ %bb.0:
|
|
; SOFT-FLOAT-VFP32-NEXT: push {r11, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #8]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #12]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP32-NEXT: pop {r11, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP64-LABEL: fmuladd_contract_f64:
|
|
; SOFT-FLOAT-VFP64: @ %bb.0:
|
|
; SOFT-FLOAT-VFP64-NEXT: push {r11, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #8]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #12]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP64-NEXT: pop {r11, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov pc, lr
|
|
%product = fmul contract double %a, %b
|
|
%result = fadd contract double %product, %c
|
|
ret double %result
|
|
}
|
|
|
|
define <4 x float> @fmuladd_contract_v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c) #0 {
|
|
; SOFT-FLOAT-LABEL: fmuladd_contract_v4f32:
|
|
; SOFT-FLOAT: @ %bb.0:
|
|
; SOFT-FLOAT-NEXT: push {r4, r5, r6, r7, r11, lr}
|
|
; SOFT-FLOAT-NEXT: mov r7, r1
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #24]
|
|
; SOFT-FLOAT-NEXT: mov r4, r3
|
|
; SOFT-FLOAT-NEXT: mov r6, r2
|
|
; SOFT-FLOAT-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #40]
|
|
; SOFT-FLOAT-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #28]
|
|
; SOFT-FLOAT-NEXT: mov r5, r0
|
|
; SOFT-FLOAT-NEXT: mov r0, r7
|
|
; SOFT-FLOAT-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #44]
|
|
; SOFT-FLOAT-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #32]
|
|
; SOFT-FLOAT-NEXT: mov r7, r0
|
|
; SOFT-FLOAT-NEXT: mov r0, r6
|
|
; SOFT-FLOAT-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #48]
|
|
; SOFT-FLOAT-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #36]
|
|
; SOFT-FLOAT-NEXT: mov r6, r0
|
|
; SOFT-FLOAT-NEXT: mov r0, r4
|
|
; SOFT-FLOAT-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #52]
|
|
; SOFT-FLOAT-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-NEXT: mov r3, r0
|
|
; SOFT-FLOAT-NEXT: mov r0, r5
|
|
; SOFT-FLOAT-NEXT: mov r1, r7
|
|
; SOFT-FLOAT-NEXT: mov r2, r6
|
|
; SOFT-FLOAT-NEXT: pop {r4, r5, r6, r7, r11, lr}
|
|
; SOFT-FLOAT-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP32-LABEL: fmuladd_contract_v4f32:
|
|
; SOFT-FLOAT-VFP32: @ %bb.0:
|
|
; SOFT-FLOAT-VFP32-NEXT: push {r4, r5, r6, r7, r11, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r7, r1
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #24]
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r4, r3
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r6, r2
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #40]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #28]
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r5, r0
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r0, r7
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #44]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #32]
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r7, r0
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r0, r6
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #48]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #36]
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r6, r0
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r0, r4
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #52]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r3, r0
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r0, r5
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r1, r7
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r2, r6
|
|
; SOFT-FLOAT-VFP32-NEXT: pop {r4, r5, r6, r7, r11, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP64-LABEL: fmuladd_contract_v4f32:
|
|
; SOFT-FLOAT-VFP64: @ %bb.0:
|
|
; SOFT-FLOAT-VFP64-NEXT: push {r4, r5, r6, r7, r11, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r7, r1
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #24]
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r4, r3
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r6, r2
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #40]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #28]
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r5, r0
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r0, r7
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #44]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #32]
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r7, r0
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r0, r6
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #48]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #36]
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r6, r0
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r0, r4
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __mulsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #52]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __addsf3
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r3, r0
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r0, r5
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r1, r7
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r2, r6
|
|
; SOFT-FLOAT-VFP64-NEXT: pop {r4, r5, r6, r7, r11, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov pc, lr
|
|
%product = fmul contract <4 x float> %a, %b
|
|
%result = fadd contract <4 x float> %product, %c
|
|
ret <4 x float> %result
|
|
}
|
|
|
|
define <4 x double> @fmuladd_contract_v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c) #0 {
|
|
; SOFT-FLOAT-LABEL: fmuladd_contract_v4f64:
|
|
; SOFT-FLOAT: @ %bb.0:
|
|
; SOFT-FLOAT-NEXT: push {r4, r5, r6, lr}
|
|
; SOFT-FLOAT-NEXT: mov r5, r3
|
|
; SOFT-FLOAT-NEXT: mov r6, r2
|
|
; SOFT-FLOAT-NEXT: mov r4, r0
|
|
; SOFT-FLOAT-NEXT: ldr r0, [sp, #32]
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #36]
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #64]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #68]
|
|
; SOFT-FLOAT-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #96]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #100]
|
|
; SOFT-FLOAT-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-NEXT: str r0, [r4, #24]
|
|
; SOFT-FLOAT-NEXT: str r1, [r4, #28]
|
|
; SOFT-FLOAT-NEXT: ldr r0, [sp, #24]
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #28]
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #56]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #60]
|
|
; SOFT-FLOAT-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #88]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #92]
|
|
; SOFT-FLOAT-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-NEXT: str r0, [r4, #16]
|
|
; SOFT-FLOAT-NEXT: str r1, [r4, #20]
|
|
; SOFT-FLOAT-NEXT: ldr r0, [sp, #16]
|
|
; SOFT-FLOAT-NEXT: ldr r1, [sp, #20]
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #48]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #52]
|
|
; SOFT-FLOAT-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #80]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #84]
|
|
; SOFT-FLOAT-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #40]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #44]
|
|
; SOFT-FLOAT-NEXT: str r0, [r4, #8]
|
|
; SOFT-FLOAT-NEXT: mov r0, r6
|
|
; SOFT-FLOAT-NEXT: str r1, [r4, #12]
|
|
; SOFT-FLOAT-NEXT: mov r1, r5
|
|
; SOFT-FLOAT-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-NEXT: ldr r2, [sp, #72]
|
|
; SOFT-FLOAT-NEXT: ldr r3, [sp, #76]
|
|
; SOFT-FLOAT-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-NEXT: stm r4, {r0, r1}
|
|
; SOFT-FLOAT-NEXT: pop {r4, r5, r6, lr}
|
|
; SOFT-FLOAT-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP32-LABEL: fmuladd_contract_v4f64:
|
|
; SOFT-FLOAT-VFP32: @ %bb.0:
|
|
; SOFT-FLOAT-VFP32-NEXT: push {r4, r5, r6, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r5, r3
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r6, r2
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r4, r0
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r0, [sp, #32]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #36]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #64]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #68]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #96]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #100]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP32-NEXT: str r0, [r4, #24]
|
|
; SOFT-FLOAT-VFP32-NEXT: str r1, [r4, #28]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r0, [sp, #24]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #28]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #56]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #60]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #88]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #92]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP32-NEXT: str r0, [r4, #16]
|
|
; SOFT-FLOAT-VFP32-NEXT: str r1, [r4, #20]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r0, [sp, #16]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r1, [sp, #20]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #48]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #52]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #80]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #84]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #40]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #44]
|
|
; SOFT-FLOAT-VFP32-NEXT: str r0, [r4, #8]
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r0, r6
|
|
; SOFT-FLOAT-VFP32-NEXT: str r1, [r4, #12]
|
|
; SOFT-FLOAT-VFP32-NEXT: mov r1, r5
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r2, [sp, #72]
|
|
; SOFT-FLOAT-VFP32-NEXT: ldr r3, [sp, #76]
|
|
; SOFT-FLOAT-VFP32-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP32-NEXT: stm r4, {r0, r1}
|
|
; SOFT-FLOAT-VFP32-NEXT: pop {r4, r5, r6, lr}
|
|
; SOFT-FLOAT-VFP32-NEXT: mov pc, lr
|
|
;
|
|
; SOFT-FLOAT-VFP64-LABEL: fmuladd_contract_v4f64:
|
|
; SOFT-FLOAT-VFP64: @ %bb.0:
|
|
; SOFT-FLOAT-VFP64-NEXT: push {r4, r5, r6, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r5, r3
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r6, r2
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r4, r0
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r0, [sp, #32]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #36]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #64]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #68]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #96]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #100]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP64-NEXT: str r0, [r4, #24]
|
|
; SOFT-FLOAT-VFP64-NEXT: str r1, [r4, #28]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r0, [sp, #24]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #28]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #56]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #60]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #88]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #92]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP64-NEXT: str r0, [r4, #16]
|
|
; SOFT-FLOAT-VFP64-NEXT: str r1, [r4, #20]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r0, [sp, #16]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r1, [sp, #20]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #48]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #52]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #80]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #84]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #40]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #44]
|
|
; SOFT-FLOAT-VFP64-NEXT: str r0, [r4, #8]
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r0, r6
|
|
; SOFT-FLOAT-VFP64-NEXT: str r1, [r4, #12]
|
|
; SOFT-FLOAT-VFP64-NEXT: mov r1, r5
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __muldf3
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r2, [sp, #72]
|
|
; SOFT-FLOAT-VFP64-NEXT: ldr r3, [sp, #76]
|
|
; SOFT-FLOAT-VFP64-NEXT: bl __adddf3
|
|
; SOFT-FLOAT-VFP64-NEXT: stm r4, {r0, r1}
|
|
; SOFT-FLOAT-VFP64-NEXT: pop {r4, r5, r6, lr}
|
|
; SOFT-FLOAT-VFP64-NEXT: mov pc, lr
|
|
%product = fmul contract <4 x double> %a, %b
|
|
%result = fadd contract <4 x double> %product, %c
|
|
ret <4 x double> %result
|
|
}
|
|
|
|
attributes #0 = { "use-soft-float"="true" }
|
|
|
|
declare float @llvm.fmuladd.f32(float %a, float %b, float %c)
|
|
declare double @llvm.fmuladd.f64(double %a, double %b, double %c)
|