1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=small < %s | FileCheck %s
3; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=large < %s | FileCheck %s --check-prefix=LARGE
4; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=small -mattr=avx < %s | FileCheck %s --check-prefix=AVX
5; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=large -mattr=avx < %s | FileCheck %s --check-prefix=LARGE_AVX
6; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=small -mattr=avx512f < %s | FileCheck %s --check-prefix=AVX
7; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=large -mattr=avx512f < %s | FileCheck %s --check-prefix=LARGE_AVX
8
9; This large code mode shouldn't mean anything on x86 but it used to
10; generate 64-bit only instructions and asserted in the encoder.
11; -show-mc-encoding here to assert if this breaks again.
12; RUN: llc -mtriple=i686-apple-darwin -fast-isel -code-model=large -mattr=sse2 -show-mc-encoding < %s | FileCheck %s --check-prefix=X86-LARGE
13
14; Make sure fast isel uses rip-relative addressing for the small code model.
15define float @constpool_float(float %x) {
16; CHECK-LABEL: constpool_float:
17; CHECK:       ## %bb.0:
18; CHECK-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
19; CHECK-NEXT:    addss %xmm1, %xmm0
20; CHECK-NEXT:    retq
21;
22; LARGE-LABEL: constpool_float:
23; LARGE:       ## %bb.0:
24; LARGE-NEXT:    movabsq $LCPI0_0, %rax
25; LARGE-NEXT:    addss (%rax), %xmm0
26; LARGE-NEXT:    retq
27;
28; AVX-LABEL: constpool_float:
29; AVX:       ## %bb.0:
30; AVX-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
31; AVX-NEXT:    vaddss %xmm1, %xmm0, %xmm0
32; AVX-NEXT:    retq
33;
34; LARGE_AVX-LABEL: constpool_float:
35; LARGE_AVX:       ## %bb.0:
36; LARGE_AVX-NEXT:    movabsq $LCPI0_0, %rax
37; LARGE_AVX-NEXT:    vaddss (%rax), %xmm0, %xmm0
38; LARGE_AVX-NEXT:    retq
39;
40; X86-LARGE-LABEL: constpool_float:
41; X86-LARGE:       ## %bb.0:
42; X86-LARGE-NEXT:    pushl %eax ## encoding: [0x50]
43; X86-LARGE-NEXT:    .cfi_def_cfa_offset 8
44; X86-LARGE-NEXT:    movss {{[0-9]+}}(%esp), %xmm0 ## encoding: [0xf3,0x0f,0x10,0x44,0x24,0x08]
45; X86-LARGE-NEXT:    ## xmm0 = mem[0],zero,zero,zero
46; X86-LARGE-NEXT:    addss LCPI0_0, %xmm0 ## encoding: [0xf3,0x0f,0x58,0x05,A,A,A,A]
47; X86-LARGE-NEXT:    ## fixup A - offset: 4, value: LCPI0_0, kind: FK_Data_4
48; X86-LARGE-NEXT:    movss %xmm0, (%esp) ## encoding: [0xf3,0x0f,0x11,0x04,0x24]
49; X86-LARGE-NEXT:    flds (%esp) ## encoding: [0xd9,0x04,0x24]
50; X86-LARGE-NEXT:    popl %eax ## encoding: [0x58]
51; X86-LARGE-NEXT:    retl ## encoding: [0xc3]
52
53  %1 = fadd float %x, 16.50e+01
54  ret float %1
55}
56
57define double @constpool_double(double %x) nounwind {
58; CHECK-LABEL: constpool_double:
59; CHECK:       ## %bb.0:
60; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
61; CHECK-NEXT:    addsd %xmm1, %xmm0
62; CHECK-NEXT:    retq
63;
64; LARGE-LABEL: constpool_double:
65; LARGE:       ## %bb.0:
66; LARGE-NEXT:    movabsq $LCPI1_0, %rax
67; LARGE-NEXT:    addsd (%rax), %xmm0
68; LARGE-NEXT:    retq
69;
70; AVX-LABEL: constpool_double:
71; AVX:       ## %bb.0:
72; AVX-NEXT:    vmovsd {{.*#+}} xmm1 = mem[0],zero
73; AVX-NEXT:    vaddsd %xmm1, %xmm0, %xmm0
74; AVX-NEXT:    retq
75;
76; LARGE_AVX-LABEL: constpool_double:
77; LARGE_AVX:       ## %bb.0:
78; LARGE_AVX-NEXT:    movabsq $LCPI1_0, %rax
79; LARGE_AVX-NEXT:    vaddsd (%rax), %xmm0, %xmm0
80; LARGE_AVX-NEXT:    retq
81;
82; X86-LARGE-LABEL: constpool_double:
83; X86-LARGE:       ## %bb.0:
84; X86-LARGE-NEXT:    subl $12, %esp ## encoding: [0x83,0xec,0x0c]
85; X86-LARGE-NEXT:    movsd {{[0-9]+}}(%esp), %xmm0 ## encoding: [0xf2,0x0f,0x10,0x44,0x24,0x10]
86; X86-LARGE-NEXT:    ## xmm0 = mem[0],zero
87; X86-LARGE-NEXT:    addsd LCPI1_0, %xmm0 ## encoding: [0xf2,0x0f,0x58,0x05,A,A,A,A]
88; X86-LARGE-NEXT:    ## fixup A - offset: 4, value: LCPI1_0, kind: FK_Data_4
89; X86-LARGE-NEXT:    movsd %xmm0, (%esp) ## encoding: [0xf2,0x0f,0x11,0x04,0x24]
90; X86-LARGE-NEXT:    fldl (%esp) ## encoding: [0xdd,0x04,0x24]
91; X86-LARGE-NEXT:    addl $12, %esp ## encoding: [0x83,0xc4,0x0c]
92; X86-LARGE-NEXT:    retl ## encoding: [0xc3]
93
94  %1 = fadd double %x, 8.500000e-01
95  ret double %1
96}
97
98define void @constpool_float_no_fp_args(float* %x) nounwind {
99; CHECK-LABEL: constpool_float_no_fp_args:
100; CHECK:       ## %bb.0:
101; CHECK-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
102; CHECK-NEXT:    addss (%rdi), %xmm0
103; CHECK-NEXT:    movss %xmm0, (%rdi)
104; CHECK-NEXT:    retq
105;
106; LARGE-LABEL: constpool_float_no_fp_args:
107; LARGE:       ## %bb.0:
108; LARGE-NEXT:    movabsq $LCPI2_0, %rax
109; LARGE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
110; LARGE-NEXT:    addss (%rdi), %xmm0
111; LARGE-NEXT:    movss %xmm0, (%rdi)
112; LARGE-NEXT:    retq
113;
114; AVX-LABEL: constpool_float_no_fp_args:
115; AVX:       ## %bb.0:
116; AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
117; AVX-NEXT:    vaddss (%rdi), %xmm0, %xmm0
118; AVX-NEXT:    vmovss %xmm0, (%rdi)
119; AVX-NEXT:    retq
120;
121; LARGE_AVX-LABEL: constpool_float_no_fp_args:
122; LARGE_AVX:       ## %bb.0:
123; LARGE_AVX-NEXT:    movabsq $LCPI2_0, %rax
124; LARGE_AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
125; LARGE_AVX-NEXT:    vaddss (%rdi), %xmm0, %xmm0
126; LARGE_AVX-NEXT:    vmovss %xmm0, (%rdi)
127; LARGE_AVX-NEXT:    retq
128;
129; X86-LARGE-LABEL: constpool_float_no_fp_args:
130; X86-LARGE:       ## %bb.0:
131; X86-LARGE-NEXT:    movl {{[0-9]+}}(%esp), %eax ## encoding: [0x8b,0x44,0x24,0x04]
132; X86-LARGE-NEXT:    movss LCPI2_0, %xmm0 ## encoding: [0xf3,0x0f,0x10,0x05,A,A,A,A]
133; X86-LARGE-NEXT:    ## fixup A - offset: 4, value: LCPI2_0, kind: FK_Data_4
134; X86-LARGE-NEXT:    ## xmm0 = mem[0],zero,zero,zero
135; X86-LARGE-NEXT:    addss (%eax), %xmm0 ## encoding: [0xf3,0x0f,0x58,0x00]
136; X86-LARGE-NEXT:    movss %xmm0, (%eax) ## encoding: [0xf3,0x0f,0x11,0x00]
137; X86-LARGE-NEXT:    retl ## encoding: [0xc3]
138  %a = load float, float* %x
139  %b = fadd float %a, 16.50e+01
140  store float %b, float* %x
141  ret void
142}
143
144define void @constpool_double_no_fp_args(double* %x) nounwind {
145; CHECK-LABEL: constpool_double_no_fp_args:
146; CHECK:       ## %bb.0:
147; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
148; CHECK-NEXT:    addsd (%rdi), %xmm0
149; CHECK-NEXT:    movsd %xmm0, (%rdi)
150; CHECK-NEXT:    retq
151;
152; LARGE-LABEL: constpool_double_no_fp_args:
153; LARGE:       ## %bb.0:
154; LARGE-NEXT:    movabsq $LCPI3_0, %rax
155; LARGE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
156; LARGE-NEXT:    addsd (%rdi), %xmm0
157; LARGE-NEXT:    movsd %xmm0, (%rdi)
158; LARGE-NEXT:    retq
159;
160; AVX-LABEL: constpool_double_no_fp_args:
161; AVX:       ## %bb.0:
162; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
163; AVX-NEXT:    vaddsd (%rdi), %xmm0, %xmm0
164; AVX-NEXT:    vmovsd %xmm0, (%rdi)
165; AVX-NEXT:    retq
166;
167; LARGE_AVX-LABEL: constpool_double_no_fp_args:
168; LARGE_AVX:       ## %bb.0:
169; LARGE_AVX-NEXT:    movabsq $LCPI3_0, %rax
170; LARGE_AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
171; LARGE_AVX-NEXT:    vaddsd (%rdi), %xmm0, %xmm0
172; LARGE_AVX-NEXT:    vmovsd %xmm0, (%rdi)
173; LARGE_AVX-NEXT:    retq
174;
175; X86-LARGE-LABEL: constpool_double_no_fp_args:
176; X86-LARGE:       ## %bb.0:
177; X86-LARGE-NEXT:    movl {{[0-9]+}}(%esp), %eax ## encoding: [0x8b,0x44,0x24,0x04]
178; X86-LARGE-NEXT:    movsd LCPI3_0, %xmm0 ## encoding: [0xf2,0x0f,0x10,0x05,A,A,A,A]
179; X86-LARGE-NEXT:    ## fixup A - offset: 4, value: LCPI3_0, kind: FK_Data_4
180; X86-LARGE-NEXT:    ## xmm0 = mem[0],zero
181; X86-LARGE-NEXT:    addsd (%eax), %xmm0 ## encoding: [0xf2,0x0f,0x58,0x00]
182; X86-LARGE-NEXT:    movsd %xmm0, (%eax) ## encoding: [0xf2,0x0f,0x11,0x00]
183; X86-LARGE-NEXT:    retl ## encoding: [0xc3]
184  %a = load double, double* %x
185  %b = fadd double %a, 8.500000e-01
186  store double %b, double* %x
187  ret void
188}
189