xref: /llvm-project/llvm/test/Other/constant-fold-gep-address-spaces.ll (revision 38386b4318e3ba54f450480ad49b237a9c357af4)
1; "PLAIN" - No optimizations. This tests the target-independent
2; constant folder.
3; RUN: opt -S -o - %s | FileCheck --check-prefix=PLAIN %s
4
5target 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 ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -1)
11@G8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -1)
12; PLAIN: @G1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 1 to ptr addrspace(2)), i8 -1)
13@G1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 1 to ptr addrspace(2)), i8 -1)
14; PLAIN: @F8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -2)
15@F8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -2)
16; PLAIN: @F1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 1 to ptr addrspace(2)), i8 -2)
17@F1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 1 to ptr addrspace(2)), i8 -2)
18; PLAIN: @H8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i32 -1)
19@H8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 0 to ptr addrspace(1)), i32 -1)
20; PLAIN: @H1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) null, i8 -1)
21@H1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 0 to ptr 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 (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2310)
28@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint (ptr addrspace(4) getelementptr ({[7 x double], [7 x double]}, ptr addrspace(4) null, i64 11) to i64), i64 5))
29
30; PLAIN-X: @b = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({ i1, double }, ptr null, i64 0, i32 1) to i64)
31@b = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, [13 x double]}, ptr addrspace(4) null, i64 0, i32 1) to i64)
32
33; PLAIN-X: @c = constant i64 mul nuw (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2)
34@c = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({double, double, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64)
35
36; PLAIN-X: @d = constant i64 mul nuw (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 11)
37@d = constant i64 ptrtoint (ptr addrspace(4) getelementptr ([13 x double], ptr addrspace(4) null, i64 0, i32 11) to i64)
38
39; PLAIN-X: @e = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({ double, float, double, double }, ptr null, i64 0, i32 2) to i64)
40@e = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({double, float, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64)
41
42; PLAIN-X: @f = constant i64 1
43@f = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, <{ i16, i128 }>}, ptr addrspace(4) null, i64 0, i32 1) to i64)
44
45; PLAIN-X: @g = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({ i1, double }, ptr null, i64 0, i32 1) to i64)
46@g = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, {double, double}}, ptr addrspace(4) null, i64 0, i32 1) to i64)
47
48; PLAIN-X: @h = constant i64 ptrtoint (ptr addrspace(2) getelementptr (i1, ptr addrspace(2) null, i32 1) to i64)
49@h = constant i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i64 1) to i64)
50
51; PLAIN-X: @i = constant i64 ptrtoint (ptr addrspace(2) getelementptr ({ i1, ptr addrspace(2) }, ptr null, i64 0, i32 1) to i64)
52@i = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, double}, ptr 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 ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 1)
57; PLAIN: @N = constant ptr addrspace(4) getelementptr ({ i64, i64 }, ptr addrspace(4) null, i32 0, i32 1)
58; PLAIN: @O = constant ptr addrspace(4) getelementptr ([2 x i64], ptr addrspace(4) null, i32 0, i32 1)
59
60@M = constant ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 1)
61@N = constant ptr addrspace(4) getelementptr ({ i64, i64 }, ptr addrspace(4) null, i32 0, i32 1)
62@O = constant ptr addrspace(4) getelementptr ([2 x i64], ptr 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 ptraddrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptraddrspace(3) @ext, i64 2)
67@ext = external addrspace(3) global [3 x { i32, i32 }]
68@Y = global ptr addrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(3) @ext, i64 1), i64 1)
69
70; PLAIN-X: @Z = global ptraddrspace(3) getelementptr inbounds (i32, ptr addrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(3) @ext, i64 0, i64 1, i32 0), i64 1)
71@Z = global ptr addrspace(3) getelementptr inbounds (i32, ptr addrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptr 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 ptr addrspace(1) @goo8() #0 {
78; PLAIN:   %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -1) to ptr addrspace(1)
79; PLAIN:   ret ptr addrspace(1) %t
80; PLAIN: }
81; PLAIN: define ptr addrspace(2) @goo1() #0 {
82; PLAIN:   %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 1 to ptr addrspace(2)), i32 -1) to ptr addrspace(2)
83; PLAIN:   ret ptr addrspace(2) %t
84; PLAIN: }
85; PLAIN: define ptr addrspace(1) @foo8() #0 {
86; PLAIN:   %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -2) to ptr addrspace(1)
87; PLAIN:   ret ptr addrspace(1) %t
88; PLAIN: }
89; PLAIN: define ptr addrspace(2) @foo1() #0 {
90; PLAIN:   %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 1 to ptr addrspace(2)), i32 -2) to ptr addrspace(2)
91; PLAIN:   ret ptr addrspace(2) %t
92; PLAIN: }
93; PLAIN: define ptr addrspace(1) @hoo8() #0 {
94; PLAIN:   %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i32 -1) to ptr addrspace(1)
95; PLAIN:   ret ptr addrspace(1) %t
96; PLAIN: }
97; PLAIN: define ptr addrspace(2) @hoo1() #0 {
98; PLAIN:   %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) null, i32 -1) to ptr addrspace(2)
99; PLAIN:   ret ptr addrspace(2) %t
100; PLAIN: }
101define ptr addrspace(1) @goo8() #0 {
102  %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -1) to ptr addrspace(1)
103  ret ptr addrspace(1) %t
104}
105define ptr addrspace(2) @goo1() #0 {
106  %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 1 to ptr addrspace(2)), i32 -1) to ptr addrspace(2)
107  ret ptr addrspace(2) %t
108}
109define ptr addrspace(1) @foo8() #0 {
110  %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -2) to ptr addrspace(1)
111  ret ptr addrspace(1) %t
112}
113define ptr addrspace(2) @foo1() #0 {
114  %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 1 to ptr addrspace(2)), i32 -2) to ptr addrspace(2)
115  ret ptr addrspace(2) %t
116}
117define ptr addrspace(1) @hoo8() #0 {
118  %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 0 to ptr addrspace(1)), i32 -1) to ptr addrspace(1)
119  ret ptr addrspace(1) %t
120}
121define ptr addrspace(2) @hoo1() #0 {
122  %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 0 to ptr addrspace(2)), i32 -1) to ptr addrspace(2)
123  ret ptr addrspace(2) %t
124}
125
126; PLAIN-X: define i64 @fa() #0 {
127; PLAIN-X:   %t = bitcast i64 mul (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr 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 (ptr addrspace(4) getelementptr ({ i1, double }, ptr 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 (ptr addrspace(4) getelementptr (double, ptr 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 (ptr addrspace(4) getelementptr (double, ptr 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 (ptr addrspace(4) getelementptr ({ double, float, double, double }, ptr 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 (ptr addrspace(4) getelementptr ({ i1, double }, ptr 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 (ptr addrspace(2) getelementptr (i1, ptr 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 (ptr addrspace(2) getelementptr ({ i1, ptr addrspace(2) }, ptr null, i64 0, i32 1) to i64) to i64
160; PLAIN-X:   ret i64 %t
161; PLAIN-X: }
162define i64 @fa() #0 {
163  %t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint (ptr getelementptr ({[7 x double], [7 x double]}, ptr null, i64 11) to i64), i64 5)) to i64
164  ret i64 %t
165}
166define i64 @fb() #0 {
167  %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, [13 x double]}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64
168  ret i64 %t
169}
170define i64 @fc() #0 {
171  %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({double, double, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64) to i64
172  ret i64 %t
173}
174define i64 @fd() #0 {
175  %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ([13 x double], ptr addrspace(4) null, i64 0, i32 11) to i64) to i64
176  ret i64 %t
177}
178define i64 @fe() #0 {
179  %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({double, float, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64) to i64
180  ret i64 %t
181}
182define i64 @ff() #0 {
183  %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, <{ i16, i128 }>}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64
184  ret i64 %t
185}
186define i64 @fg() #0 {
187  %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, {double, double}}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64
188  ret i64 %t
189}
190define i64 @fh() #0 {
191  %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64) to i64
192  ret i64 %t
193}
194define i64 @fi() #0 {
195  %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, double}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64
196  ret i64 %t
197}
198
199; PLAIN: define ptr @fM() #0 {
200; PLAIN:   %t = bitcast ptr getelementptr (i64, ptr null, i32 1) to ptr
201; PLAIN:   ret ptr %t
202; PLAIN: }
203; PLAIN: define ptr @fN() #0 {
204; PLAIN:   %t = bitcast ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) to ptr
205; PLAIN:   ret ptr %t
206; PLAIN: }
207; PLAIN: define ptr @fO() #0 {
208; PLAIN:   %t = bitcast ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) to ptr
209; PLAIN:   ret ptr %t
210; PLAIN: }
211
212define ptr @fM() #0 {
213  %t = bitcast ptr getelementptr (i64, ptr null, i32 1) to ptr
214  ret ptr %t
215}
216define ptr @fN() #0 {
217  %t = bitcast ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) to ptr
218  ret ptr %t
219}
220define ptr @fO() #0 {
221  %t = bitcast ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) to ptr
222  ret ptr %t
223}
224
225; PLAIN: define ptr addrspace(1) @fZ() #0 {
226; PLAIN:   %t = bitcast ptr addrspace(1) getelementptr inbounds (i32, ptr addrspace(1) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(1) @ext2, i64 0, i64 1, i32 0), i64 1) to ptr addrspace(1)
227; PLAIN:   ret ptr addrspace(1) %t
228; PLAIN: }
229@ext2 = external addrspace(1) global [3 x { i32, i32 }]
230define ptr addrspace(1) @fZ() #0 {
231  %t = bitcast ptr addrspace(1) getelementptr inbounds (i32, ptr addrspace(1) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(1) @ext2, i64 0, i64 1, i32 0), i64 1) to ptr addrspace(1)
232  ret ptr addrspace(1) %t
233}
234
235attributes #0 = { nounwind }
236