74fe31613773a07f82ed1908da9b5eac2782d5c7
[oota-llvm.git] / test / Transforms / InstCombine / constant-fold-gep-as-0.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 target datalayout = "e-p:128:128:128-p1:32:32:32-p2:8:8:8-p3:16:16:16-p4:64:64:64-p5:96:96:96-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32"
6
7 ; PLAIN: ModuleID = '<stdin>'
8
9 ; The automatic constant folder in opt does not have targetdata access, so
10 ; it can't fold gep arithmetic, in general. However, the constant folder run
11 ; from instcombine and global opt can use targetdata.
12 ; PLAIN: @G8 = global i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -1)
13 @G8 = global i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -1)
14 ; PLAIN: @G1 = global i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i8 1 to i1 addrspace(2)*), i8 -1)
15 @G1 = global i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i8 1 to i1 addrspace(2)*), i8 -1)
16 ; PLAIN: @F8 = global i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -2)
17 @F8 = global i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -2)
18 ; PLAIN: @F1 = global i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i8 1 to i1 addrspace(2)*), i8 -2)
19 @F1 = global i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i8 1 to i1 addrspace(2)*), i8 -2)
20 ; PLAIN: @H8 = global i8 addrspace(1)* getelementptr (i8 addrspace(1)* null, i32 -1)
21 @H8 = global i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 0 to i8 addrspace(1)*), i32 -1)
22 ; PLAIN: @H1 = global i1 addrspace(2)* getelementptr (i1 addrspace(2)* null, i8 -1)
23 @H1 = global i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i8 0 to i1 addrspace(2)*), i8 -1)
24
25
26 ; The target-independent folder should be able to do some clever
27 ; simplifications on sizeof, alignof, and offsetof expressions. The
28 ; target-dependent folder should fold these down to constants.
29 ; PLAIN-X: @a = constant i64 mul (i64 ptrtoint (double addrspace(4)* getelementptr (double addrspace(4)* null, i32 1) to i64), i64 2310)
30 @a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]} addrspace(4)* getelementptr ({[7 x double], [7 x double]} addrspace(4)* null, i64 11) to i64), i64 5))
31
32 ; PLAIN-X: @b = constant i64 ptrtoint (double addrspace(4)* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64)
33 @b = constant i64 ptrtoint ([13 x double] addrspace(4)* getelementptr ({i1, [13 x double]} addrspace(4)* null, i64 0, i32 1) to i64)
34
35 ; PLAIN-X: @c = constant i64 mul nuw (i64 ptrtoint (double addrspace(4)* getelementptr (double addrspace(4)* null, i32 1) to i64), i64 2)
36 @c = constant i64 ptrtoint (double addrspace(4)* getelementptr ({double, double, double, double} addrspace(4)* null, i64 0, i32 2) to i64)
37
38 ; PLAIN-X: @d = constant i64 mul nuw (i64 ptrtoint (double addrspace(4)* getelementptr (double addrspace(4)* null, i32 1) to i64), i64 11)
39 @d = constant i64 ptrtoint (double addrspace(4)* getelementptr ([13 x double] addrspace(4)* null, i64 0, i32 11) to i64)
40
41 ; PLAIN-X: @e = constant i64 ptrtoint (double addrspace(4)* getelementptr ({ double, float, double, double }* null, i64 0, i32 2) to i64)
42 @e = constant i64 ptrtoint (double addrspace(4)* getelementptr ({double, float, double, double} addrspace(4)* null, i64 0, i32 2) to i64)
43
44 ; PLAIN-X: @f = constant i64 1
45 @f = constant i64 ptrtoint (<{ i16, i128 }> addrspace(4)* getelementptr ({i1, <{ i16, i128 }>} addrspace(4)* null, i64 0, i32 1) to i64)
46
47 ; PLAIN-X: @g = constant i64 ptrtoint (double addrspace(4)* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64)
48 @g = constant i64 ptrtoint ({double, double} addrspace(4)* getelementptr ({i1, {double, double}} addrspace(4)* null, i64 0, i32 1) to i64)
49
50 ; PLAIN-X: @h = constant i64 ptrtoint (i1 addrspace(2)* getelementptr (i1 addrspace(2)* null, i32 1) to i64)
51 @h = constant i64 ptrtoint (double addrspace(4)* getelementptr (double addrspace(4)* null, i64 1) to i64)
52
53 ; PLAIN-X: @i = constant i64 ptrtoint (i1 addrspace(2)* getelementptr ({ i1, i1 addrspace(2)* }* null, i64 0, i32 1) to i64)
54 @i = constant i64 ptrtoint (double addrspace(4)* getelementptr ({i1, double} addrspace(4)* null, i64 0, i32 1) to i64)
55
56 ; The target-dependent folder should cast GEP indices to integer-sized pointers.
57
58 ; PLAIN: @M = constant i64 addrspace(5)* getelementptr (i64 addrspace(5)* null, i32 1)
59 ; PLAIN: @N = constant i64 addrspace(5)* getelementptr ({ i64, i64 } addrspace(5)* null, i32 0, i32 1)
60 ; PLAIN: @O = constant i64 addrspace(5)* getelementptr ([2 x i64] addrspace(5)* null, i32 0, i32 1)
61
62 @M = constant i64 addrspace(5)* getelementptr (i64 addrspace(5)* null, i32 1)
63 @N = constant i64 addrspace(5)* getelementptr ({ i64, i64 } addrspace(5)* null, i32 0, i32 1)
64 @O = constant i64 addrspace(5)* getelementptr ([2 x i64] addrspace(5)* null, i32 0, i32 1)
65
66 ; Fold GEP of a GEP. Very simple cases are folded.
67
68 ; PLAIN-X: @Y = global [3 x { i32, i32 }]addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }]addrspace(3)* @ext, i64 2)
69 @ext = external addrspace(3) global [3 x { i32, i32 }]
70 @Y = global [3 x { i32, i32 }]addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }]addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }]addrspace(3)* @ext, i64 1), i64 1)
71
72 ; PLAIN-X: @Z = global i32addrspace(3)* getelementptr inbounds (i32addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }]addrspace(3)* @ext, i64 0, i64 1, i32 0), i64 1)
73 @Z = global i32addrspace(3)* getelementptr inbounds (i32addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }]addrspace(3)* @ext, i64 0, i64 1, i32 0), i64 1)
74
75
76 ; Duplicate all of the above as function return values rather than
77 ; global initializers.
78
79 ; PLAIN: define i8 addrspace(1)* @goo8() nounwind {
80 ; PLAIN:   %t = bitcast i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -1) to i8 addrspace(1)*
81 ; PLAIN:   ret i8 addrspace(1)* %t
82 ; PLAIN: }
83 ; PLAIN: define i1 addrspace(2)* @goo1() nounwind {
84 ; PLAIN:   %t = bitcast i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i32 1 to i1 addrspace(2)*), i32 -1) to i1 addrspace(2)*
85 ; PLAIN:   ret i1 addrspace(2)* %t
86 ; PLAIN: }
87 ; PLAIN: define i8 addrspace(1)* @foo8() nounwind {
88 ; PLAIN:   %t = bitcast i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -2) to i8 addrspace(1)*
89 ; PLAIN:   ret i8 addrspace(1)* %t
90 ; PLAIN: }
91 ; PLAIN: define i1 addrspace(2)* @foo1() nounwind {
92 ; PLAIN:   %t = bitcast i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i32 1 to i1 addrspace(2)*), i32 -2) to i1 addrspace(2)*
93 ; PLAIN:   ret i1 addrspace(2)* %t
94 ; PLAIN: }
95 ; PLAIN: define i8 addrspace(1)* @hoo8() nounwind {
96 ; PLAIN:   %t = bitcast i8 addrspace(1)* getelementptr (i8 addrspace(1)* null, i32 -1) to i8 addrspace(1)*
97 ; PLAIN:   ret i8 addrspace(1)* %t
98 ; PLAIN: }
99 ; PLAIN: define i1 addrspace(2)* @hoo1() nounwind {
100 ; PLAIN:   %t = bitcast i1 addrspace(2)* getelementptr (i1 addrspace(2)* null, i32 -1) to i1 addrspace(2)*
101 ; PLAIN:   ret i1 addrspace(2)* %t
102 ; PLAIN: }
103 define i8 addrspace(1)* @goo8() nounwind {
104   %t = bitcast i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -1) to i8 addrspace(1)*
105   ret i8 addrspace(1)* %t
106 }
107 define i1 addrspace(2)* @goo1() nounwind {
108   %t = bitcast i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i32 1 to i1 addrspace(2)*), i32 -1) to i1 addrspace(2)*
109   ret i1 addrspace(2)* %t
110 }
111 define i8 addrspace(1)* @foo8() nounwind {
112   %t = bitcast i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -2) to i8 addrspace(1)*
113   ret i8 addrspace(1)* %t
114 }
115 define i1 addrspace(2)* @foo1() nounwind {
116   %t = bitcast i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i32 1 to i1 addrspace(2)*), i32 -2) to i1 addrspace(2)*
117   ret i1 addrspace(2)* %t
118 }
119 define i8 addrspace(1)* @hoo8() nounwind {
120   %t = bitcast i8 addrspace(1)* getelementptr (i8 addrspace(1)* inttoptr (i32 0 to i8 addrspace(1)*), i32 -1) to i8 addrspace(1)*
121   ret i8 addrspace(1)* %t
122 }
123 define i1 addrspace(2)* @hoo1() nounwind {
124   %t = bitcast i1 addrspace(2)* getelementptr (i1 addrspace(2)* inttoptr (i32 0 to i1 addrspace(2)*), i32 -1) to i1 addrspace(2)*
125   ret i1 addrspace(2)* %t
126 }
127
128 ; PLAIN-X: define i64 @fa() nounwind {
129 ; PLAIN-X:   %t = bitcast i64 mul (i64 ptrtoint (double addrspace(4)* getelementptr (double addrspace(4)* null, i32 1) to i64), i64 2310) to i64
130 ; PLAIN-X:   ret i64 %t
131 ; PLAIN-X: }
132 ; PLAIN-X: define i64 @fb() nounwind {
133 ; PLAIN-X:   %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64) to i64
134 ; PLAIN-X:   ret i64 %t
135 ; PLAIN-X: }
136 ; PLAIN-X: define i64 @fc() nounwind {
137 ; PLAIN-X:   %t = bitcast i64 mul nuw (i64 ptrtoint (double addrspace(4)* getelementptr (double addrspace(4)* null, i32 1) to i64), i64 2) to i64
138 ; PLAIN-X:   ret i64 %t
139 ; PLAIN-X: }
140 ; PLAIN-X: define i64 @fd() nounwind {
141 ; PLAIN-X:   %t = bitcast i64 mul nuw (i64 ptrtoint (double addrspace(4)* getelementptr (double addrspace(4)* null, i32 1) to i64), i64 11) to i64
142 ; PLAIN-X:   ret i64 %t
143 ; PLAIN-X: }
144 ; PLAIN-X: define i64 @fe() nounwind {
145 ; PLAIN-X:   %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({ double, float, double, double }* null, i64 0, i32 2) to i64) to i64
146 ; PLAIN-X:   ret i64 %t
147 ; PLAIN-X: }
148 ; PLAIN-X: define i64 @ff() nounwind {
149 ; PLAIN-X:   %t = bitcast i64 1 to i64
150 ; PLAIN-X:   ret i64 %t
151 ; PLAIN-X: }
152 ; PLAIN-X: define i64 @fg() nounwind {
153 ; PLAIN-X:   %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64) to i64
154 ; PLAIN-X:   ret i64 %t
155 ; PLAIN-X: }
156 ; PLAIN-X: define i64 @fh() nounwind {
157 ; PLAIN-X:   %t = bitcast i64 ptrtoint (i1 addrspace(2)* getelementptr (i1 addrspace(2)* null, i32 1) to i64) to i64
158 ; PLAIN-X:   ret i64 %t
159 ; PLAIN-X: }
160 ; PLAIN-X: define i64 @fi() nounwind {
161 ; PLAIN-X:   %t = bitcast i64 ptrtoint (i1 addrspace(2)* getelementptr ({ i1, i1 addrspace(2)* }* null, i64 0, i32 1) to i64) to i64
162 ; PLAIN-X:   ret i64 %t
163 ; PLAIN-X: }
164 define i64 @fa() nounwind {
165   %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
166   ret i64 %t
167 }
168 define i64 @fb() nounwind {
169   %t = bitcast i64 ptrtoint ([13 x double] addrspace(4)* getelementptr ({i1, [13 x double]} addrspace(4)* null, i64 0, i32 1) to i64) to i64
170   ret i64 %t
171 }
172 define i64 @fc() nounwind {
173   %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({double, double, double, double} addrspace(4)* null, i64 0, i32 2) to i64) to i64
174   ret i64 %t
175 }
176 define i64 @fd() nounwind {
177   %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ([13 x double] addrspace(4)* null, i64 0, i32 11) to i64) to i64
178   ret i64 %t
179 }
180 define i64 @fe() nounwind {
181   %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({double, float, double, double} addrspace(4)* null, i64 0, i32 2) to i64) to i64
182   ret i64 %t
183 }
184 define i64 @ff() nounwind {
185   %t = bitcast i64 ptrtoint (<{ i16, i128 }> addrspace(4)* getelementptr ({i1, <{ i16, i128 }>} addrspace(4)* null, i64 0, i32 1) to i64) to i64
186   ret i64 %t
187 }
188 define i64 @fg() nounwind {
189   %t = bitcast i64 ptrtoint ({double, double} addrspace(4)* getelementptr ({i1, {double, double}} addrspace(4)* null, i64 0, i32 1) to i64) to i64
190   ret i64 %t
191 }
192 define i64 @fh() nounwind {
193   %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr (double addrspace(4)* null, i32 1) to i64) to i64
194   ret i64 %t
195 }
196 define i64 @fi() nounwind {
197   %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({i1, double}addrspace(4)* null, i64 0, i32 1) to i64) to i64
198   ret i64 %t
199 }
200
201 ; PLAIN: define i64* @fM() nounwind {
202 ; PLAIN:   %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*
203 ; PLAIN:   ret i64* %t
204 ; PLAIN: }
205 ; PLAIN: define i64* @fN() nounwind {
206 ; PLAIN:   %t = bitcast i64* getelementptr ({ i64, i64 }* null, i32 0, i32 1) to i64*
207 ; PLAIN:   ret i64* %t
208 ; PLAIN: }
209 ; PLAIN: define i64* @fO() nounwind {
210 ; PLAIN:   %t = bitcast i64* getelementptr ([2 x i64]* null, i32 0, i32 1) to i64*
211 ; PLAIN:   ret i64* %t
212 ; PLAIN: }
213
214 define i64* @fM() nounwind {
215   %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*
216   ret i64* %t
217 }
218 define i64* @fN() nounwind {
219   %t = bitcast i64* getelementptr ({ i64, i64 }* null, i32 0, i32 1) to i64*
220   ret i64* %t
221 }
222 define i64* @fO() nounwind {
223   %t = bitcast i64* getelementptr ([2 x i64]* null, i32 0, i32 1) to i64*
224   ret i64* %t
225 }
226
227 ; PLAIN: define i32 addrspace(1)* @fZ() nounwind {
228 ; PLAIN:   %t = bitcast i32 addrspace(1)* getelementptr inbounds (i32 addrspace(1)* getelementptr inbounds ([3 x { i32, i32 }] addrspace(1)* @ext2, i64 0, i64 1, i32 0), i64 1) to i32 addrspace(1)*
229 ; PLAIN:   ret i32 addrspace(1)* %t
230 ; PLAIN: }
231 @ext2 = external addrspace(1) global [3 x { i32, i32 }]
232 define i32 addrspace(1)* @fZ() nounwind {
233   %t = bitcast i32 addrspace(1)* getelementptr inbounds (i32 addrspace(1)* getelementptr inbounds ([3 x { i32, i32 }] addrspace(1)* @ext2, i64 0, i64 1, i32 0), i64 1) to i32 addrspace(1)*
234   ret i32 addrspace(1)* %t
235 }