xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/vec_loadsingles.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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(float* 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, float* %p
11  %vecins = insertelement <4 x float> undef, float %tmp1, i32 0
12  %add.ptr = getelementptr float, float* %p, i32 1
13  %tmp5 = load float, float* %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 i64*, i64** undef, align 8
27  %2 = getelementptr inbounds i64, i64* %1, i64 0
28  %3 = load i64, i64* %2
29  %4 = insertelement <4 x i64> undef, i64 %3, i32 0
30  %5 = load i64*, i64** undef, align 8
31  %6 = getelementptr inbounds i64, i64* %5, i64 1
32  %7 = load i64, i64* %6
33  %8 = insertelement <4 x i64> %4, i64 %7, i32 1
34  %9 = shufflevector <4 x i64> %8, <4 x i64> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
35  ret <4 x i64> %9
36}
37
38define <4 x float> @merge_4_floats(float* %ptr) {
39; ALL-LABEL: merge_4_floats:
40; ALL:       # BB#0:
41; ALL-NEXT:    vmovups (%rdi), %xmm0
42; ALL-NEXT:    retq
43  %a = load float, float* %ptr, align 8
44  %vec = insertelement <4 x float> undef, float %a, i32 0
45  %idx1 = getelementptr inbounds float, float* %ptr, i64 1
46  %b = load float, float* %idx1, align 8
47  %vec2 = insertelement <4 x float> %vec, float %b, i32 1
48  %idx3 = getelementptr inbounds float, float* %ptr, i64 2
49  %c = load float, float* %idx3, align 8
50  %vec4 = insertelement <4 x float> %vec2, float %c, i32 2
51  %idx5 = getelementptr inbounds float, float* %ptr, i64 3
52  %d = load float, float* %idx5, align 8
53  %vec6 = insertelement <4 x float> %vec4, float %d, i32 3
54  ret <4 x float> %vec6
55}
56
57; PR21710 ( http://llvm.org/bugs/show_bug.cgi?id=21710 )
58; Make sure that 32-byte vectors are handled efficiently.
59; If the target has slow 32-byte accesses, we should still generate
60; 16-byte loads.
61
62define <8 x float> @merge_8_floats(float* %ptr) {
63; FAST32-LABEL: merge_8_floats:
64; FAST32:       # BB#0:
65; FAST32-NEXT:    vmovups (%rdi), %ymm0
66; FAST32-NEXT:    retq
67;
68; SLOW32-LABEL: merge_8_floats:
69; SLOW32:       # BB#0:
70; SLOW32-NEXT:    vmovups (%rdi), %xmm0
71; SLOW32-NEXT:    vinsertf128 $1, 16(%rdi), %ymm0, %ymm0
72; SLOW32-NEXT:    retq
73  %a = load float, float* %ptr, align 4
74  %vec = insertelement <8 x float> undef, float %a, i32 0
75  %idx1 = getelementptr inbounds float, float* %ptr, i64 1
76  %b = load float, float* %idx1, align 4
77  %vec2 = insertelement <8 x float> %vec, float %b, i32 1
78  %idx3 = getelementptr inbounds float, float* %ptr, i64 2
79  %c = load float, float* %idx3, align 4
80  %vec4 = insertelement <8 x float> %vec2, float %c, i32 2
81  %idx5 = getelementptr inbounds float, float* %ptr, i64 3
82  %d = load float, float* %idx5, align 4
83  %vec6 = insertelement <8 x float> %vec4, float %d, i32 3
84  %idx7 = getelementptr inbounds float, float* %ptr, i64 4
85  %e = load float, float* %idx7, align 4
86  %vec8 = insertelement <8 x float> %vec6, float %e, i32 4
87  %idx9 = getelementptr inbounds float, float* %ptr, i64 5
88  %f = load float, float* %idx9, align 4
89  %vec10 = insertelement <8 x float> %vec8, float %f, i32 5
90  %idx11 = getelementptr inbounds float, float* %ptr, i64 6
91  %g = load float, float* %idx11, align 4
92  %vec12 = insertelement <8 x float> %vec10, float %g, i32 6
93  %idx13 = getelementptr inbounds float, float* %ptr, i64 7
94  %h = load float, float* %idx13, align 4
95  %vec14 = insertelement <8 x float> %vec12, float %h, i32 7
96  ret <8 x float> %vec14
97}
98
99define <4 x double> @merge_4_doubles(double* %ptr) {
100; FAST32-LABEL: merge_4_doubles:
101; FAST32:       # BB#0:
102; FAST32-NEXT:    vmovups (%rdi), %ymm0
103; FAST32-NEXT:    retq
104;
105; SLOW32-LABEL: merge_4_doubles:
106; SLOW32:       # BB#0:
107; SLOW32-NEXT:    vmovups (%rdi), %xmm0
108; SLOW32-NEXT:    vinsertf128 $1, 16(%rdi), %ymm0, %ymm0
109; SLOW32-NEXT:    retq
110  %a = load double, double* %ptr, align 8
111  %vec = insertelement <4 x double> undef, double %a, i32 0
112  %idx1 = getelementptr inbounds double, double* %ptr, i64 1
113  %b = load double, double* %idx1, align 8
114  %vec2 = insertelement <4 x double> %vec, double %b, i32 1
115  %idx3 = getelementptr inbounds double, double* %ptr, i64 2
116  %c = load double, double* %idx3, align 8
117  %vec4 = insertelement <4 x double> %vec2, double %c, i32 2
118  %idx5 = getelementptr inbounds double, double* %ptr, i64 3
119  %d = load double, double* %idx5, align 8
120  %vec6 = insertelement <4 x double> %vec4, double %d, i32 3
121  ret <4 x double> %vec6
122}
123
124; PR21771 ( http://llvm.org/bugs/show_bug.cgi?id=21771 )
125; Recognize and combine consecutive loads even when the
126; first of the combined loads is offset from the base address.
127define <4 x double> @merge_4_doubles_offset(double* %ptr) {
128; FAST32-LABEL: merge_4_doubles_offset:
129; FAST32:       # BB#0:
130; FAST32-NEXT:    vmovups 32(%rdi), %ymm0
131; FAST32-NEXT:    retq
132;
133; SLOW32-LABEL: merge_4_doubles_offset:
134; SLOW32:       # BB#0:
135; SLOW32-NEXT:    vmovups 32(%rdi), %xmm0
136; SLOW32-NEXT:    vinsertf128 $1, 48(%rdi), %ymm0, %ymm0
137; SLOW32-NEXT:    retq
138  %arrayidx4 = getelementptr inbounds double, double* %ptr, i64 4
139  %arrayidx5 = getelementptr inbounds double, double* %ptr, i64 5
140  %arrayidx6 = getelementptr inbounds double, double* %ptr, i64 6
141  %arrayidx7 = getelementptr inbounds double, double* %ptr, i64 7
142  %e = load double, double* %arrayidx4, align 8
143  %f = load double, double* %arrayidx5, align 8
144  %g = load double, double* %arrayidx6, align 8
145  %h = load double, double* %arrayidx7, align 8
146  %vecinit4 = insertelement <4 x double> undef, double %e, i32 0
147  %vecinit5 = insertelement <4 x double> %vecinit4, double %f, i32 1
148  %vecinit6 = insertelement <4 x double> %vecinit5, double %g, i32 2
149  %vecinit7 = insertelement <4 x double> %vecinit6, double %h, i32 3
150  ret <4 x double> %vecinit7
151}
152
153