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