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