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