constant-fold-gep.ll revision 0891d752a68a25025ffc3339aab1f0ad3221b0ed
1; "PLAIN" - No optimizations. This tests the target-independent
2; constant folder.
3; RUN: opt -S -o - < %s | FileCheck --check-prefix=PLAIN %s
4
5; "OPT" - Optimizations but no targetdata. This tests target-independent
6; folding in the optimizers.
7; RUN: opt -S -o - -instcombine -globalopt < %s | FileCheck --check-prefix=OPT %s
8
9; "TO" - Optimizations and targetdata. This tests target-dependent
10; folding in the optimizers.
11; RUN: opt -S -o - -instcombine -globalopt -default-data-layout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" < %s | FileCheck --check-prefix=TO %s
12
13; "SCEV" - ScalarEvolution but no targetdata.
14; RUN: opt -analyze -scalar-evolution < %s | FileCheck --check-prefix=SCEV %s
15
16; ScalarEvolution with targetdata isn't interesting on these testcases
17; because ScalarEvolution doesn't attempt to duplicate all of instcombine's
18; and the constant folders' folding.
19
20; PLAIN: %0 = type { i1, double }
21; PLAIN: %1 = type { double, float, double, double }
22; PLAIN: %2 = type { i1, i1* }
23; PLAIN: %3 = type { i64, i64 }
24; PLAIN: %4 = type { i32, i32 }
25; OPT: %0 = type { i1, double }
26; OPT: %1 = type { double, float, double, double }
27; OPT: %2 = type { i1, i1* }
28; OPT: %3 = type { i64, i64 }
29; OPT: %4 = type { i32, i32 }
30
31; The automatic constant folder in opt does not have targetdata access, so
32; it can't fold gep arithmetic, in general. However, the constant folder run
33; from instcombine and global opt can use targetdata.
34
35; PLAIN: @G8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
36; PLAIN: @G1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
37; PLAIN: @F8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
38; PLAIN: @F1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
39; PLAIN: @H8 = global i8* getelementptr (i8* null, i32 -1)
40; PLAIN: @H1 = global i1* getelementptr (i1* null, i32 -1)
41; OPT: @G8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
42; OPT: @G1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
43; OPT: @F8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
44; OPT: @F1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
45; OPT: @H8 = global i8* getelementptr (i8* null, i32 -1)
46; OPT: @H1 = global i1* getelementptr (i1* null, i32 -1)
47; TO: @G8 = global i8* null
48; TO: @G1 = global i1* null
49; TO: @F8 = global i8* inttoptr (i64 -1 to i8*)
50; TO: @F1 = global i1* inttoptr (i64 -1 to i1*)
51; TO: @H8 = global i8* inttoptr (i64 -1 to i8*)
52; TO: @H1 = global i1* inttoptr (i64 -1 to i1*)
53
54@G8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
55@G1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
56@F8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
57@F1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
58@H8 = global i8* getelementptr (i8* inttoptr (i32 0 to i8*), i32 -1)
59@H1 = global i1* getelementptr (i1* inttoptr (i32 0 to i1*), i32 -1)
60
61; The target-independent folder should be able to do some clever
62; simplifications on sizeof, alignof, and offsetof expressions. The
63; target-dependent folder should fold these down to constants.
64
65; PLAIN: @a = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
66; PLAIN: @b = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
67; PLAIN: @c = constant i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
68; PLAIN: @d = constant i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
69; PLAIN: @e = constant i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64)
70; PLAIN: @f = constant i64 1
71; PLAIN: @g = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
72; PLAIN: @h = constant i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
73; PLAIN: @i = constant i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
74; PLAIN: @j = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
75; PLAIN: @k = constant i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
76; OPT: @a = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
77; OPT: @b = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
78; OPT: @c = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
79; OPT: @d = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
80; OPT: @e = constant i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64)
81; OPT: @f = constant i64 1
82; OPT: @g = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
83; OPT: @h = constant i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
84; OPT: @i = constant i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
85; OPT: @j = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
86; OPT: @k = constant i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
87; TO: @a = constant i64 18480
88; TO: @b = constant i64 8
89; TO: @c = constant i64 16
90; TO: @d = constant i64 88
91; TO: @e = constant i64 16
92; TO: @f = constant i64 1
93; TO: @g = constant i64 8
94; TO: @h = constant i64 8
95; TO: @i = constant i64 8
96; TO: @j = constant i64 8
97; TO: @k = constant i64 8
98
99@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}* null, i64 11) to i64), i64 5))
100@b = constant i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}* null, i64 0, i32 1) to i64)
101@c = constant i64 ptrtoint (double* getelementptr ({double, double, double, double}* null, i64 0, i32 2) to i64)
102@d = constant i64 ptrtoint (double* getelementptr ([13 x double]* null, i64 0, i32 11) to i64)
103@e = constant i64 ptrtoint (double* getelementptr ({double, float, double, double}* null, i64 0, i32 2) to i64)
104@f = constant i64 ptrtoint (<{ i16, i128 }>* getelementptr ({i1, <{ i16, i128 }>}* null, i64 0, i32 1) to i64)
105@g = constant i64 ptrtoint ({double, double}* getelementptr ({i1, {double, double}}* null, i64 0, i32 1) to i64)
106@h = constant i64 ptrtoint (double** getelementptr (double** null, i64 1) to i64)
107@i = constant i64 ptrtoint (double** getelementptr ({i1, double*}* null, i64 0, i32 1) to i64)
108@j = constant i64 ptrtoint (union {double, double}* getelementptr ({i1, union {double, double}}* null, i64 0, i32 1) to i64)
109@k = constant i64 ptrtoint (union {double, double}* getelementptr (union {double, double}* null, i64 1) to i64)
110
111; The target-dependent folder should cast GEP indices to integer-sized pointers.
112
113; PLAIN: @M = constant i64* getelementptr (i64* null, i32 1)
114; PLAIN: @N = constant i64* getelementptr (%3* null, i32 0, i32 1)
115; PLAIN: @O = constant i64* getelementptr ([2 x i64]* null, i32 0, i32 1)
116; OPT: @M = constant i64* getelementptr (i64* null, i32 1)
117; OPT: @N = constant i64* getelementptr (%3* null, i32 0, i32 1)
118; OPT: @O = constant i64* getelementptr ([2 x i64]* null, i32 0, i32 1)
119; TO: @M = constant i64* inttoptr (i64 8 to i64*)
120; TO: @N = constant i64* inttoptr (i64 8 to i64*)
121; TO: @O = constant i64* inttoptr (i64 8 to i64*)
122
123@M = constant i64* getelementptr (i64* null, i32 1)
124@N = constant i64* getelementptr ({ i64, i64 }* null, i32 0, i32 1)
125@O = constant i64* getelementptr ([2 x i64]* null, i32 0, i32 1)
126
127; Fold GEP of a GEP. Theoretically some of these cases could be folded
128; without using targetdata, however that's not implemented yet.
129
130; PLAIN: @Z = global i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x %4]* @ext, i64 0, i64 1, i32 0), i64 1)
131; OPT: @Z = global i32* getelementptr (i32* getelementptr inbounds ([3 x %4]* @ext, i64 0, i64 1, i32 0), i64 1)
132; TO: @Z = global i32* getelementptr inbounds ([3 x %0]* @ext, i64 0, i64 1, i32 1)
133
134@ext = external global [3 x { i32, i32 }]
135@Z = global i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1)
136
137; Duplicate all of the above as function return values rather than
138; global initializers.
139
140; PLAIN: define i8* @goo8() nounwind {
141; PLAIN:   %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1) to i8*
142; PLAIN:   ret i8* %t
143; PLAIN: }
144; PLAIN: define i1* @goo1() nounwind {
145; PLAIN:   %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1) to i1*
146; PLAIN:   ret i1* %t
147; PLAIN: }
148; PLAIN: define i8* @foo8() nounwind {
149; PLAIN:   %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2) to i8*
150; PLAIN:   ret i8* %t
151; PLAIN: }
152; PLAIN: define i1* @foo1() nounwind {
153; PLAIN:   %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2) to i1*
154; PLAIN:   ret i1* %t
155; PLAIN: }
156; PLAIN: define i8* @hoo8() nounwind {
157; PLAIN:   %t = bitcast i8* getelementptr (i8* null, i32 -1) to i8*
158; PLAIN:   ret i8* %t
159; PLAIN: }
160; PLAIN: define i1* @hoo1() nounwind {
161; PLAIN:   %t = bitcast i1* getelementptr (i1* null, i32 -1) to i1*
162; PLAIN:   ret i1* %t
163; PLAIN: }
164; OPT: define i8* @goo8() nounwind {
165; OPT:   ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
166; OPT: }
167; OPT: define i1* @goo1() nounwind {
168; OPT:   ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
169; OPT: }
170; OPT: define i8* @foo8() nounwind {
171; OPT:   ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
172; OPT: }
173; OPT: define i1* @foo1() nounwind {
174; OPT:   ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
175; OPT: }
176; OPT: define i8* @hoo8() nounwind {
177; OPT:   ret i8* getelementptr (i8* null, i32 -1)
178; OPT: }
179; OPT: define i1* @hoo1() nounwind {
180; OPT:   ret i1* getelementptr (i1* null, i32 -1)
181; OPT: }
182; TO: define i8* @goo8() nounwind {
183; TO:   ret i8* null
184; TO: }
185; TO: define i1* @goo1() nounwind {
186; TO:   ret i1* null
187; TO: }
188; TO: define i8* @foo8() nounwind {
189; TO:   ret i8* inttoptr (i64 -1 to i8*)
190; TO: }
191; TO: define i1* @foo1() nounwind {
192; TO:   ret i1* inttoptr (i64 -1 to i1*)
193; TO: }
194; TO: define i8* @hoo8() nounwind {
195; TO:   ret i8* inttoptr (i64 -1 to i8*)
196; TO: }
197; TO: define i1* @hoo1() nounwind {
198; TO:   ret i1* inttoptr (i64 -1 to i1*)
199; TO: }
200; SCEV: Classifying expressions for: @goo8
201; SCEV:   %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1) to i8*
202; SCEV:   -->  ((-1 * sizeof(i8)) + inttoptr (i32 1 to i8*))
203; SCEV: Classifying expressions for: @goo1
204; SCEV:   %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1) to i1*
205; SCEV:   -->  ((-1 * sizeof(i1)) + inttoptr (i32 1 to i1*))
206; SCEV: Classifying expressions for: @foo8
207; SCEV:   %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2) to i8*
208; SCEV:   -->  ((-2 * sizeof(i8)) + inttoptr (i32 1 to i8*))
209; SCEV: Classifying expressions for: @foo1
210; SCEV:   %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2) to i1*
211; SCEV:   -->  ((-2 * sizeof(i1)) + inttoptr (i32 1 to i1*))
212; SCEV: Classifying expressions for: @hoo8
213; SCEV:   -->  (-1 * sizeof(i8))
214; SCEV: Classifying expressions for: @hoo1
215; SCEV:   -->  (-1 * sizeof(i1))
216
217define i8* @goo8() nounwind {
218  %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1) to i8*
219  ret i8* %t
220}
221define i1* @goo1() nounwind {
222  %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1) to i1*
223  ret i1* %t
224}
225define i8* @foo8() nounwind {
226  %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2) to i8*
227  ret i8* %t
228}
229define i1* @foo1() nounwind {
230  %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2) to i1*
231  ret i1* %t
232}
233define i8* @hoo8() nounwind {
234  %t = bitcast i8* getelementptr (i8* inttoptr (i32 0 to i8*), i32 -1) to i8*
235  ret i8* %t
236}
237define i1* @hoo1() nounwind {
238  %t = bitcast i1* getelementptr (i1* inttoptr (i32 0 to i1*), i32 -1) to i1*
239  ret i1* %t
240}
241
242; PLAIN: define i64 @fa() nounwind {
243; PLAIN:   %t = bitcast i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310) to i64
244; PLAIN:   ret i64 %t
245; PLAIN: }
246; PLAIN: define i64 @fb() nounwind {
247; PLAIN:   %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
248; PLAIN:   ret i64 %t
249; PLAIN: }
250; PLAIN: define i64 @fc() nounwind {
251; PLAIN:   %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2) to i64
252; PLAIN:   ret i64 %t
253; PLAIN: }
254; PLAIN: define i64 @fd() nounwind {
255; PLAIN:   %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11) to i64
256; PLAIN:   ret i64 %t
257; PLAIN: }
258; PLAIN: define i64 @fe() nounwind {
259; PLAIN:   %t = bitcast i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64) to i64
260; PLAIN:   ret i64 %t
261; PLAIN: }
262; PLAIN: define i64 @ff() nounwind {
263; PLAIN:   %t = bitcast i64 1 to i64
264; PLAIN:   ret i64 %t
265; PLAIN: }
266; PLAIN: define i64 @fg() nounwind {
267; PLAIN:   %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
268; PLAIN:   ret i64 %t
269; PLAIN: }
270; PLAIN: define i64 @fh() nounwind {
271; PLAIN:   %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64) to i64
272; PLAIN:   ret i64 %t
273; PLAIN: }
274; PLAIN: define i64 @fi() nounwind {
275; PLAIN:   %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64) to i64
276; PLAIN:   ret i64 %t
277; PLAIN: }
278; PLAIN: define i64 @fj() nounwind {
279; PLAIN:   %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
280; PLAIN:   ret i64 %t
281; PLAIN: }
282; PLAIN: define i64 @fk() nounwind {
283; PLAIN:   %t = bitcast i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64) to i64
284; PLAIN:   ret i64 %t
285; PLAIN: }
286; OPT: define i64 @fa() nounwind {
287; OPT:   ret i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
288; OPT: }
289; OPT: define i64 @fb() nounwind {
290; OPT:   ret i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
291; OPT: }
292; OPT: define i64 @fc() nounwind {
293; OPT:   ret i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
294; OPT: }
295; OPT: define i64 @fd() nounwind {
296; OPT:   ret i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
297; OPT: }
298; OPT: define i64 @fe() nounwind {
299; OPT:   ret i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64)
300; OPT: }
301; OPT: define i64 @ff() nounwind {
302; OPT:   ret i64 1
303; OPT: }
304; OPT: define i64 @fg() nounwind {
305; OPT:   ret i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
306; OPT: }
307; OPT: define i64 @fh() nounwind {
308; OPT:   ret i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
309; OPT: }
310; OPT: define i64 @fi() nounwind {
311; OPT:   ret i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
312; OPT: }
313; OPT: define i64 @fj() nounwind {
314; OPT:   ret i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
315; OPT: }
316; OPT: define i64 @fk() nounwind {
317; OPT:   ret i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
318; OPT: }
319; TO: define i64 @fa() nounwind {
320; TO:   ret i64 18480
321; TO: }
322; TO: define i64 @fb() nounwind {
323; TO:   ret i64 8
324; TO: }
325; TO: define i64 @fc() nounwind {
326; TO:   ret i64 16
327; TO: }
328; TO: define i64 @fd() nounwind {
329; TO:   ret i64 88
330; TO: }
331; TO: define i64 @fe() nounwind {
332; TO:   ret i64 16
333; TO: }
334; TO: define i64 @ff() nounwind {
335; TO:   ret i64 1
336; TO: }
337; TO: define i64 @fg() nounwind {
338; TO:   ret i64 8
339; TO: }
340; TO: define i64 @fh() nounwind {
341; TO:   ret i64 8
342; TO: }
343; TO: define i64 @fi() nounwind {
344; TO:   ret i64 8
345; TO: }
346; TO: define i64 @fj() nounwind {
347; TO:   ret i64 8
348; TO: }
349; TO: define i64 @fk() nounwind {
350; TO:   ret i64 8
351; TO: }
352; SCEV: Classifying expressions for: @fa
353; SCEV:   %t = bitcast i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310) to i64 
354; SCEV:   -->  (2310 * sizeof(double))
355; SCEV: Classifying expressions for: @fb
356; SCEV:   %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64 
357; SCEV:   -->  alignof(double)
358; SCEV: Classifying expressions for: @fc
359; SCEV:   %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2) to i64 
360; SCEV:   -->  (2 * sizeof(double))
361; SCEV: Classifying expressions for: @fd
362; SCEV:   %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11) to i64 
363; SCEV:   -->  (11 * sizeof(double))
364; SCEV: Classifying expressions for: @fe
365; SCEV:   %t = bitcast i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64) to i64 
366; SCEV:   -->  offsetof({ double, float, double, double }, 2)
367; SCEV: Classifying expressions for: @ff
368; SCEV:   %t = bitcast i64 1 to i64 
369; SCEV:   -->  1
370; SCEV: Classifying expressions for: @fg
371; SCEV:   %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
372; SCEV:   -->  alignof(double)
373; SCEV: Classifying expressions for: @fh
374; SCEV:   %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64) to i64
375; SCEV:   -->  sizeof(i1*)
376; SCEV: Classifying expressions for: @fi
377; SCEV:   %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64) to i64
378; SCEV:   -->  alignof(i1*)
379; SCEV: Classifying expressions for: @fj
380; SCEV:   %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
381; SCEV:   -->  alignof(double)
382; SCEV: Classifying expressions for: @fk
383; SCEV:   %t = bitcast i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64) to i64
384; SCEV:   -->  sizeof(double)
385
386define i64 @fa() nounwind {
387  %t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}* null, i64 11) to i64), i64 5)) to i64
388  ret i64 %t
389}
390define i64 @fb() nounwind {
391  %t = bitcast i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}* null, i64 0, i32 1) to i64) to i64
392  ret i64 %t
393}
394define i64 @fc() nounwind {
395  %t = bitcast i64 ptrtoint (double* getelementptr ({double, double, double, double}* null, i64 0, i32 2) to i64) to i64
396  ret i64 %t
397}
398define i64 @fd() nounwind {
399  %t = bitcast i64 ptrtoint (double* getelementptr ([13 x double]* null, i64 0, i32 11) to i64) to i64
400  ret i64 %t
401}
402define i64 @fe() nounwind {
403  %t = bitcast i64 ptrtoint (double* getelementptr ({double, float, double, double}* null, i64 0, i32 2) to i64) to i64
404  ret i64 %t
405}
406define i64 @ff() nounwind {
407  %t = bitcast i64 ptrtoint (<{ i16, i128 }>* getelementptr ({i1, <{ i16, i128 }>}* null, i64 0, i32 1) to i64) to i64
408  ret i64 %t
409}
410define i64 @fg() nounwind {
411  %t = bitcast i64 ptrtoint ({double, double}* getelementptr ({i1, {double, double}}* null, i64 0, i32 1) to i64) to i64
412  ret i64 %t
413}
414define i64 @fh() nounwind {
415  %t = bitcast i64 ptrtoint (double** getelementptr (double** null, i32 1) to i64) to i64
416  ret i64 %t
417}
418define i64 @fi() nounwind {
419  %t = bitcast i64 ptrtoint (double** getelementptr ({i1, double*}* null, i64 0, i32 1) to i64) to i64
420  ret i64 %t
421}
422define i64 @fj() nounwind {
423  %t = bitcast i64 ptrtoint (union {double, double}* getelementptr ({i1, union {double, double}}* null, i64 0, i32 1) to i64) to i64
424  ret i64 %t
425}
426define i64 @fk() nounwind {
427  %t = bitcast i64 ptrtoint (union {double, double}* getelementptr (union {double, double}* null, i64 1) to i64) to i64
428  ret i64 %t
429}
430
431; PLAIN: define i64* @fM() nounwind {
432; PLAIN:   %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*
433; PLAIN:   ret i64* %t
434; PLAIN: }
435; PLAIN: define i64* @fN() nounwind {
436; PLAIN:   %t = bitcast i64* getelementptr (%3* null, i32 0, i32 1) to i64*
437; PLAIN:   ret i64* %t
438; PLAIN: }
439; PLAIN: define i64* @fO() nounwind {
440; PLAIN:   %t = bitcast i64* getelementptr ([2 x i64]* null, i32 0, i32 1) to i64*
441; PLAIN:   ret i64* %t
442; PLAIN: }
443; OPT: define i64* @fM() nounwind {
444; OPT:   ret i64* getelementptr (i64* null, i32 1)
445; OPT: }
446; OPT: define i64* @fN() nounwind {
447; OPT:   ret i64* getelementptr (%3* null, i32 0, i32 1)
448; OPT: }
449; OPT: define i64* @fO() nounwind {
450; OPT:   ret i64* getelementptr ([2 x i64]* null, i32 0, i32 1)
451; OPT: }
452; TO: define i64* @fM() nounwind {
453; TO:   ret i64* inttoptr (i64 8 to i64*)
454; TO: }
455; TO: define i64* @fN() nounwind {
456; TO:   ret i64* inttoptr (i64 8 to i64*)
457; TO: }
458; TO: define i64* @fO() nounwind {
459; TO:   ret i64* inttoptr (i64 8 to i64*)
460; TO: }
461; SCEV: Classifying expressions for: @fM
462; SCEV:   %t = bitcast i64* getelementptr (i64* null, i32 1) to i64* 
463; SCEV:   -->  sizeof(i64)
464; SCEV: Classifying expressions for: @fN
465; SCEV:   %t = bitcast i64* getelementptr (%3* null, i32 0, i32 1) to i64* 
466; SCEV:   -->  sizeof(i64)
467; SCEV: Classifying expressions for: @fO
468; SCEV:   %t = bitcast i64* getelementptr ([2 x i64]* null, i32 0, i32 1) to i64* 
469; SCEV:   -->  sizeof(i64)
470
471define i64* @fM() nounwind {
472  %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*
473  ret i64* %t
474}
475define i64* @fN() nounwind {
476  %t = bitcast i64* getelementptr ({ i64, i64 }* null, i32 0, i32 1) to i64*
477  ret i64* %t
478}
479define i64* @fO() nounwind {
480  %t = bitcast i64* getelementptr ([2 x i64]* null, i32 0, i32 1) to i64*
481  ret i64* %t
482}
483
484; PLAIN: define i32* @fZ() nounwind {
485; PLAIN:   %t = bitcast i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x %4]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
486; PLAIN:   ret i32* %t
487; PLAIN: }
488; OPT: define i32* @fZ() nounwind {
489; OPT:   ret i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x %4]* @ext, i64 0, i64 1, i32 0), i64 1)
490; OPT: }
491; TO: define i32* @fZ() nounwind {
492; TO:   ret i32* getelementptr inbounds ([3 x %0]* @ext, i64 0, i64 1, i32 1)
493; TO: }
494; SCEV: Classifying expressions for: @fZ
495; SCEV:   %t = bitcast i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x %4]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
496; SCEV:   -->  ((3 * sizeof(i32)) + @ext)
497
498define i32* @fZ() nounwind {
499  %t = bitcast i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
500  ret i32* %t
501}
502