1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -passes=sandbox-vectorizer -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
4 define void @store_load(ptr %ptr) {
5 ; CHECK-LABEL: define void @store_load(
6 ; CHECK-SAME: ptr [[PTR:%.*]]) {
7 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
8 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
9 ; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
10 ; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4
11 ; CHECK-NEXT: ret void
13 %ptr0 = getelementptr float, ptr %ptr, i32 0
14 %ptr1 = getelementptr float, ptr %ptr, i32 1
15 %ld0 = load float, ptr %ptr0
16 %ld1 = load float, ptr %ptr1
17 store float %ld0, ptr %ptr0
18 store float %ld1, ptr %ptr1
23 define void @store_fpext_load(ptr %ptr) {
24 ; CHECK-LABEL: define void @store_fpext_load(
25 ; CHECK-SAME: ptr [[PTR:%.*]]) {
26 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
27 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
28 ; CHECK-NEXT: [[PTRD0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
29 ; CHECK-NEXT: [[PTRD1:%.*]] = getelementptr double, ptr [[PTR]], i32 1
30 ; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
31 ; CHECK-NEXT: [[VCAST:%.*]] = fpext <2 x float> [[VECL]] to <2 x double>
32 ; CHECK-NEXT: store <2 x double> [[VCAST]], ptr [[PTRD0]], align 8
33 ; CHECK-NEXT: ret void
35 %ptr0 = getelementptr float, ptr %ptr, i32 0
36 %ptr1 = getelementptr float, ptr %ptr, i32 1
37 %ptrd0 = getelementptr double, ptr %ptr, i32 0
38 %ptrd1 = getelementptr double, ptr %ptr, i32 1
39 %ld0 = load float, ptr %ptr0
40 %ld1 = load float, ptr %ptr1
41 %fpext0 = fpext float %ld0 to double
42 %fpext1 = fpext float %ld1 to double
43 store double %fpext0, ptr %ptrd0
44 store double %fpext1, ptr %ptrd1
48 define void @store_fcmp_zext_load(ptr %ptr) {
49 ; CHECK-LABEL: define void @store_fcmp_zext_load(
50 ; CHECK-SAME: ptr [[PTR:%.*]]) {
51 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
52 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
53 ; CHECK-NEXT: [[PTRB0:%.*]] = getelementptr i32, ptr [[PTR]], i32 0
54 ; CHECK-NEXT: [[PTRB1:%.*]] = getelementptr i32, ptr [[PTR]], i32 1
55 ; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
56 ; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
57 ; CHECK-NEXT: [[VCMP:%.*]] = fcmp ogt <2 x float> [[VECL]], [[VECL1]]
58 ; CHECK-NEXT: [[VCAST:%.*]] = zext <2 x i1> [[VCMP]] to <2 x i32>
59 ; CHECK-NEXT: store <2 x i32> [[VCAST]], ptr [[PTRB0]], align 4
60 ; CHECK-NEXT: ret void
62 %ptr0 = getelementptr float, ptr %ptr, i32 0
63 %ptr1 = getelementptr float, ptr %ptr, i32 1
64 %ptrb0 = getelementptr i32, ptr %ptr, i32 0
65 %ptrb1 = getelementptr i32, ptr %ptr, i32 1
66 %ldB0 = load float, ptr %ptr0
67 %ldB1 = load float, ptr %ptr1
68 %ldA0 = load float, ptr %ptr0
69 %ldA1 = load float, ptr %ptr1
70 %fcmp0 = fcmp ogt float %ldA0, %ldB0
71 %fcmp1 = fcmp ogt float %ldA1, %ldB1
72 %zext0 = zext i1 %fcmp0 to i32
73 %zext1 = zext i1 %fcmp1 to i32
74 store i32 %zext0, ptr %ptrb0
75 store i32 %zext1, ptr %ptrb1
79 define void @store_fadd_load(ptr %ptr) {
80 ; CHECK-LABEL: define void @store_fadd_load(
81 ; CHECK-SAME: ptr [[PTR:%.*]]) {
82 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
83 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
84 ; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
85 ; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
86 ; CHECK-NEXT: [[VEC:%.*]] = fadd <2 x float> [[VECL]], [[VECL1]]
87 ; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4
88 ; CHECK-NEXT: ret void
90 %ptr0 = getelementptr float, ptr %ptr, i32 0
91 %ptr1 = getelementptr float, ptr %ptr, i32 1
92 %ldA0 = load float, ptr %ptr0
93 %ldA1 = load float, ptr %ptr1
94 %ldB0 = load float, ptr %ptr0
95 %ldB1 = load float, ptr %ptr1
96 %fadd0 = fadd float %ldA0, %ldB0
97 %fadd1 = fadd float %ldA1, %ldB1
98 store float %fadd0, ptr %ptr0
99 store float %fadd1, ptr %ptr1
103 define void @store_fneg_load(ptr %ptr) {
104 ; CHECK-LABEL: define void @store_fneg_load(
105 ; CHECK-SAME: ptr [[PTR:%.*]]) {
106 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
107 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
108 ; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
109 ; CHECK-NEXT: [[VEC:%.*]] = fneg <2 x float> [[VECL]]
110 ; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4
111 ; CHECK-NEXT: ret void
113 %ptr0 = getelementptr float, ptr %ptr, i32 0
114 %ptr1 = getelementptr float, ptr %ptr, i32 1
115 %ld0 = load float, ptr %ptr0
116 %ld1 = load float, ptr %ptr1
117 %fneg0 = fneg float %ld0
118 %fneg1 = fneg float %ld1
119 store float %fneg0, ptr %ptr0
120 store float %fneg1, ptr %ptr1
124 define float @scalars_with_external_uses_not_dead(ptr %ptr) {
125 ; CHECK-LABEL: define float @scalars_with_external_uses_not_dead(
126 ; CHECK-SAME: ptr [[PTR:%.*]]) {
127 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
128 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
129 ; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
130 ; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
131 ; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
132 ; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4
133 ; CHECK-NEXT: [[USER:%.*]] = fneg float [[LD1]]
134 ; CHECK-NEXT: ret float [[LD0]]
136 %ptr0 = getelementptr float, ptr %ptr, i32 0
137 %ptr1 = getelementptr float, ptr %ptr, i32 1
138 %ld0 = load float, ptr %ptr0
139 %ld1 = load float, ptr %ptr1
140 store float %ld0, ptr %ptr0
141 store float %ld1, ptr %ptr1
142 %user = fneg float %ld1
146 define void @pack_scalars(ptr %ptr, ptr %ptr2) {
147 ; CHECK-LABEL: define void @pack_scalars(
148 ; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
149 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
150 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
151 ; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
152 ; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
153 ; CHECK-NEXT: [[PACK:%.*]] = insertelement <2 x float> poison, float [[LD0]], i32 0
154 ; CHECK-NEXT: [[PACK1:%.*]] = insertelement <2 x float> [[PACK]], float [[LD1]], i32 1
155 ; CHECK-NEXT: store <2 x float> [[PACK1]], ptr [[PTR0]], align 4
156 ; CHECK-NEXT: ret void
158 %ptr0 = getelementptr float, ptr %ptr, i32 0
159 %ptr1 = getelementptr float, ptr %ptr, i32 1
160 %ld0 = load float, ptr %ptr0
161 %ld1 = load float, ptr %ptr2
162 store float %ld0, ptr %ptr0
163 store float %ld1, ptr %ptr1
168 define void @cant_vectorize_seeds(ptr %ptr) {
169 ; CHECK-LABEL: define void @cant_vectorize_seeds(
170 ; CHECK-SAME: ptr [[PTR:%.*]]) {
171 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
172 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
173 ; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
174 ; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
175 ; CHECK-NEXT: store float [[LD1]], ptr [[PTR1]], align 4
176 ; CHECK-NEXT: call void @foo()
177 ; CHECK-NEXT: store float [[LD1]], ptr [[PTR1]], align 4
178 ; CHECK-NEXT: ret void
180 %ptr0 = getelementptr float, ptr %ptr, i32 0
181 %ptr1 = getelementptr float, ptr %ptr, i32 1
182 %ld0 = load float, ptr %ptr0
183 %ld1 = load float, ptr %ptr1
184 store float %ld1, ptr %ptr1
185 call void @foo() ; This call blocks scheduling of the store seeds.
186 store float %ld1, ptr %ptr1
190 define void @pack_vectors(ptr %ptr, ptr %ptr2) {
191 ; CHECK-LABEL: define void @pack_vectors(
192 ; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
193 ; CHECK-NEXT: [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
194 ; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 2
195 ; CHECK-NEXT: [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8
196 ; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
197 ; CHECK-NEXT: [[VPACK:%.*]] = extractelement <2 x float> [[LD0]], i32 0
198 ; CHECK-NEXT: [[VPACK1:%.*]] = insertelement <3 x float> poison, float [[VPACK]], i32 0
199 ; CHECK-NEXT: [[VPACK2:%.*]] = extractelement <2 x float> [[LD0]], i32 1
200 ; CHECK-NEXT: [[VPACK3:%.*]] = insertelement <3 x float> [[VPACK1]], float [[VPACK2]], i32 1
201 ; CHECK-NEXT: [[PACK:%.*]] = insertelement <3 x float> [[VPACK3]], float [[LD1]], i32 2
202 ; CHECK-NEXT: store <3 x float> [[PACK]], ptr [[PTR0]], align 8
203 ; CHECK-NEXT: ret void
205 %ptr0 = getelementptr <2 x float>, ptr %ptr, i32 0
206 %ptr1 = getelementptr float, ptr %ptr, i32 2
207 %ld0 = load <2 x float>, ptr %ptr0
208 %ld1 = load float, ptr %ptr2
209 store <2 x float> %ld0, ptr %ptr0
210 store float %ld1, ptr %ptr1