1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple thumbv8m.main-arm-unknown-eabi --float-abi=soft -mattr=+vfp4d16sp < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VFPV4-SOFT
3; RUN: llc -mtriple thumbv8.1m.main-arm-unknown-eabi --float-abi=soft -mattr=+fullfp16 < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP16-SOFT
4; RUN: llc -mtriple thumbv8m.main-arm-unknown-eabi --float-abi=hard -mattr=+vfp4d16sp < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VFPV4-HARD
5; RUN: llc -mtriple thumbv8.1m.main-arm-unknown-eabi --float-abi=hard -mattr=+fullfp16 < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP16-HARD
6
7target triple = "thumbv8.1m.main-arm-unknown-eabi"
8
9define float @add(float %a, float %b) {
10; CHECK-VFPV4-SOFT-LABEL: add:
11; CHECK-VFPV4-SOFT:       @ %bb.0: @ %entry
12; CHECK-VFPV4-SOFT-NEXT:    vmov s0, r1
13; CHECK-VFPV4-SOFT-NEXT:    vmov s2, r0
14; CHECK-VFPV4-SOFT-NEXT:    vadd.f32 s0, s2, s0
15; CHECK-VFPV4-SOFT-NEXT:    vmov r0, s0
16; CHECK-VFPV4-SOFT-NEXT:    bx lr
17;
18; CHECK-FP16-SOFT-LABEL: add:
19; CHECK-FP16-SOFT:       @ %bb.0: @ %entry
20; CHECK-FP16-SOFT-NEXT:    vmov s0, r1
21; CHECK-FP16-SOFT-NEXT:    vmov s2, r0
22; CHECK-FP16-SOFT-NEXT:    vadd.f32 s0, s2, s0
23; CHECK-FP16-SOFT-NEXT:    vmov r0, s0
24; CHECK-FP16-SOFT-NEXT:    bx lr
25;
26; CHECK-VFPV4-HARD-LABEL: add:
27; CHECK-VFPV4-HARD:       @ %bb.0: @ %entry
28; CHECK-VFPV4-HARD-NEXT:    vadd.f32 s0, s0, s1
29; CHECK-VFPV4-HARD-NEXT:    bx lr
30;
31; CHECK-FP16-HARD-LABEL: add:
32; CHECK-FP16-HARD:       @ %bb.0: @ %entry
33; CHECK-FP16-HARD-NEXT:    vadd.f32 s0, s0, s1
34; CHECK-FP16-HARD-NEXT:    bx lr
35entry:
36  %add = fadd float %a, %b
37  ret float %add
38}
39
40define half @addf16(half %a, half %b) {
41; CHECK-VFPV4-SOFT-LABEL: addf16:
42; CHECK-VFPV4-SOFT:       @ %bb.0: @ %entry
43; CHECK-VFPV4-SOFT-NEXT:    vmov s0, r0
44; CHECK-VFPV4-SOFT-NEXT:    vmov s2, r1
45; CHECK-VFPV4-SOFT-NEXT:    vcvtb.f32.f16 s0, s0
46; CHECK-VFPV4-SOFT-NEXT:    vcvtb.f32.f16 s2, s2
47; CHECK-VFPV4-SOFT-NEXT:    vadd.f32 s0, s0, s2
48; CHECK-VFPV4-SOFT-NEXT:    vcvtb.f16.f32 s0, s0
49; CHECK-VFPV4-SOFT-NEXT:    vmov r0, s0
50; CHECK-VFPV4-SOFT-NEXT:    bx lr
51;
52; CHECK-FP16-SOFT-LABEL: addf16:
53; CHECK-FP16-SOFT:       @ %bb.0: @ %entry
54; CHECK-FP16-SOFT-NEXT:    vmov.f16 s0, r1
55; CHECK-FP16-SOFT-NEXT:    vmov.f16 s2, r0
56; CHECK-FP16-SOFT-NEXT:    vadd.f16 s0, s2, s0
57; CHECK-FP16-SOFT-NEXT:    vmov r0, s0
58; CHECK-FP16-SOFT-NEXT:    bx lr
59;
60; CHECK-VFPV4-HARD-LABEL: addf16:
61; CHECK-VFPV4-HARD:       @ %bb.0: @ %entry
62; CHECK-VFPV4-HARD-NEXT:    vcvtb.f32.f16 s2, s1
63; CHECK-VFPV4-HARD-NEXT:    vcvtb.f32.f16 s0, s0
64; CHECK-VFPV4-HARD-NEXT:    vadd.f32 s0, s0, s2
65; CHECK-VFPV4-HARD-NEXT:    vcvtb.f16.f32 s0, s0
66; CHECK-VFPV4-HARD-NEXT:    bx lr
67;
68; CHECK-FP16-HARD-LABEL: addf16:
69; CHECK-FP16-HARD:       @ %bb.0: @ %entry
70; CHECK-FP16-HARD-NEXT:    vadd.f16 s0, s0, s1
71; CHECK-FP16-HARD-NEXT:    bx lr
72entry:
73  %add = fadd half %a, %b
74  ret half %add
75}
76
77define half @load_i16(i16 *%hp) {
78; CHECK-VFPV4-SOFT-LABEL: load_i16:
79; CHECK-VFPV4-SOFT:       @ %bb.0: @ %entry
80; CHECK-VFPV4-SOFT-NEXT:    vmov.f32 s0, #1.000000e+00
81; CHECK-VFPV4-SOFT-NEXT:    ldrh r0, [r0]
82; CHECK-VFPV4-SOFT-NEXT:    vmov s2, r0
83; CHECK-VFPV4-SOFT-NEXT:    vcvtb.f32.f16 s2, s2
84; CHECK-VFPV4-SOFT-NEXT:    vadd.f32 s0, s2, s0
85; CHECK-VFPV4-SOFT-NEXT:    vcvtb.f16.f32 s0, s0
86; CHECK-VFPV4-SOFT-NEXT:    vmov r0, s0
87; CHECK-VFPV4-SOFT-NEXT:    bx lr
88;
89; CHECK-FP16-SOFT-LABEL: load_i16:
90; CHECK-FP16-SOFT:       @ %bb.0: @ %entry
91; CHECK-FP16-SOFT-NEXT:    vldr.16 s2, [r0]
92; CHECK-FP16-SOFT-NEXT:    vmov.f16 s0, #1.000000e+00
93; CHECK-FP16-SOFT-NEXT:    vadd.f16 s0, s2, s0
94; CHECK-FP16-SOFT-NEXT:    vmov r0, s0
95; CHECK-FP16-SOFT-NEXT:    bx lr
96;
97; CHECK-VFPV4-HARD-LABEL: load_i16:
98; CHECK-VFPV4-HARD:       @ %bb.0: @ %entry
99; CHECK-VFPV4-HARD-NEXT:    vmov.f32 s0, #1.000000e+00
100; CHECK-VFPV4-HARD-NEXT:    ldrh r0, [r0]
101; CHECK-VFPV4-HARD-NEXT:    vmov s2, r0
102; CHECK-VFPV4-HARD-NEXT:    vcvtb.f32.f16 s2, s2
103; CHECK-VFPV4-HARD-NEXT:    vadd.f32 s0, s2, s0
104; CHECK-VFPV4-HARD-NEXT:    vcvtb.f16.f32 s0, s0
105; CHECK-VFPV4-HARD-NEXT:    bx lr
106;
107; CHECK-FP16-HARD-LABEL: load_i16:
108; CHECK-FP16-HARD:       @ %bb.0: @ %entry
109; CHECK-FP16-HARD-NEXT:    vldr.16 s2, [r0]
110; CHECK-FP16-HARD-NEXT:    vmov.f16 s0, #1.000000e+00
111; CHECK-FP16-HARD-NEXT:    vadd.f16 s0, s2, s0
112; CHECK-FP16-HARD-NEXT:    bx lr
113entry:
114  %h = load i16, i16 *%hp, align 2
115  %hc = bitcast i16 %h to half
116  %add = fadd half %hc, 1.0
117  ret half %add
118}
119
120define i16 @load_f16(half *%hp) {
121; CHECK-LABEL: load_f16:
122; CHECK:       @ %bb.0: @ %entry
123; CHECK-NEXT:    ldrh r0, [r0]
124; CHECK-NEXT:    adds r0, #1
125; CHECK-NEXT:    bx lr
126entry:
127  %h = load half, half *%hp, align 2
128  %hc = bitcast half %h to i16
129  %add = add i16 %hc, 1
130  ret i16 %add
131}
132
133define half @constcall() {
134; CHECK-VFPV4-SOFT-LABEL: constcall:
135; CHECK-VFPV4-SOFT:       @ %bb.0: @ %entry
136; CHECK-VFPV4-SOFT-NEXT:    mov.w r0, #18688
137; CHECK-VFPV4-SOFT-NEXT:    b ccc
138;
139; CHECK-FP16-SOFT-LABEL: constcall:
140; CHECK-FP16-SOFT:       @ %bb.0: @ %entry
141; CHECK-FP16-SOFT-NEXT:    mov.w r0, #18688
142; CHECK-FP16-SOFT-NEXT:    b ccc
143;
144; CHECK-VFPV4-HARD-LABEL: constcall:
145; CHECK-VFPV4-HARD:       @ %bb.0: @ %entry
146; CHECK-VFPV4-HARD-NEXT:    vldr s0, .LCPI4_0
147; CHECK-VFPV4-HARD-NEXT:    b ccc
148; CHECK-VFPV4-HARD-NEXT:    .p2align 2
149; CHECK-VFPV4-HARD-NEXT:  @ %bb.1:
150; CHECK-VFPV4-HARD-NEXT:  .LCPI4_0:
151; CHECK-VFPV4-HARD-NEXT:    .long 0x00004900 @ float 2.61874657E-41
152;
153; CHECK-FP16-HARD-LABEL: constcall:
154; CHECK-FP16-HARD:       @ %bb.0: @ %entry
155; CHECK-FP16-HARD-NEXT:    vmov.f16 s0, #1.000000e+01
156; CHECK-FP16-HARD-NEXT:    b ccc
157entry:
158  %call = tail call fast half @ccc(half 0xH4900)
159  ret half %call
160}
161
162define half @constret() {
163; CHECK-VFPV4-SOFT-LABEL: constret:
164; CHECK-VFPV4-SOFT:       @ %bb.0: @ %entry
165; CHECK-VFPV4-SOFT-NEXT:    mov.w r0, #18688
166; CHECK-VFPV4-SOFT-NEXT:    bx lr
167;
168; CHECK-FP16-SOFT-LABEL: constret:
169; CHECK-FP16-SOFT:       @ %bb.0: @ %entry
170; CHECK-FP16-SOFT-NEXT:    vmov.f16 s0, #1.000000e+01
171; CHECK-FP16-SOFT-NEXT:    vmov r0, s0
172; CHECK-FP16-SOFT-NEXT:    bx lr
173;
174; CHECK-VFPV4-HARD-LABEL: constret:
175; CHECK-VFPV4-HARD:       @ %bb.0: @ %entry
176; CHECK-VFPV4-HARD-NEXT:    vldr s0, .LCPI5_0
177; CHECK-VFPV4-HARD-NEXT:    bx lr
178; CHECK-VFPV4-HARD-NEXT:    .p2align 2
179; CHECK-VFPV4-HARD-NEXT:  @ %bb.1:
180; CHECK-VFPV4-HARD-NEXT:  .LCPI5_0:
181; CHECK-VFPV4-HARD-NEXT:    .long 0x00004900 @ float 2.61874657E-41
182;
183; CHECK-FP16-HARD-LABEL: constret:
184; CHECK-FP16-HARD:       @ %bb.0: @ %entry
185; CHECK-FP16-HARD-NEXT:    vmov.f16 s0, #1.000000e+01
186; CHECK-FP16-HARD-NEXT:    bx lr
187entry:
188  ret half 0xH4900
189}
190
191declare half @ccc(half)
192