1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -verify-machineinstrs | FileCheck %s
4 define double @test1(double %a, double %b) {
7 ; CHECK-NEXT: fadd d1, d1, d1
8 ; CHECK-NEXT: fsub d0, d0, d1
10 %mul = fmul double %b, -2.000000e+00
11 %add1 = fadd double %a, %mul
15 ; DAGCombine will canonicalize 'a - 2.0*b' to 'a + -2.0*b'
17 define double @test2(double %a, double %b) {
20 ; CHECK-NEXT: fadd d1, d1, d1
21 ; CHECK-NEXT: fsub d0, d0, d1
23 %mul = fmul double %b, 2.000000e+00
24 %add1 = fsub double %a, %mul
28 define double @test3(double %a, double %b, double %c) {
31 ; CHECK-NEXT: fmul d0, d0, d1
32 ; CHECK-NEXT: fadd d1, d2, d2
33 ; CHECK-NEXT: fsub d0, d0, d1
35 %mul = fmul double %a, %b
36 %mul1 = fmul double %c, 2.000000e+00
37 %sub = fsub double %mul, %mul1
41 define double @test4(double %a, double %b, double %c) {
44 ; CHECK-NEXT: fmul d0, d0, d1
45 ; CHECK-NEXT: fadd d1, d2, d2
46 ; CHECK-NEXT: fsub d0, d0, d1
48 %mul = fmul double %a, %b
49 %mul1 = fmul double %c, -2.000000e+00
50 %add2 = fadd double %mul, %mul1
54 define <4 x float> @test5(<4 x float> %a, <4 x float> %b) {
57 ; CHECK-NEXT: fadd v1.4s, v1.4s, v1.4s
58 ; CHECK-NEXT: fsub v0.4s, v0.4s, v1.4s
60 %mul = fmul <4 x float> %b, <float -2.0, float -2.0, float -2.0, float -2.0>
61 %add = fadd <4 x float> %a, %mul
65 define <4 x float> @test6(<4 x float> %a, <4 x float> %b) {
68 ; CHECK-NEXT: fadd v1.4s, v1.4s, v1.4s
69 ; CHECK-NEXT: fsub v0.4s, v0.4s, v1.4s
71 %mul = fmul <4 x float> %b, <float 2.0, float 2.0, float 2.0, float 2.0>
72 %add = fsub <4 x float> %a, %mul
76 ; Don't fold (fadd A, (fmul B, -2.0)) -> (fsub A, (fadd B, B)) if the fmul has
79 define double @test7(double %a, double %b) nounwind {
82 ; CHECK-NEXT: str d8, [sp, #-16]! // 8-byte Folded Spill
83 ; CHECK-NEXT: fmov d2, #-2.00000000
84 ; CHECK-NEXT: fmul d1, d1, d2
85 ; CHECK-NEXT: fadd d8, d0, d1
86 ; CHECK-NEXT: mov v0.16b, v1.16b
87 ; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill
89 ; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload
90 ; CHECK-NEXT: mov v0.16b, v8.16b
91 ; CHECK-NEXT: ldr d8, [sp], #16 // 8-byte Folded Reload
93 %mul = fmul double %b, -2.000000e+00
94 %add1 = fadd double %a, %mul
95 call void @use(double %mul)
99 define float @fadd_const_multiuse_fmf(float %x) {
100 ; CHECK-LABEL: fadd_const_multiuse_fmf:
102 ; CHECK-NEXT: adrp x8, .LCPI7_0
103 ; CHECK-NEXT: adrp x9, .LCPI7_1
104 ; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI7_0]
105 ; CHECK-NEXT: ldr s2, [x9, :lo12:.LCPI7_1]
106 ; CHECK-NEXT: fadd s1, s0, s1
107 ; CHECK-NEXT: fadd s0, s0, s2
108 ; CHECK-NEXT: fadd s0, s1, s0
110 %a1 = fadd float %x, 42.0
111 %a2 = fadd nsz reassoc float %a1, 17.0
112 %a3 = fadd float %a1, %a2
116 ; DAGCombiner transforms this into: (x + 59.0) + (x + 17.0).
117 ; The machine combiner transforms this into a chain of 3 dependent adds:
118 ; ((x + 59.0) + 17.0) + x
120 define float @fadd_const_multiuse_attr(float %x) #0 {
121 ; CHECK-LABEL: fadd_const_multiuse_attr:
123 ; CHECK-NEXT: adrp x9, .LCPI8_1
124 ; CHECK-NEXT: adrp x8, .LCPI8_0
125 ; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI8_1]
126 ; CHECK-NEXT: ldr s2, [x8, :lo12:.LCPI8_0]
127 ; CHECK-NEXT: fadd s1, s0, s1
128 ; CHECK-NEXT: fadd s1, s2, s1
129 ; CHECK-NEXT: fadd s0, s0, s1
131 %a1 = fadd float %x, 42.0
132 %a2 = fadd float %a1, 17.0
133 %a3 = fadd float %a1, %a2
137 attributes #0 = { "unsafe-fp-math"="true" }
139 declare void @use(double)