summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/AArch64/fadd-combines.ll
blob: be027a7b558b2fffd465507a4318cfb57d9f7036 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -verify-machineinstrs | FileCheck %s

define double @test1(double %a, double %b) {
; CHECK-LABEL: test1:
; CHECK:       // %bb.0:
; CHECK-NEXT:    fadd d1, d1, d1
; CHECK-NEXT:    fsub d0, d0, d1
; CHECK-NEXT:    ret
  %mul = fmul double %b, -2.000000e+00
  %add1 = fadd double %a, %mul
  ret double %add1
}

; DAGCombine will canonicalize 'a - 2.0*b' to 'a + -2.0*b'

define double @test2(double %a, double %b) {
; CHECK-LABEL: test2:
; CHECK:       // %bb.0:
; CHECK-NEXT:    fadd d1, d1, d1
; CHECK-NEXT:    fsub d0, d0, d1
; CHECK-NEXT:    ret
  %mul = fmul double %b, 2.000000e+00
  %add1 = fsub double %a, %mul
  ret double %add1
}

define double @test3(double %a, double %b, double %c) {
; CHECK-LABEL: test3:
; CHECK:       // %bb.0:
; CHECK-NEXT:    fmul d0, d0, d1
; CHECK-NEXT:    fadd d1, d2, d2
; CHECK-NEXT:    fsub d0, d0, d1
; CHECK-NEXT:    ret
  %mul = fmul double %a, %b
  %mul1 = fmul double %c, 2.000000e+00
  %sub = fsub double %mul, %mul1
  ret double %sub
}

define double @test4(double %a, double %b, double %c) {
; CHECK-LABEL: test4:
; CHECK:       // %bb.0:
; CHECK-NEXT:    fmul d0, d0, d1
; CHECK-NEXT:    fadd d1, d2, d2
; CHECK-NEXT:    fsub d0, d0, d1
; CHECK-NEXT:    ret
  %mul = fmul double %a, %b
  %mul1 = fmul double %c, -2.000000e+00
  %add2 = fadd double %mul, %mul1
  ret double %add2
}

define <4 x float> @test5(<4 x float> %a, <4 x float> %b) {
; CHECK-LABEL: test5:
; CHECK:       // %bb.0:
; CHECK-NEXT:    fadd v1.4s, v1.4s, v1.4s
; CHECK-NEXT:    fsub v0.4s, v0.4s, v1.4s
; CHECK-NEXT:    ret
  %mul = fmul <4 x float> %b, <float -2.0, float -2.0, float -2.0, float -2.0>
  %add = fadd <4 x float> %a, %mul
  ret <4 x float> %add
}

define <4 x float> @test6(<4 x float> %a, <4 x float> %b) {
; CHECK-LABEL: test6:
; CHECK:       // %bb.0:
; CHECK-NEXT:    fadd v1.4s, v1.4s, v1.4s
; CHECK-NEXT:    fsub v0.4s, v0.4s, v1.4s
; CHECK-NEXT:    ret
  %mul = fmul <4 x float> %b, <float 2.0, float 2.0, float 2.0, float 2.0>
  %add = fsub <4 x float> %a, %mul
  ret <4 x float> %add
}

; Don't fold (fadd A, (fmul B, -2.0)) -> (fsub A, (fadd B, B)) if the fmul has
; multiple uses.

define double @test7(double %a, double %b) nounwind {
; CHECK-LABEL: test7:
; CHECK:       // %bb.0:
; CHECK-NEXT:    str d8, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT:    fmov d2, #-2.00000000
; CHECK-NEXT:    fmul d1, d1, d2
; CHECK-NEXT:    fadd d8, d0, d1
; CHECK-NEXT:    mov v0.16b, v1.16b
; CHECK-NEXT:    str x30, [sp, #8] // 8-byte Folded Spill
; CHECK-NEXT:    bl use
; CHECK-NEXT:    ldr x30, [sp, #8] // 8-byte Folded Reload
; CHECK-NEXT:    mov v0.16b, v8.16b
; CHECK-NEXT:    ldr d8, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT:    ret
  %mul = fmul double %b, -2.000000e+00
  %add1 = fadd double %a, %mul
  call void @use(double %mul)
  ret double %add1
}

define float @fadd_const_multiuse_fmf(float %x) {
; CHECK-LABEL: fadd_const_multiuse_fmf:
; CHECK:       // %bb.0:
; CHECK-NEXT:    adrp x8, .LCPI7_0
; CHECK-NEXT:    adrp x9, .LCPI7_1
; CHECK-NEXT:    ldr s1, [x8, :lo12:.LCPI7_0]
; CHECK-NEXT:    ldr s2, [x9, :lo12:.LCPI7_1]
; CHECK-NEXT:    fadd s1, s0, s1
; CHECK-NEXT:    fadd s0, s0, s2
; CHECK-NEXT:    fadd s0, s1, s0
; CHECK-NEXT:    ret
  %a1 = fadd float %x, 42.0
  %a2 = fadd nsz reassoc float %a1, 17.0
  %a3 = fadd float %a1, %a2
  ret float %a3
}

; DAGCombiner transforms this into: (x + 59.0) + (x + 17.0).
; The machine combiner transforms this into a chain of 3 dependent adds:
; ((x + 59.0) + 17.0) + x

define float @fadd_const_multiuse_attr(float %x) #0 {
; CHECK-LABEL: fadd_const_multiuse_attr:
; CHECK:       // %bb.0:
; CHECK-NEXT:    adrp x9, .LCPI8_1
; CHECK-NEXT:    adrp x8, .LCPI8_0
; CHECK-NEXT:    ldr s1, [x9, :lo12:.LCPI8_1]
; CHECK-NEXT:    ldr s2, [x8, :lo12:.LCPI8_0]
; CHECK-NEXT:    fadd s1, s0, s1
; CHECK-NEXT:    fadd s1, s2, s1
; CHECK-NEXT:    fadd s0, s0, s1
; CHECK-NEXT:    ret
  %a1 = fadd float %x, 42.0
  %a2 = fadd float %a1, 17.0
  %a3 = fadd float %a1, %a2
  ret float %a3
}

attributes #0 = { "unsafe-fp-math"="true" }

declare void @use(double)

OpenPOWER on IntegriCloud