Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / ARM / fp16-return-pr60510.ll
bloba84cbce2d696315907a8ef2052a291cce3442f5b
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --filter-out "(\.v?save|push|pop)"
3 ; No FP16/BF16
4 ; RUN: llc -mtriple=arm-none-eabi -float-abi=soft -mattr=+armv8.2-a,+fp-armv8,-fullfp16,-bf16,-neon %s -o - | FileCheck %s --check-prefixes=NO-FP16-SOFT
5 ; RUN: llc -mtriple=thumb-none-eabi -float-abi=soft -mattr=+armv8.2-a,+fp-armv8,-fullfp16,-bf16,-neon %s -o - | FileCheck %s --check-prefixes=NO-FP16-SOFT
6 ; RUN: llc -mtriple=arm-none-eabi -mattr=+armv8.2-a,+fp-armv8,-fullfp16,-bf16,-neon %s -o - | FileCheck %s --check-prefixes=NO-FP16-SOFT
7 ; RUN: llc -mtriple=thumb-none-eabi -mattr=+armv8.2-a,+fp-armv8,-fullfp16,-bf16,-neon %s -o - | FileCheck %s --check-prefixes=NO-FP16-SOFT
8 ; RUN: llc -mtriple=arm-none-eabihf -mattr=+armv8.2-a,+fp-armv8,-fullfp16,-bf16,-neon %s -o - | FileCheck %s --check-prefixes=NO-FP16-HARD
9 ; RUN: llc -mtriple=thumb-none-eabihf -mattr=+armv8.2-a,+fp-armv8,-fullfp16,-bf16,-neon %s -o - | FileCheck %s --check-prefixes=NO-FP16-HARD
11 ; FP16/BF16
12 ; RUN: llc -mtriple=arm-none-eabi -float-abi=soft -mattr=+armv8.2-a,+fp-armv8,+fullfp16,+bf16,-neon %s -o - | FileCheck %s --check-prefixes=FP16-SOFT
13 ; RUN: llc -mtriple=thumb-none-eabi -float-abi=soft -mattr=+armv8.2-a,+fp-armv8,+fullfp16,+bf16,-neon %s -o - | FileCheck %s --check-prefixes=FP16-SOFT
14 ; RUN: llc -mtriple=arm-none-eabi -mattr=+armv8.2-a,+fp-armv8,+fullfp16,+bf16,-neon %s -o - | FileCheck %s --check-prefixes=FP16-SOFT
15 ; RUN: llc -mtriple=thumb-none-eabi -mattr=+armv8.2-a,+fp-armv8,+fullfp16,+bf16,-neon %s -o - | FileCheck %s --check-prefixes=FP16-SOFT
16 ; RUN: llc -mtriple=arm-none-eabihf -mattr=+armv8.2-a,+fp-armv8,+fullfp16,+bf16,-neon %s -o - | FileCheck %s --check-prefixes=FP16-HARD
17 ; RUN: llc -mtriple=thumb-none-eabihf -mattr=+armv8.2-a,+fp-armv8,+fullfp16,+bf16,-neon %s -o - | FileCheck %s --check-prefixes=FP16-HARD
19 ; PR60510 showed a bug where the return from `*_inner` was getting "lost" by an
20 ; optimisation, and a garbage value was being left in `s0`.
22 declare dso_local float @other(float) nounwind
23 declare dso_local void @fp16_sink(half) nounwind
24 declare dso_local void @bf16_sink(bfloat) nounwind
26 declare dso_local half @fp16_inner() nounwind
27 declare dso_local bfloat @bf_inner() nounwind
29 define half @fp16_out_call_oneuse(float %arg) nounwind {
30 ; NO-FP16-SOFT-LABEL: fp16_out_call_oneuse:
31 ; NO-FP16-SOFT:  @ %bb.0:
32 ; NO-FP16-SOFT:    mov r4, r0
33 ; NO-FP16-SOFT:    bl fp16_inner
34 ; NO-FP16-SOFT:    mov r5, r0
35 ; NO-FP16-SOFT:    mov r0, r4
36 ; NO-FP16-SOFT:    bl other
37 ; NO-FP16-SOFT:    mov r0, r5
39 ; NO-FP16-HARD-LABEL: fp16_out_call_oneuse:
40 ; NO-FP16-HARD:  @ %bb.0:
41 ; NO-FP16-HARD:    vmov.f32 s16, s0
42 ; NO-FP16-HARD:    bl fp16_inner
43 ; NO-FP16-HARD:    vmov.f32 s18, s0
44 ; NO-FP16-HARD:    vmov.f32 s0, s16
45 ; NO-FP16-HARD:    bl other
46 ; NO-FP16-HARD:    vmov.f32 s0, s18
48 ; FP16-SOFT-LABEL: fp16_out_call_oneuse:
49 ; FP16-SOFT:  @ %bb.0:
50 ; FP16-SOFT:    mov r4, r0
51 ; FP16-SOFT:    bl fp16_inner
52 ; FP16-SOFT:    mov r5, r0
53 ; FP16-SOFT:    mov r0, r4
54 ; FP16-SOFT:    bl other
55 ; FP16-SOFT:    vmov.f16 s0, r5
56 ; FP16-SOFT:    vmov r0, s0
58 ; FP16-HARD-LABEL: fp16_out_call_oneuse:
59 ; FP16-HARD:  @ %bb.0:
60 ; FP16-HARD:    vmov.f32 s16, s0
61 ; FP16-HARD:    bl fp16_inner
62 ; FP16-HARD:    vmov.f32 s18, s0
63 ; FP16-HARD:    vmov.f32 s0, s16
64 ; FP16-HARD:    bl other
65 ; FP16-HARD:    vmov.f32 s0, s18
66   %call = call half @fp16_inner()
67   %call1 = call float @other(float %arg)
68   ret half %call
71 define half @fp16_out_call_multiuse(float %arg) nounwind {
72 ; NO-FP16-SOFT-LABEL: fp16_out_call_multiuse:
73 ; NO-FP16-SOFT:  @ %bb.0:
74 ; NO-FP16-SOFT:    mov r4, r0
75 ; NO-FP16-SOFT:    bl fp16_inner
76 ; NO-FP16-SOFT:    mov r5, r0
77 ; NO-FP16-SOFT:    mov r0, r4
78 ; NO-FP16-SOFT:    bl other
79 ; NO-FP16-SOFT:    mov r0, r5
80 ; NO-FP16-SOFT:    bl fp16_sink
81 ; NO-FP16-SOFT:    mov r0, r5
83 ; NO-FP16-HARD-LABEL: fp16_out_call_multiuse:
84 ; NO-FP16-HARD:  @ %bb.0:
85 ; NO-FP16-HARD:    vmov.f32 s16, s0
86 ; NO-FP16-HARD:    bl fp16_inner
87 ; NO-FP16-HARD:    vmov.f32 s18, s0
88 ; NO-FP16-HARD:    vmov.f32 s0, s16
89 ; NO-FP16-HARD:    bl other
90 ; NO-FP16-HARD:    vmov.f32 s0, s18
91 ; NO-FP16-HARD:    bl fp16_sink
92 ; NO-FP16-HARD:    vmov.f32 s0, s18
94 ; FP16-SOFT-LABEL: fp16_out_call_multiuse:
95 ; FP16-SOFT:  @ %bb.0:
96 ; FP16-SOFT:    mov r4, r0
97 ; FP16-SOFT:    bl fp16_inner
98 ; FP16-SOFT:    mov r5, r0
99 ; FP16-SOFT:    mov r0, r4
100 ; FP16-SOFT:    bl other
101 ; FP16-SOFT:    vmov.f16 s16, r5
102 ; FP16-SOFT:    vmov.f16 r0, s16
103 ; FP16-SOFT:    bl fp16_sink
104 ; FP16-SOFT:    vmov r0, s16
106 ; FP16-HARD-LABEL: fp16_out_call_multiuse:
107 ; FP16-HARD:  @ %bb.0:
108 ; FP16-HARD:    vmov.f32 s16, s0
109 ; FP16-HARD:    bl fp16_inner
110 ; FP16-HARD:    vmov.f32 s18, s0
111 ; FP16-HARD:    vmov.f32 s0, s16
112 ; FP16-HARD:    bl other
113 ; FP16-HARD:    vmov.f16 r0, s18
114 ; FP16-HARD:    vmov s0, r0
115 ; FP16-HARD:    bl fp16_sink
116 ; FP16-HARD:    vmov.f32 s0, s18
117   %call = call half @fp16_inner()
118   %call1 = call float @other(float %arg)
119   call void @fp16_sink(half %call)
120   ret half %call
123 define bfloat @bf_out_call_oneuse(float %arg) nounwind {
124 ; NO-FP16-SOFT-LABEL: bf_out_call_oneuse:
125 ; NO-FP16-SOFT:  @ %bb.0:
126 ; NO-FP16-SOFT:    mov r4, r0
127 ; NO-FP16-SOFT:    bl bf_inner
128 ; NO-FP16-SOFT:    mov r5, r0
129 ; NO-FP16-SOFT:    mov r0, r4
130 ; NO-FP16-SOFT:    bl other
131 ; NO-FP16-SOFT:    mov r0, r5
133 ; NO-FP16-HARD-LABEL: bf_out_call_oneuse:
134 ; NO-FP16-HARD:  @ %bb.0:
135 ; NO-FP16-HARD:    vmov.f32 s16, s0
136 ; NO-FP16-HARD:    bl bf_inner
137 ; NO-FP16-HARD:    vmov.f32 s18, s0
138 ; NO-FP16-HARD:    vmov.f32 s0, s16
139 ; NO-FP16-HARD:    bl other
140 ; NO-FP16-HARD:    vmov.f32 s0, s18
142 ; FP16-SOFT-LABEL: bf_out_call_oneuse:
143 ; FP16-SOFT:  @ %bb.0:
144 ; FP16-SOFT:    mov r4, r0
145 ; FP16-SOFT:    bl bf_inner
146 ; FP16-SOFT:    mov r5, r0
147 ; FP16-SOFT:    mov r0, r4
148 ; FP16-SOFT:    bl other
149 ; FP16-SOFT:    mov r0, r5
151 ; FP16-HARD-LABEL: bf_out_call_oneuse:
152 ; FP16-HARD:  @ %bb.0:
153 ; FP16-HARD:    vmov.f32 s16, s0
154 ; FP16-HARD:    bl bf_inner
155 ; FP16-HARD:    vmov.f32 s18, s0
156 ; FP16-HARD:    vmov.f32 s0, s16
157 ; FP16-HARD:    bl other
158 ; FP16-HARD:    vmov.f32 s0, s18
159   %call = call bfloat @bf_inner()
160   %call1 = call float @other(float %arg)
161   ret bfloat %call
164 define bfloat @bf_out_call_multiuse(float %arg) nounwind {
165 ; NO-FP16-SOFT-LABEL: bf_out_call_multiuse:
166 ; NO-FP16-SOFT:  @ %bb.0:
167 ; NO-FP16-SOFT:    mov r4, r0
168 ; NO-FP16-SOFT:    bl bf_inner
169 ; NO-FP16-SOFT:    mov r5, r0
170 ; NO-FP16-SOFT:    mov r0, r4
171 ; NO-FP16-SOFT:    bl other
172 ; NO-FP16-SOFT:    mov r0, r5
173 ; NO-FP16-SOFT:    bl bf16_sink
174 ; NO-FP16-SOFT:    mov r0, r5
176 ; NO-FP16-HARD-LABEL: bf_out_call_multiuse:
177 ; NO-FP16-HARD:  @ %bb.0:
178 ; NO-FP16-HARD:    vmov.f32 s16, s0
179 ; NO-FP16-HARD:    bl bf_inner
180 ; NO-FP16-HARD:    vmov.f32 s18, s0
181 ; NO-FP16-HARD:    vmov.f32 s0, s16
182 ; NO-FP16-HARD:    bl other
183 ; NO-FP16-HARD:    vmov.f32 s0, s18
184 ; NO-FP16-HARD:    bl bf16_sink
185 ; NO-FP16-HARD:    vmov.f32 s0, s18
187 ; FP16-SOFT-LABEL: bf_out_call_multiuse:
188 ; FP16-SOFT:  @ %bb.0:
189 ; FP16-SOFT:    mov r4, r0
190 ; FP16-SOFT:    bl bf_inner
191 ; FP16-SOFT:    mov r5, r0
192 ; FP16-SOFT:    mov r0, r4
193 ; FP16-SOFT:    bl other
194 ; FP16-SOFT:    mov r0, r5
195 ; FP16-SOFT:    bl bf16_sink
196 ; FP16-SOFT:    mov r0, r5
198 ; FP16-HARD-LABEL: bf_out_call_multiuse:
199 ; FP16-HARD:  @ %bb.0:
200 ; FP16-HARD:    vmov.f32 s16, s0
201 ; FP16-HARD:    bl bf_inner
202 ; FP16-HARD:    vmov.f32 s18, s0
203 ; FP16-HARD:    vmov.f32 s0, s16
204 ; FP16-HARD:    bl other
205 ; FP16-HARD:    vmov.f32 s0, s18
206 ; FP16-HARD:    bl bf16_sink
207 ; FP16-HARD:    vmov.f32 s0, s18
208   %call = call bfloat @bf_inner()
209   %call1 = call float @other(float %arg)
210   call void @bf16_sink(bfloat %call)
211   ret bfloat %call