xref: /llvm-project/llvm/test/CodeGen/ARM/constantfp.ll (revision 7432fb2c784691eb85b5996e0922b55389b43b6e)
1; RUN: llc -mtriple=armv7 -mattr=+neon -mcpu=swift %s -o - | FileCheck %s
2; RUN: llc -mtriple=armv7 -mattr=+neon -mcpu=cortex-a8 %s -o - | FileCheck --check-prefix=CHECK-NONEONFP %s
3; RUN: llc -mtriple=armv7 -mattr=-neon -mcpu=cortex-a8 %s -o - | FileCheck --check-prefix=CHECK-NONEON %s
4
5; RUN: llc -mtriple=thumbv7m -mcpu=cortex-m4 %s -o - \
6; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s
7
8; RUN: llc -mtriple=thumbv7m -mattr=+execute-only -mcpu=cortex-m4 %s -o - \
9; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE %s
10
11; RUN: llc -mtriple=thumbv7meb -mattr=+execute-only -mcpu=cortex-m4 %s -o - \
12; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE  --check-prefix=CHECK-XO-DOUBLE-BE-FPREGS %s
13
14; RUN: llc -mtriple=thumbv7meb -mattr=+execute-only -mcpu=cortex-m3 %s -o - \
15; RUN: | FileCheck --check-prefix=CHECK-XO-DOUBLE-BE %s
16
17; RUN: llc -mtriple=thumbv7m -mattr=+execute-only -mcpu=cortex-m4 -relocation-model=ropi %s -o - \
18; RUN: | FileCheck --check-prefix=CHECK-XO-ROPI %s
19
20; RUN: llc -mtriple=thumbv8m.main -mattr=fp-armv8 %s -o - \
21; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s
22
23; RUN: llc -mtriple=thumbv8m.main -mattr=+execute-only -mattr=fp-armv8 %s -o - \
24; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE %s
25
26; RUN: llc -mtriple=thumbv8m.maineb -mattr=+execute-only -mattr=fp-armv8 %s -o - \
27; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE %s
28
29; RUN: llc -mtriple=thumbv8m.main -mattr=+execute-only -mattr=fp-armv8 -relocation-model=ropi %s -o - \
30; RUN: | FileCheck --check-prefix=CHECK-XO-ROPI %s
31
32define arm_aapcs_vfpcc float @test_vmov_f32() {
33; CHECK-LABEL: test_vmov_f32:
34; CHECK: vmov.f32 d0, #1.0
35
36; CHECK-NONEONFP: vmov.f32 s0, #1.0
37  ret float 1.0
38}
39
40define arm_aapcs_vfpcc float @test_vmov_imm() {
41; CHECK-LABEL: test_vmov_imm:
42; CHECK: vmov.i32 d0, #0
43
44; CHECK-NONEON-LABEL: test_vmov_imm:
45; CHECK-NONEON: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}
46
47; CHECK-NO-XO-LABEL: test_vmov_imm:
48; CHECK-NO-XO: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}
49
50; CHECK-XO-FLOAT-LABEL: test_vmov_imm:
51; CHECK-XO-FLOAT: movs [[REG:r[0-9]+]], #0
52; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]
53; CHECK-XO-FLOAT-NOT: vldr
54  ret float 0.0
55}
56
57define arm_aapcs_vfpcc float @test_vmvn_imm() {
58; CHECK-LABEL: test_vmvn_imm:
59; CHECK: vmvn.i32 d0, #0xb0000000
60
61; CHECK-NONEON-LABEL: test_vmvn_imm:
62; CHECK-NONEON: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}
63
64; CHECK-NO-XO-LABEL: test_vmvn_imm:
65; CHECK-NO-XO: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}
66
67; CHECK-XO-FLOAT-LABEL: test_vmvn_imm:
68; CHECK-XO-FLOAT: mvn [[REG:r[0-9]+]], #-1342177280
69; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]
70; CHECK-XO-FLOAT-NOT: vldr
71  ret float 8589934080.0
72}
73
74define arm_aapcs_vfpcc double @test_vmov_f64() {
75; CHECK-LABEL: test_vmov_f64:
76; CHECK: vmov.f64 d0, #1.0
77
78; CHECK-NONEON-LABEL: test_vmov_f64:
79; CHECK-NONEON: vmov.f64 d0, #1.0
80
81  ret double 1.0
82}
83
84define arm_aapcs_vfpcc double @test_vmov_double_imm() {
85; CHECK-LABEL: test_vmov_double_imm:
86; CHECK: vmov.i32 d0, #0
87
88; CHECK-NONEON-LABEL: test_vmov_double_imm:
89; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
90
91; CHECK-NO-XO-LABEL: test_vmov_double_imm:
92; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
93
94; CHECK-XO-DOUBLE-LABEL: test_vmov_double_imm:
95; CHECK-XO-DOUBLE: movs [[REG:r[0-9]+]], #0
96; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG]], [[REG]]
97; CHECK-XO-DOUBLE-NOT: vldr
98
99; CHECK-XO-DOUBLE-BE-LABEL: test_vmov_double_imm:
100; CHECK-XO-DOUBLE-BE-FPREGS: movs [[REG:r[0-9]+]], #0
101; CHECK-XO-DOUBLE-BE-FPREGS: vmov {{d[0-9]+}}, [[REG]], [[REG]]
102; CHECK-XO-DOUBLE-NOT: vldr
103  ret double 0.0
104}
105
106define arm_aapcs_vfpcc double @test_vmvn_double_imm() {
107; CHECK-LABEL: test_vmvn_double_imm:
108; CHECK: vmvn.i32 d0, #0xb0000000
109
110; CHECK-NONEON-LABEL: test_vmvn_double_imm:
111; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
112
113; CHECK-NO-XO-LABEL: test_vmvn_double_imm:
114; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
115
116; CHECK-XO-DOUBLE-LABEL: test_vmvn_double_imm:
117; CHECK-XO-DOUBLE: mvn [[REG:r[0-9]+]], #-1342177280
118; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG]], [[REG]]
119; CHECK-XO-DOUBLE-NOT: vldr
120
121; CHECK-XO-DOUBLE-BE-LABEL: test_vmvn_double_imm:
122; CHECK-XO-DOUBLE-BE-FPREGS: mvn [[REG:r[0-9]+]], #-1342177280
123; CHECK-XO-DOUBLE-BE-FPREGS: vmov {{d[0-9]+}}, [[REG]], [[REG]]
124; CHECK-XO-DOUBLE-BE-NOT: vldr
125  ret double 0x4fffffff4fffffff
126}
127
128; Make sure we don't ignore the high half of 64-bit values when deciding whether
129; a vmov/vmvn is possible.
130define arm_aapcs_vfpcc double @test_notvmvn_double_imm() {
131; CHECK-LABEL: test_notvmvn_double_imm:
132; CHECK: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
133
134; CHECK-NONEON-LABEL: test_notvmvn_double_imm:
135; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
136
137; CHECK-NO-XO-LABEL: test_notvmvn_double_imm:
138; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
139
140; CHECK-XO-DOUBLE-LABEL: test_notvmvn_double_imm:
141; CHECK-XO-DOUBLE: mvn [[REG1:r[0-9]+]], #-1342177280
142; CHECK-XO-DOUBLE: mov.w [[REG2:r[0-9]+]], #-1
143; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]
144; CHECK-XO-DOUBLE-NOT: vldr
145
146; CHECK-XO-DOUBLE-BE-LABEL: test_notvmvn_double_imm:
147; CHECK-XO-DOUBLE-BE: mvn [[REG1:r[0-9]+]], #-1342177280
148; CHECK-XO-DOUBLE-BE: mov.w [[REG2:r[0-9]+]], #-1
149; CHECK-XO-DOUBLE-BE-FPREGS: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]
150; CHECK-XO-DOUBLE-BE-NOT: vldr
151  ret double 0x4fffffffffffffff
152}
153
154define arm_aapcs_vfpcc float @lower_const_f32_xo() {
155; CHECK-NO-XO-LABEL: lower_const_f32_xo
156; CHECK-NO-XO: vldr {{s[0-9]+}}, {{.?LCPI[0-9]+_[0-9]+}}
157
158; CHECK-XO-FLOAT-LABEL: lower_const_f32_xo
159; CHECK-XO-FLOAT: movw [[REG:r[0-9]+]], #29884
160; CHECK-XO-FLOAT: movt [[REG]], #16083
161; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]
162; CHECK-XO-FLOAT-NOT: vldr
163  ret float 0x3FDA6E9780000000
164}
165
166define arm_aapcs_vfpcc double @lower_const_f64_xo() {
167; CHECK-NO-XO-LABEL: lower_const_f64_xo
168; CHECK-NO-XO: vldr {{d[0-9]+}}, {{.?LCPI[0-9]+_[0-9]+}}
169
170; CHECK-XO-DOUBLE-LABEL: lower_const_f64_xo
171; CHECK-XO-DOUBLE: movw [[REG1:r[0-9]+]], #6291
172; CHECK-XO-DOUBLE: movw [[REG2:r[0-9]+]], #27263
173; CHECK-XO-DOUBLE: movt [[REG1]], #16340
174; CHECK-XO-DOUBLE: movt [[REG2]], #29884
175; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]
176; CHECK-XO-DOUBLE-NOT: vldr
177
178; CHECK-XO-DOUBLE-BE-LABEL: lower_const_f64_xo
179; CHECK-XO-DOUBLE-BE: movw [[REG1:r[0-9]+]], #6291
180; CHECK-XO-DOUBLE-BE: movw [[REG2:r[0-9]+]], #27263
181; CHECK-XO-DOUBLE-BE: movt [[REG1]], #16340
182; CHECK-XO-DOUBLE-BE: movt [[REG2]], #29884
183; CHECK-XO-DOUBLE-BE-FPREGS: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]
184; CHECK-XO-DOUBLE-BE-NOT: vldr
185  ret double 3.140000e-01
186}
187
188; This is a target independent optimization, performed by the
189; DAG Combiner, which promotes floating point literals into
190; constant pools:
191;
192; (a cond b) ? 1.0f : 2.0f -> load (ConstPoolAddr + ((a cond b) ? 0 : 4)
193;
194; We need to make sure that the constant pools are placed in
195; the data section when generating execute-only code:
196
197define arm_aapcs_vfpcc float @lower_fpconst_select(float %f) {
198
199; CHECK-NO-XO-LABEL: lower_fpconst_select
200; CHECK-NO-XO: adr [[REG:r[0-9]+]], [[LABEL:.?LCPI[0-9]+_[0-9]+]]
201; CHECK-NO-XO: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}}
202; CHECK-NO-XO-NOT: .rodata
203; CHECK-NO-XO: [[LABEL]]:
204; CHECK-NO-XO: .long   0x4f9502f9
205; CHECK-NO-XO: .long   0x4dee6b28
206
207; CHECK-XO-FLOAT-LABEL: lower_fpconst_select
208; CHECK-XO-FLOAT: movw [[REG:r[0-9]+]], :lower16:[[LABEL:.?LCP[0-9]+_[0-9]+]]
209; CHECK-XO-FLOAT: movt [[REG]], :upper16:[[LABEL]]
210; CHECK-XO-FLOAT: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}}
211; CHECK-XO-FLOAT: .rodata
212; CHECK-XO-FLOAT-NOT: .text
213; CHECK-XO-FLOAT: [[LABEL]]:
214; CHECK-XO-FLOAT: .long   0x4f9502f9
215; CHECK-XO-FLOAT: .long   0x4dee6b28
216
217; CHECK-XO-ROPI-LABEL: lower_fpconst_select
218; CHECK-XO-ROPI: movw [[REG:r[0-9]+]], :lower16:([[LABEL1:.?LCP[0-9]+_[0-9]+]]-([[LABEL2:.?LPC[0-9]+_[0-9]+]]+4))
219; CHECK-XO-ROPI: movt [[REG]], :upper16:([[LABEL1]]-([[LABEL2]]+4))
220; CHECK-XO-ROPI: [[LABEL2]]:
221; CHECK-XO-ROPI: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}}
222; CHECK-XO-ROPI: .rodata
223; CHECK-XO-ROPI-NOT: .text
224; CHECK-XO-ROPI: [[LABEL1]]:
225; CHECK-XO-ROPI: .long   0x4f9502f9
226; CHECK-XO-ROPI: .long   0x4dee6b28
227
228  %cmp = fcmp nnan oeq float %f, 0.000000e+00
229  %sel = select i1 %cmp, float 5.000000e+08, float 5.000000e+09
230  ret float %sel
231}
232