[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / SandboxVectorizer / bottomup_basic.ll
blob7422d287ff3e2a66ee8103831d9ef390e7f09948
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
19   ret void
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
45   ret void
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
76   ret void
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
100   ret void
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
121   ret void
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
143   ret float %ld0
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
164   ret void
167 declare void @foo()
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
187   ret void
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
211   ret void