xref: /llvm-project/llvm/test/CodeGen/X86/vec_loadsingles.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,-slow-unaligned-mem-32 | FileCheck %s --check-prefix=ALL --check-prefix=FAST32
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,+slow-unaligned-mem-32 | FileCheck %s --check-prefix=ALL --check-prefix=SLOW32
4
5define <4 x float> @merge_2_floats(ptr nocapture %p) nounwind readonly {
6; ALL-LABEL: merge_2_floats:
7; ALL:       # %bb.0:
8; ALL-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
9; ALL-NEXT:    retq
10  %tmp1 = load float, ptr %p
11  %vecins = insertelement <4 x float> undef, float %tmp1, i32 0
12  %add.ptr = getelementptr float, ptr %p, i32 1
13  %tmp5 = load float, ptr %add.ptr
14  %vecins7 = insertelement <4 x float> %vecins, float %tmp5, i32 1
15  ret <4 x float> %vecins7
16}
17
18; Test-case generated due to a crash when trying to treat loading the first
19; two i64s of a <4 x i64> as a load of two i32s.
20define <4 x i64> @merge_2_floats_into_4() {
21; ALL-LABEL: merge_2_floats_into_4:
22; ALL:       # %bb.0:
23; ALL-NEXT:    movq (%rax), %rax
24; ALL-NEXT:    vmovups (%rax), %xmm0
25; ALL-NEXT:    retq
26  %1 = load ptr, ptr undef, align 8
27  %2 = load i64, ptr %1
28  %3 = insertelement <4 x i64> undef, i64 %2, i32 0
29  %4 = load ptr, ptr undef, align 8
30  %5 = getelementptr inbounds i64, ptr %4, i64 1
31  %6 = load i64, ptr %5
32  %7 = insertelement <4 x i64> %3, i64 %6, i32 1
33  %8 = shufflevector <4 x i64> %7, <4 x i64> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
34  ret <4 x i64> %8
35}
36
37define <4 x float> @merge_4_floats(ptr %ptr) {
38; ALL-LABEL: merge_4_floats:
39; ALL:       # %bb.0:
40; ALL-NEXT:    vmovups (%rdi), %xmm0
41; ALL-NEXT:    retq
42  %a = load float, ptr %ptr, align 8
43  %vec = insertelement <4 x float> undef, float %a, i32 0
44  %idx1 = getelementptr inbounds float, ptr %ptr, i64 1
45  %b = load float, ptr %idx1, align 8
46  %vec2 = insertelement <4 x float> %vec, float %b, i32 1
47  %idx3 = getelementptr inbounds float, ptr %ptr, i64 2
48  %c = load float, ptr %idx3, align 8
49  %vec4 = insertelement <4 x float> %vec2, float %c, i32 2
50  %idx5 = getelementptr inbounds float, ptr %ptr, i64 3
51  %d = load float, ptr %idx5, align 8
52  %vec6 = insertelement <4 x float> %vec4, float %d, i32 3
53  ret <4 x float> %vec6
54}
55
56; PR21710 ( http://llvm.org/bugs/show_bug.cgi?id=21710 )
57; Make sure that 32-byte vectors are handled efficiently.
58; If the target has slow 32-byte accesses, we should still generate
59; 16-byte loads.
60
61define <8 x float> @merge_8_floats(ptr %ptr) {
62; FAST32-LABEL: merge_8_floats:
63; FAST32:       # %bb.0:
64; FAST32-NEXT:    vmovups (%rdi), %ymm0
65; FAST32-NEXT:    retq
66;
67; SLOW32-LABEL: merge_8_floats:
68; SLOW32:       # %bb.0:
69; SLOW32-NEXT:    vmovups (%rdi), %xmm0
70; SLOW32-NEXT:    vinsertf128 $1, 16(%rdi), %ymm0, %ymm0
71; SLOW32-NEXT:    retq
72  %a = load float, ptr %ptr, align 4
73  %vec = insertelement <8 x float> undef, float %a, i32 0
74  %idx1 = getelementptr inbounds float, ptr %ptr, i64 1
75  %b = load float, ptr %idx1, align 4
76  %vec2 = insertelement <8 x float> %vec, float %b, i32 1
77  %idx3 = getelementptr inbounds float, ptr %ptr, i64 2
78  %c = load float, ptr %idx3, align 4
79  %vec4 = insertelement <8 x float> %vec2, float %c, i32 2
80  %idx5 = getelementptr inbounds float, ptr %ptr, i64 3
81  %d = load float, ptr %idx5, align 4
82  %vec6 = insertelement <8 x float> %vec4, float %d, i32 3
83  %idx7 = getelementptr inbounds float, ptr %ptr, i64 4
84  %e = load float, ptr %idx7, align 4
85  %vec8 = insertelement <8 x float> %vec6, float %e, i32 4
86  %idx9 = getelementptr inbounds float, ptr %ptr, i64 5
87  %f = load float, ptr %idx9, align 4
88  %vec10 = insertelement <8 x float> %vec8, float %f, i32 5
89  %idx11 = getelementptr inbounds float, ptr %ptr, i64 6
90  %g = load float, ptr %idx11, align 4
91  %vec12 = insertelement <8 x float> %vec10, float %g, i32 6
92  %idx13 = getelementptr inbounds float, ptr %ptr, i64 7
93  %h = load float, ptr %idx13, align 4
94  %vec14 = insertelement <8 x float> %vec12, float %h, i32 7
95  ret <8 x float> %vec14
96}
97
98define <4 x double> @merge_4_doubles(ptr %ptr) {
99; FAST32-LABEL: merge_4_doubles:
100; FAST32:       # %bb.0:
101; FAST32-NEXT:    vmovups (%rdi), %ymm0
102; FAST32-NEXT:    retq
103;
104; SLOW32-LABEL: merge_4_doubles:
105; SLOW32:       # %bb.0:
106; SLOW32-NEXT:    vmovups (%rdi), %xmm0
107; SLOW32-NEXT:    vinsertf128 $1, 16(%rdi), %ymm0, %ymm0
108; SLOW32-NEXT:    retq
109  %a = load double, ptr %ptr, align 8
110  %vec = insertelement <4 x double> undef, double %a, i32 0
111  %idx1 = getelementptr inbounds double, ptr %ptr, i64 1
112  %b = load double, ptr %idx1, align 8
113  %vec2 = insertelement <4 x double> %vec, double %b, i32 1
114  %idx3 = getelementptr inbounds double, ptr %ptr, i64 2
115  %c = load double, ptr %idx3, align 8
116  %vec4 = insertelement <4 x double> %vec2, double %c, i32 2
117  %idx5 = getelementptr inbounds double, ptr %ptr, i64 3
118  %d = load double, ptr %idx5, align 8
119  %vec6 = insertelement <4 x double> %vec4, double %d, i32 3
120  ret <4 x double> %vec6
121}
122
123; PR21771 ( http://llvm.org/bugs/show_bug.cgi?id=21771 )
124; Recognize and combine consecutive loads even when the
125; first of the combined loads is offset from the base address.
126define <4 x double> @merge_4_doubles_offset(ptr %ptr) {
127; FAST32-LABEL: merge_4_doubles_offset:
128; FAST32:       # %bb.0:
129; FAST32-NEXT:    vmovups 32(%rdi), %ymm0
130; FAST32-NEXT:    retq
131;
132; SLOW32-LABEL: merge_4_doubles_offset:
133; SLOW32:       # %bb.0:
134; SLOW32-NEXT:    vmovups 32(%rdi), %xmm0
135; SLOW32-NEXT:    vinsertf128 $1, 48(%rdi), %ymm0, %ymm0
136; SLOW32-NEXT:    retq
137  %arrayidx4 = getelementptr inbounds double, ptr %ptr, i64 4
138  %arrayidx5 = getelementptr inbounds double, ptr %ptr, i64 5
139  %arrayidx6 = getelementptr inbounds double, ptr %ptr, i64 6
140  %arrayidx7 = getelementptr inbounds double, ptr %ptr, i64 7
141  %e = load double, ptr %arrayidx4, align 8
142  %f = load double, ptr %arrayidx5, align 8
143  %g = load double, ptr %arrayidx6, align 8
144  %h = load double, ptr %arrayidx7, align 8
145  %vecinit4 = insertelement <4 x double> undef, double %e, i32 0
146  %vecinit5 = insertelement <4 x double> %vecinit4, double %f, i32 1
147  %vecinit6 = insertelement <4 x double> %vecinit5, double %g, i32 2
148  %vecinit7 = insertelement <4 x double> %vecinit6, double %h, i32 3
149  ret <4 x double> %vecinit7
150}
151
152