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