1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s
4 %v8i8 = type { i8, i8, i8, i8, i8, i8, i8, i8 }
6 ; https://bugs.llvm.org/show_bug.cgi?id=43146
8 define i64 @load_bswap(ptr %p) {
9 ; CHECK-LABEL: @load_bswap(
10 ; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[V8I8:%.*]], ptr [[P:%.*]], i64 0, i32 1
11 ; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 2
12 ; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 3
13 ; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 4
14 ; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 5
15 ; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 6
16 ; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 7
17 ; CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[P]], align 1
18 ; CHECK-NEXT: [[T1:%.*]] = load i8, ptr [[G1]], align 1
19 ; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[G2]], align 1
20 ; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[G3]], align 1
21 ; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[G4]], align 1
22 ; CHECK-NEXT: [[T5:%.*]] = load i8, ptr [[G5]], align 1
23 ; CHECK-NEXT: [[T6:%.*]] = load i8, ptr [[G6]], align 1
24 ; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[G7]], align 1
25 ; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[T0]] to i64
26 ; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[T1]] to i64
27 ; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[T2]] to i64
28 ; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[T3]] to i64
29 ; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[T4]] to i64
30 ; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[T5]] to i64
31 ; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[T6]] to i64
32 ; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[T7]] to i64
33 ; CHECK-NEXT: [[SH0:%.*]] = shl nuw i64 [[Z0]], 56
34 ; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw i64 [[Z1]], 48
35 ; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw i64 [[Z2]], 40
36 ; CHECK-NEXT: [[SH3:%.*]] = shl nuw nsw i64 [[Z3]], 32
37 ; CHECK-NEXT: [[SH4:%.*]] = shl nuw nsw i64 [[Z4]], 24
38 ; CHECK-NEXT: [[SH5:%.*]] = shl nuw nsw i64 [[Z5]], 16
39 ; CHECK-NEXT: [[SH6:%.*]] = shl nuw nsw i64 [[Z6]], 8
40 ; CHECK-NEXT: [[OR01:%.*]] = or i64 [[SH0]], [[SH1]]
41 ; CHECK-NEXT: [[OR012:%.*]] = or i64 [[OR01]], [[SH2]]
42 ; CHECK-NEXT: [[OR0123:%.*]] = or i64 [[OR012]], [[SH3]]
43 ; CHECK-NEXT: [[OR01234:%.*]] = or i64 [[OR0123]], [[SH4]]
44 ; CHECK-NEXT: [[OR012345:%.*]] = or i64 [[OR01234]], [[SH5]]
45 ; CHECK-NEXT: [[OR0123456:%.*]] = or i64 [[OR012345]], [[SH6]]
46 ; CHECK-NEXT: [[OR01234567:%.*]] = or i64 [[OR0123456]], [[Z7]]
47 ; CHECK-NEXT: ret i64 [[OR01234567]]
49 %g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1
50 %g2 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 2
51 %g3 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 3
52 %g4 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 4
53 %g5 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 5
54 %g6 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 6
55 %g7 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 7
58 %t1 = load i8, ptr %g1
59 %t2 = load i8, ptr %g2
60 %t3 = load i8, ptr %g3
61 %t4 = load i8, ptr %g4
62 %t5 = load i8, ptr %g5
63 %t6 = load i8, ptr %g6
64 %t7 = load i8, ptr %g7
66 %z0 = zext i8 %t0 to i64
67 %z1 = zext i8 %t1 to i64
68 %z2 = zext i8 %t2 to i64
69 %z3 = zext i8 %t3 to i64
70 %z4 = zext i8 %t4 to i64
71 %z5 = zext i8 %t5 to i64
72 %z6 = zext i8 %t6 to i64
73 %z7 = zext i8 %t7 to i64
75 %sh0 = shl nuw i64 %z0, 56
76 %sh1 = shl nuw nsw i64 %z1, 48
77 %sh2 = shl nuw nsw i64 %z2, 40
78 %sh3 = shl nuw nsw i64 %z3, 32
79 %sh4 = shl nuw nsw i64 %z4, 24
80 %sh5 = shl nuw nsw i64 %z5, 16
81 %sh6 = shl nuw nsw i64 %z6, 8
82 ; %sh7 = shl nuw nsw i64 %z7, 0 <-- missing phantom shift
84 %or01 = or i64 %sh0, %sh1
85 %or012 = or i64 %or01, %sh2
86 %or0123 = or i64 %or012, %sh3
87 %or01234 = or i64 %or0123, %sh4
88 %or012345 = or i64 %or01234, %sh5
89 %or0123456 = or i64 %or012345, %sh6
90 %or01234567 = or i64 %or0123456, %z7
94 define i64 @load_bswap_nop_shift(ptr %p) {
95 ; CHECK-LABEL: @load_bswap_nop_shift(
96 ; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[V8I8:%.*]], ptr [[P:%.*]], i64 0, i32 1
97 ; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 2
98 ; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 3
99 ; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 4
100 ; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 5
101 ; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 6
102 ; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 7
103 ; CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[P]], align 1
104 ; CHECK-NEXT: [[T1:%.*]] = load i8, ptr [[G1]], align 1
105 ; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[G2]], align 1
106 ; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[G3]], align 1
107 ; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[G4]], align 1
108 ; CHECK-NEXT: [[T5:%.*]] = load i8, ptr [[G5]], align 1
109 ; CHECK-NEXT: [[T6:%.*]] = load i8, ptr [[G6]], align 1
110 ; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[G7]], align 1
111 ; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[T0]] to i64
112 ; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[T1]] to i64
113 ; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[T2]] to i64
114 ; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[T3]] to i64
115 ; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[T4]] to i64
116 ; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[T5]] to i64
117 ; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[T6]] to i64
118 ; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[T7]] to i64
119 ; CHECK-NEXT: [[SH0:%.*]] = shl nuw i64 [[Z0]], 56
120 ; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw i64 [[Z1]], 48
121 ; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw i64 [[Z2]], 40
122 ; CHECK-NEXT: [[SH3:%.*]] = shl nuw nsw i64 [[Z3]], 32
123 ; CHECK-NEXT: [[SH4:%.*]] = shl nuw nsw i64 [[Z4]], 24
124 ; CHECK-NEXT: [[SH5:%.*]] = shl nuw nsw i64 [[Z5]], 16
125 ; CHECK-NEXT: [[SH6:%.*]] = shl nuw nsw i64 [[Z6]], 8
126 ; CHECK-NEXT: [[SH7:%.*]] = shl nuw nsw i64 [[Z7]], 0
127 ; CHECK-NEXT: [[OR01:%.*]] = or i64 [[SH0]], [[SH1]]
128 ; CHECK-NEXT: [[OR012:%.*]] = or i64 [[OR01]], [[SH2]]
129 ; CHECK-NEXT: [[OR0123:%.*]] = or i64 [[OR012]], [[SH3]]
130 ; CHECK-NEXT: [[OR01234:%.*]] = or i64 [[OR0123]], [[SH4]]
131 ; CHECK-NEXT: [[OR012345:%.*]] = or i64 [[OR01234]], [[SH5]]
132 ; CHECK-NEXT: [[OR0123456:%.*]] = or i64 [[OR012345]], [[SH6]]
133 ; CHECK-NEXT: [[OR01234567:%.*]] = or i64 [[OR0123456]], [[SH7]]
134 ; CHECK-NEXT: ret i64 [[OR01234567]]
136 %g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1
137 %g2 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 2
138 %g3 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 3
139 %g4 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 4
140 %g5 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 5
141 %g6 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 6
142 %g7 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 7
144 %t0 = load i8, ptr %p
145 %t1 = load i8, ptr %g1
146 %t2 = load i8, ptr %g2
147 %t3 = load i8, ptr %g3
148 %t4 = load i8, ptr %g4
149 %t5 = load i8, ptr %g5
150 %t6 = load i8, ptr %g6
151 %t7 = load i8, ptr %g7
153 %z0 = zext i8 %t0 to i64
154 %z1 = zext i8 %t1 to i64
155 %z2 = zext i8 %t2 to i64
156 %z3 = zext i8 %t3 to i64
157 %z4 = zext i8 %t4 to i64
158 %z5 = zext i8 %t5 to i64
159 %z6 = zext i8 %t6 to i64
160 %z7 = zext i8 %t7 to i64
162 %sh0 = shl nuw i64 %z0, 56
163 %sh1 = shl nuw nsw i64 %z1, 48
164 %sh2 = shl nuw nsw i64 %z2, 40
165 %sh3 = shl nuw nsw i64 %z3, 32
166 %sh4 = shl nuw nsw i64 %z4, 24
167 %sh5 = shl nuw nsw i64 %z5, 16
168 %sh6 = shl nuw nsw i64 %z6, 8
169 %sh7 = shl nuw nsw i64 %z7, 0
171 %or01 = or i64 %sh0, %sh1
172 %or012 = or i64 %or01, %sh2
173 %or0123 = or i64 %or012, %sh3
174 %or01234 = or i64 %or0123, %sh4
175 %or012345 = or i64 %or01234, %sh5
176 %or0123456 = or i64 %or012345, %sh6
177 %or01234567 = or i64 %or0123456, %sh7
181 ; https://bugs.llvm.org/show_bug.cgi?id=42708
183 define i64 @load64le(ptr %arg) {
184 ; CHECK-LABEL: @load64le(
185 ; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1
186 ; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2
187 ; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3
188 ; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4
189 ; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5
190 ; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6
191 ; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7
192 ; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[ARG]], align 1
193 ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[G1]], align 1
194 ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[G2]], align 1
195 ; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[G3]], align 1
196 ; CHECK-NEXT: [[LD4:%.*]] = load i8, ptr [[G4]], align 1
197 ; CHECK-NEXT: [[LD5:%.*]] = load i8, ptr [[G5]], align 1
198 ; CHECK-NEXT: [[LD6:%.*]] = load i8, ptr [[G6]], align 1
199 ; CHECK-NEXT: [[LD7:%.*]] = load i8, ptr [[G7]], align 1
200 ; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[LD0]] to i64
201 ; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[LD1]] to i64
202 ; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[LD2]] to i64
203 ; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[LD3]] to i64
204 ; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[LD4]] to i64
205 ; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[LD5]] to i64
206 ; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[LD6]] to i64
207 ; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[LD7]] to i64
208 ; CHECK-NEXT: [[S1:%.*]] = shl nuw nsw i64 [[Z1]], 8
209 ; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i64 [[Z2]], 16
210 ; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i64 [[Z3]], 24
211 ; CHECK-NEXT: [[S4:%.*]] = shl nuw nsw i64 [[Z4]], 32
212 ; CHECK-NEXT: [[S5:%.*]] = shl nuw nsw i64 [[Z5]], 40
213 ; CHECK-NEXT: [[S6:%.*]] = shl nuw nsw i64 [[Z6]], 48
214 ; CHECK-NEXT: [[S7:%.*]] = shl nuw i64 [[Z7]], 56
215 ; CHECK-NEXT: [[O1:%.*]] = or i64 [[S1]], [[Z0]]
216 ; CHECK-NEXT: [[O2:%.*]] = or i64 [[O1]], [[S2]]
217 ; CHECK-NEXT: [[O3:%.*]] = or i64 [[O2]], [[S3]]
218 ; CHECK-NEXT: [[O4:%.*]] = or i64 [[O3]], [[S4]]
219 ; CHECK-NEXT: [[O5:%.*]] = or i64 [[O4]], [[S5]]
220 ; CHECK-NEXT: [[O6:%.*]] = or i64 [[O5]], [[S6]]
221 ; CHECK-NEXT: [[O7:%.*]] = or i64 [[O6]], [[S7]]
222 ; CHECK-NEXT: ret i64 [[O7]]
224 %g1 = getelementptr inbounds i8, ptr %arg, i64 1
225 %g2 = getelementptr inbounds i8, ptr %arg, i64 2
226 %g3 = getelementptr inbounds i8, ptr %arg, i64 3
227 %g4 = getelementptr inbounds i8, ptr %arg, i64 4
228 %g5 = getelementptr inbounds i8, ptr %arg, i64 5
229 %g6 = getelementptr inbounds i8, ptr %arg, i64 6
230 %g7 = getelementptr inbounds i8, ptr %arg, i64 7
232 %ld0 = load i8, ptr %arg, align 1
233 %ld1 = load i8, ptr %g1, align 1
234 %ld2 = load i8, ptr %g2, align 1
235 %ld3 = load i8, ptr %g3, align 1
236 %ld4 = load i8, ptr %g4, align 1
237 %ld5 = load i8, ptr %g5, align 1
238 %ld6 = load i8, ptr %g6, align 1
239 %ld7 = load i8, ptr %g7, align 1
241 %z0 = zext i8 %ld0 to i64
242 %z1 = zext i8 %ld1 to i64
243 %z2 = zext i8 %ld2 to i64
244 %z3 = zext i8 %ld3 to i64
245 %z4 = zext i8 %ld4 to i64
246 %z5 = zext i8 %ld5 to i64
247 %z6 = zext i8 %ld6 to i64
248 %z7 = zext i8 %ld7 to i64
250 ; %s0 = shl nuw nsw i64 %z0, 0 <-- missing phantom shift
251 %s1 = shl nuw nsw i64 %z1, 8
252 %s2 = shl nuw nsw i64 %z2, 16
253 %s3 = shl nuw nsw i64 %z3, 24
254 %s4 = shl nuw nsw i64 %z4, 32
255 %s5 = shl nuw nsw i64 %z5, 40
256 %s6 = shl nuw nsw i64 %z6, 48
257 %s7 = shl nuw i64 %z7, 56
259 %o1 = or i64 %s1, %z0
260 %o2 = or i64 %o1, %s2
261 %o3 = or i64 %o2, %s3
262 %o4 = or i64 %o3, %s4
263 %o5 = or i64 %o4, %s5
264 %o6 = or i64 %o5, %s6
265 %o7 = or i64 %o6, %s7
269 define i64 @load64le_nop_shift(ptr %arg) {
270 ; CHECK-LABEL: @load64le_nop_shift(
271 ; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1
272 ; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2
273 ; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3
274 ; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4
275 ; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5
276 ; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6
277 ; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7
278 ; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[ARG]], align 1
279 ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[G1]], align 1
280 ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[G2]], align 1
281 ; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[G3]], align 1
282 ; CHECK-NEXT: [[LD4:%.*]] = load i8, ptr [[G4]], align 1
283 ; CHECK-NEXT: [[LD5:%.*]] = load i8, ptr [[G5]], align 1
284 ; CHECK-NEXT: [[LD6:%.*]] = load i8, ptr [[G6]], align 1
285 ; CHECK-NEXT: [[LD7:%.*]] = load i8, ptr [[G7]], align 1
286 ; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[LD0]] to i64
287 ; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[LD1]] to i64
288 ; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[LD2]] to i64
289 ; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[LD3]] to i64
290 ; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[LD4]] to i64
291 ; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[LD5]] to i64
292 ; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[LD6]] to i64
293 ; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[LD7]] to i64
294 ; CHECK-NEXT: [[S0:%.*]] = shl nuw nsw i64 [[Z0]], 0
295 ; CHECK-NEXT: [[S1:%.*]] = shl nuw nsw i64 [[Z1]], 8
296 ; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i64 [[Z2]], 16
297 ; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i64 [[Z3]], 24
298 ; CHECK-NEXT: [[S4:%.*]] = shl nuw nsw i64 [[Z4]], 32
299 ; CHECK-NEXT: [[S5:%.*]] = shl nuw nsw i64 [[Z5]], 40
300 ; CHECK-NEXT: [[S6:%.*]] = shl nuw nsw i64 [[Z6]], 48
301 ; CHECK-NEXT: [[S7:%.*]] = shl nuw i64 [[Z7]], 56
302 ; CHECK-NEXT: [[O1:%.*]] = or i64 [[S1]], [[S0]]
303 ; CHECK-NEXT: [[O2:%.*]] = or i64 [[O1]], [[S2]]
304 ; CHECK-NEXT: [[O3:%.*]] = or i64 [[O2]], [[S3]]
305 ; CHECK-NEXT: [[O4:%.*]] = or i64 [[O3]], [[S4]]
306 ; CHECK-NEXT: [[O5:%.*]] = or i64 [[O4]], [[S5]]
307 ; CHECK-NEXT: [[O6:%.*]] = or i64 [[O5]], [[S6]]
308 ; CHECK-NEXT: [[O7:%.*]] = or i64 [[O6]], [[S7]]
309 ; CHECK-NEXT: ret i64 [[O7]]
311 %g1 = getelementptr inbounds i8, ptr %arg, i64 1
312 %g2 = getelementptr inbounds i8, ptr %arg, i64 2
313 %g3 = getelementptr inbounds i8, ptr %arg, i64 3
314 %g4 = getelementptr inbounds i8, ptr %arg, i64 4
315 %g5 = getelementptr inbounds i8, ptr %arg, i64 5
316 %g6 = getelementptr inbounds i8, ptr %arg, i64 6
317 %g7 = getelementptr inbounds i8, ptr %arg, i64 7
319 %ld0 = load i8, ptr %arg, align 1
320 %ld1 = load i8, ptr %g1, align 1
321 %ld2 = load i8, ptr %g2, align 1
322 %ld3 = load i8, ptr %g3, align 1
323 %ld4 = load i8, ptr %g4, align 1
324 %ld5 = load i8, ptr %g5, align 1
325 %ld6 = load i8, ptr %g6, align 1
326 %ld7 = load i8, ptr %g7, align 1
328 %z0 = zext i8 %ld0 to i64
329 %z1 = zext i8 %ld1 to i64
330 %z2 = zext i8 %ld2 to i64
331 %z3 = zext i8 %ld3 to i64
332 %z4 = zext i8 %ld4 to i64
333 %z5 = zext i8 %ld5 to i64
334 %z6 = zext i8 %ld6 to i64
335 %z7 = zext i8 %ld7 to i64
337 %s0 = shl nuw nsw i64 %z0, 0
338 %s1 = shl nuw nsw i64 %z1, 8
339 %s2 = shl nuw nsw i64 %z2, 16
340 %s3 = shl nuw nsw i64 %z3, 24
341 %s4 = shl nuw nsw i64 %z4, 32
342 %s5 = shl nuw nsw i64 %z5, 40
343 %s6 = shl nuw nsw i64 %z6, 48
344 %s7 = shl nuw i64 %z7, 56
346 %o1 = or i64 %s1, %s0
347 %o2 = or i64 %o1, %s2
348 %o3 = or i64 %o2, %s3
349 %o4 = or i64 %o3, %s4
350 %o5 = or i64 %o4, %s5
351 %o6 = or i64 %o5, %s6
352 %o7 = or i64 %o6, %s7
356 define void @PR39538(ptr %t0, ptr %t1) {
357 ; CHECK-LABEL: @PR39538(
358 ; CHECK-NEXT: [[T6:%.*]] = getelementptr inbounds i8, ptr [[T0:%.*]], i64 1
359 ; CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 2
360 ; CHECK-NEXT: [[T16:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 3
361 ; CHECK-NEXT: [[T20:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 4
362 ; CHECK-NEXT: [[T24:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 5
363 ; CHECK-NEXT: [[T29:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 6
364 ; CHECK-NEXT: [[T34:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 7
365 ; CHECK-NEXT: [[T39:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 8
366 ; CHECK-NEXT: [[T43:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 9
367 ; CHECK-NEXT: [[T48:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 10
368 ; CHECK-NEXT: [[T53:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 11
369 ; CHECK-NEXT: [[T58:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 12
370 ; CHECK-NEXT: [[T62:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 13
371 ; CHECK-NEXT: [[T67:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 14
372 ; CHECK-NEXT: [[T72:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 15
373 ; CHECK-NEXT: [[T38:%.*]] = getelementptr inbounds i32, ptr [[T1:%.*]], i64 1
374 ; CHECK-NEXT: [[T57:%.*]] = getelementptr inbounds i32, ptr [[T1]], i64 2
375 ; CHECK-NEXT: [[T76:%.*]] = getelementptr inbounds i32, ptr [[T1]], i64 3
376 ; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[T0]], align 1
377 ; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[T6]], align 1
378 ; CHECK-NEXT: [[T12:%.*]] = load i8, ptr [[T11]], align 1
379 ; CHECK-NEXT: [[T17:%.*]] = load i8, ptr [[T16]], align 1
380 ; CHECK-NEXT: [[T21:%.*]] = load i8, ptr [[T20]], align 1
381 ; CHECK-NEXT: [[T25:%.*]] = load i8, ptr [[T24]], align 1
382 ; CHECK-NEXT: [[T30:%.*]] = load i8, ptr [[T29]], align 1
383 ; CHECK-NEXT: [[T35:%.*]] = load i8, ptr [[T34]], align 1
384 ; CHECK-NEXT: [[T40:%.*]] = load i8, ptr [[T39]], align 1
385 ; CHECK-NEXT: [[T44:%.*]] = load i8, ptr [[T43]], align 1
386 ; CHECK-NEXT: [[T49:%.*]] = load i8, ptr [[T48]], align 1
387 ; CHECK-NEXT: [[T54:%.*]] = load i8, ptr [[T53]], align 1
388 ; CHECK-NEXT: [[T59:%.*]] = load i8, ptr [[T58]], align 1
389 ; CHECK-NEXT: [[T63:%.*]] = load i8, ptr [[T62]], align 1
390 ; CHECK-NEXT: [[T68:%.*]] = load i8, ptr [[T67]], align 1
391 ; CHECK-NEXT: [[T73:%.*]] = load i8, ptr [[T72]], align 1
392 ; CHECK-NEXT: [[T4:%.*]] = zext i8 [[T3]] to i32
393 ; CHECK-NEXT: [[T8:%.*]] = zext i8 [[T7]] to i32
394 ; CHECK-NEXT: [[T13:%.*]] = zext i8 [[T12]] to i32
395 ; CHECK-NEXT: [[T18:%.*]] = zext i8 [[T17]] to i32
396 ; CHECK-NEXT: [[T22:%.*]] = zext i8 [[T21]] to i32
397 ; CHECK-NEXT: [[T26:%.*]] = zext i8 [[T25]] to i32
398 ; CHECK-NEXT: [[T31:%.*]] = zext i8 [[T30]] to i32
399 ; CHECK-NEXT: [[T36:%.*]] = zext i8 [[T35]] to i32
400 ; CHECK-NEXT: [[T41:%.*]] = zext i8 [[T40]] to i32
401 ; CHECK-NEXT: [[T45:%.*]] = zext i8 [[T44]] to i32
402 ; CHECK-NEXT: [[T50:%.*]] = zext i8 [[T49]] to i32
403 ; CHECK-NEXT: [[T55:%.*]] = zext i8 [[T54]] to i32
404 ; CHECK-NEXT: [[T60:%.*]] = zext i8 [[T59]] to i32
405 ; CHECK-NEXT: [[T64:%.*]] = zext i8 [[T63]] to i32
406 ; CHECK-NEXT: [[T69:%.*]] = zext i8 [[T68]] to i32
407 ; CHECK-NEXT: [[T74:%.*]] = zext i8 [[T73]] to i32
408 ; CHECK-NEXT: [[T5:%.*]] = shl nuw i32 [[T4]], 24
409 ; CHECK-NEXT: [[T23:%.*]] = shl nuw i32 [[T22]], 24
410 ; CHECK-NEXT: [[T42:%.*]] = shl nuw i32 [[T41]], 24
411 ; CHECK-NEXT: [[T61:%.*]] = shl nuw i32 [[T60]], 24
412 ; CHECK-NEXT: [[T9:%.*]] = shl nuw nsw i32 [[T8]], 16
413 ; CHECK-NEXT: [[T27:%.*]] = shl nuw nsw i32 [[T26]], 16
414 ; CHECK-NEXT: [[T46:%.*]] = shl nuw nsw i32 [[T45]], 16
415 ; CHECK-NEXT: [[T65:%.*]] = shl nuw nsw i32 [[T64]], 16
416 ; CHECK-NEXT: [[T14:%.*]] = shl nuw nsw i32 [[T13]], 8
417 ; CHECK-NEXT: [[T32:%.*]] = shl nuw nsw i32 [[T31]], 8
418 ; CHECK-NEXT: [[T51:%.*]] = shl nuw nsw i32 [[T50]], 8
419 ; CHECK-NEXT: [[T70:%.*]] = shl nuw nsw i32 [[T69]], 8
420 ; CHECK-NEXT: [[T10:%.*]] = or i32 [[T9]], [[T5]]
421 ; CHECK-NEXT: [[T15:%.*]] = or i32 [[T10]], [[T14]]
422 ; CHECK-NEXT: [[T19:%.*]] = or i32 [[T15]], [[T18]]
423 ; CHECK-NEXT: [[T28:%.*]] = or i32 [[T27]], [[T23]]
424 ; CHECK-NEXT: [[T33:%.*]] = or i32 [[T28]], [[T32]]
425 ; CHECK-NEXT: [[T37:%.*]] = or i32 [[T33]], [[T36]]
426 ; CHECK-NEXT: [[T47:%.*]] = or i32 [[T46]], [[T42]]
427 ; CHECK-NEXT: [[T52:%.*]] = or i32 [[T47]], [[T51]]
428 ; CHECK-NEXT: [[T56:%.*]] = or i32 [[T52]], [[T55]]
429 ; CHECK-NEXT: [[T66:%.*]] = or i32 [[T65]], [[T61]]
430 ; CHECK-NEXT: [[T71:%.*]] = or i32 [[T66]], [[T70]]
431 ; CHECK-NEXT: [[T75:%.*]] = or i32 [[T71]], [[T74]]
432 ; CHECK-NEXT: store i32 [[T19]], ptr [[T1]], align 4
433 ; CHECK-NEXT: store i32 [[T37]], ptr [[T38]], align 4
434 ; CHECK-NEXT: store i32 [[T56]], ptr [[T57]], align 4
435 ; CHECK-NEXT: store i32 [[T75]], ptr [[T76]], align 4
436 ; CHECK-NEXT: ret void
438 %t6 = getelementptr inbounds i8, ptr %t0, i64 1
439 %t11 = getelementptr inbounds i8, ptr %t0, i64 2
440 %t16 = getelementptr inbounds i8, ptr %t0, i64 3
441 %t20 = getelementptr inbounds i8, ptr %t0, i64 4
442 %t24 = getelementptr inbounds i8, ptr %t0, i64 5
443 %t29 = getelementptr inbounds i8, ptr %t0, i64 6
444 %t34 = getelementptr inbounds i8, ptr %t0, i64 7
445 %t39 = getelementptr inbounds i8, ptr %t0, i64 8
446 %t43 = getelementptr inbounds i8, ptr %t0, i64 9
447 %t48 = getelementptr inbounds i8, ptr %t0, i64 10
448 %t53 = getelementptr inbounds i8, ptr %t0, i64 11
449 %t58 = getelementptr inbounds i8, ptr %t0, i64 12
450 %t62 = getelementptr inbounds i8, ptr %t0, i64 13
451 %t67 = getelementptr inbounds i8, ptr %t0, i64 14
452 %t72 = getelementptr inbounds i8, ptr %t0, i64 15
453 %t38 = getelementptr inbounds i32, ptr %t1, i64 1
454 %t57 = getelementptr inbounds i32, ptr %t1, i64 2
455 %t76 = getelementptr inbounds i32, ptr %t1, i64 3
456 %t3 = load i8, ptr %t0, align 1
457 %t7 = load i8, ptr %t6, align 1
458 %t12 = load i8, ptr %t11, align 1
459 %t17 = load i8, ptr %t16, align 1
460 %t21 = load i8, ptr %t20, align 1
461 %t25 = load i8, ptr %t24, align 1
462 %t30 = load i8, ptr %t29, align 1
463 %t35 = load i8, ptr %t34, align 1
464 %t40 = load i8, ptr %t39, align 1
465 %t44 = load i8, ptr %t43, align 1
466 %t49 = load i8, ptr %t48, align 1
467 %t54 = load i8, ptr %t53, align 1
468 %t59 = load i8, ptr %t58, align 1
469 %t63 = load i8, ptr %t62, align 1
470 %t68 = load i8, ptr %t67, align 1
471 %t73 = load i8, ptr %t72, align 1
472 %t4 = zext i8 %t3 to i32
473 %t8 = zext i8 %t7 to i32
474 %t13 = zext i8 %t12 to i32
475 %t18 = zext i8 %t17 to i32
476 %t22 = zext i8 %t21 to i32
477 %t26 = zext i8 %t25 to i32
478 %t31 = zext i8 %t30 to i32
479 %t36 = zext i8 %t35 to i32
480 %t41 = zext i8 %t40 to i32
481 %t45 = zext i8 %t44 to i32
482 %t50 = zext i8 %t49 to i32
483 %t55 = zext i8 %t54 to i32
484 %t60 = zext i8 %t59 to i32
485 %t64 = zext i8 %t63 to i32
486 %t69 = zext i8 %t68 to i32
487 %t74 = zext i8 %t73 to i32
488 %t5 = shl nuw i32 %t4, 24
489 %t23 = shl nuw i32 %t22, 24
490 %t42 = shl nuw i32 %t41, 24
491 %t61 = shl nuw i32 %t60, 24
492 %t9 = shl nuw nsw i32 %t8, 16
493 %t27 = shl nuw nsw i32 %t26, 16
494 %t46 = shl nuw nsw i32 %t45, 16
495 %t65 = shl nuw nsw i32 %t64, 16
496 %t14 = shl nuw nsw i32 %t13, 8
497 %t32 = shl nuw nsw i32 %t31, 8
498 %t51 = shl nuw nsw i32 %t50, 8
499 %t70 = shl nuw nsw i32 %t69, 8
500 %t10 = or i32 %t9, %t5
501 %t15 = or i32 %t10, %t14
502 %t19 = or i32 %t15, %t18
503 %t28 = or i32 %t27, %t23
504 %t33 = or i32 %t28, %t32
505 %t37 = or i32 %t33, %t36
506 %t47 = or i32 %t46, %t42
507 %t52 = or i32 %t47, %t51
508 %t56 = or i32 %t52, %t55
509 %t66 = or i32 %t65, %t61
510 %t71 = or i32 %t66, %t70
511 %t75 = or i32 %t71, %t74
512 store i32 %t19, ptr %t1, align 4
513 store i32 %t37, ptr %t38, align 4
514 store i32 %t56, ptr %t57, align 4
515 store i32 %t75, ptr %t76, align 4
519 ; Do not crash on constant expressions.
521 @g1 = external dso_local unnamed_addr constant [8 x i8], align 1
522 @g2 = external dso_local unnamed_addr constant [5 x i8], align 1
524 define void @load_combine_constant_expression(ptr %t1) {
525 ; CHECK-LABEL: @load_combine_constant_expression(
526 ; CHECK-NEXT: [[EXT1:%.*]] = zext i32 ptrtoint (ptr @g1 to i32) to i64
527 ; CHECK-NEXT: [[EXT2:%.*]] = zext i32 ptrtoint (ptr @g2 to i32) to i64
528 ; CHECK-NEXT: [[SHL1:%.*]] = shl i64 [[EXT1]], 32
529 ; CHECK-NEXT: [[OR1:%.*]] = or i64 [[SHL1]], [[EXT2]]
530 ; CHECK-NEXT: store i64 [[OR1]], ptr [[T1:%.*]], align 4
531 ; CHECK-NEXT: [[T3:%.*]] = getelementptr i64, ptr [[T1]], i64 1
532 ; CHECK-NEXT: [[SHL2:%.*]] = shl i64 [[EXT1]], 32
533 ; CHECK-NEXT: [[OR2:%.*]] = or i64 [[SHL2]], [[EXT2]]
534 ; CHECK-NEXT: store i64 [[OR2]], ptr [[T3]], align 4
535 ; CHECK-NEXT: ret void
537 %ext1 = zext i32 ptrtoint (ptr @g1 to i32) to i64
538 %ext2 = zext i32 ptrtoint (ptr @g2 to i32) to i64
539 %shl1 = shl i64 %ext1, 32
540 %or1 = or i64 %shl1, %ext2
541 store i64 %or1, ptr %t1, align 4
542 %t3 = getelementptr i64, ptr %t1, i64 1
543 %shl2 = shl i64 %ext1, 32
544 %or2 = or i64 %shl2, %ext2
545 store i64 %or2, ptr %t3, align 4
549 @output = dso_local local_unnamed_addr global [8 x i32] zeroinitializer, align 16
551 define void @PR47450(ptr nocapture readonly %p) {
552 ; CHECK-LABEL: @PR47450(
553 ; CHECK-NEXT: [[X:%.*]] = load i16, ptr [[P:%.*]], align 2
554 ; CHECK-NEXT: [[Z:%.*]] = zext i16 [[X]] to i32
555 ; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 1
556 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 [[S]], i32 0
557 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
558 ; CHECK-NEXT: store <4 x i32> [[TMP2]], ptr @output, align 16
559 ; CHECK-NEXT: ret void
561 %x = load i16, ptr %p, align 2
562 %z = zext i16 %x to i32
563 %s = shl nuw nsw i32 %z, 1
564 store i32 %s, ptr @output, align 16
565 store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 1), align 4
566 store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 2), align 8
567 store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 3), align 4