1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine -opaque-pointers < %s | FileCheck %s
4 define ptr @bitcast_opaque_to_opaque(ptr %a) {
5 ; CHECK-LABEL: @bitcast_opaque_to_opaque(
6 ; CHECK-NEXT: ret ptr [[A:%.*]]
8 %b = bitcast ptr %a to ptr
12 define ptr @bitcast_typed_to_opaque(i8* %a) {
13 ; CHECK-LABEL: @bitcast_typed_to_opaque(
14 ; CHECK-NEXT: ret ptr [[A:%.*]]
16 %b = bitcast i8* %a to ptr
20 define i8* @bitcast_opaque_to_typed(ptr %a) {
21 ; CHECK-LABEL: @bitcast_opaque_to_typed(
22 ; CHECK-NEXT: ret ptr [[A:%.*]]
24 %b = bitcast ptr %a to i8*
29 define ptr @bitcast_typed_to_opaque_constexpr() {
30 ; CHECK-LABEL: @bitcast_typed_to_opaque_constexpr(
31 ; CHECK-NEXT: ret ptr @g
33 ret ptr bitcast (i8* @g to ptr)
36 define ptr @addrspacecast_opaque_to_opaque(ptr addrspace(1) %a) {
37 ; CHECK-LABEL: @addrspacecast_opaque_to_opaque(
38 ; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
39 ; CHECK-NEXT: ret ptr [[B]]
41 %b = addrspacecast ptr addrspace(1) %a to ptr
45 define ptr @addrspacecast_typed_to_opaque(i8 addrspace(1)* %a) {
46 ; CHECK-LABEL: @addrspacecast_typed_to_opaque(
47 ; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
48 ; CHECK-NEXT: ret ptr [[B]]
50 %b = addrspacecast i8 addrspace(1)* %a to ptr
54 define i8* @addrspacecast_opaque_to_typed(ptr addrspace(1) %a) {
55 ; CHECK-LABEL: @addrspacecast_opaque_to_typed(
56 ; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
57 ; CHECK-NEXT: ret ptr [[B]]
59 %b = addrspacecast ptr addrspace(1) %a to i8*
63 define ptr addrspace(1) @bitcast_and_addrspacecast_eliminable(ptr %a) {
64 ; CHECK-LABEL: @bitcast_and_addrspacecast_eliminable(
65 ; CHECK-NEXT: [[C:%.*]] = addrspacecast ptr [[A:%.*]] to ptr addrspace(1)
66 ; CHECK-NEXT: ret ptr addrspace(1) [[C]]
68 %b = bitcast ptr %a to i8*
69 %c = addrspacecast i8* %b to ptr addrspace(1)
70 ret ptr addrspace(1) %c
73 define ptr addrspace(1) @addrspacecast_typed_to_opaque_constexpr() {
74 ; CHECK-LABEL: @addrspacecast_typed_to_opaque_constexpr(
75 ; CHECK-NEXT: ret ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1))
77 ret ptr addrspace(1) addrspacecast (i8* @g to ptr addrspace(1))
80 define ptr @gep_constexpr_1(ptr %a) {
81 ; CHECK-LABEL: @gep_constexpr_1(
82 ; CHECK-NEXT: ret ptr inttoptr (i64 6 to ptr)
84 ret ptr getelementptr (i16, ptr null, i32 3)
87 define ptr @gep_constexpr_2(ptr %a) {
88 ; CHECK-LABEL: @gep_constexpr_2(
89 ; CHECK-NEXT: ret ptr getelementptr (i8, ptr @g, i64 3)
91 ret ptr getelementptr (i8, ptr bitcast (i8* @g to ptr), i32 3)
94 define ptr @load_bitcast_1(ptr %a) {
95 ; CHECK-LABEL: @load_bitcast_1(
96 ; CHECK-NEXT: [[B1:%.*]] = load ptr, ptr [[A:%.*]], align 8
97 ; CHECK-NEXT: ret ptr [[B1]]
100 %c = bitcast i8* %b to ptr
104 define ptr @load_bitcast_2(ptr %a) {
105 ; CHECK-LABEL: @load_bitcast_2(
106 ; CHECK-NEXT: [[C1:%.*]] = load ptr, ptr [[A:%.*]], align 8
107 ; CHECK-NEXT: ret ptr [[C1]]
109 %b = bitcast ptr %a to i8**
110 %c = load i8*, i8** %b
111 %d = bitcast i8* %c to ptr
115 define void @call(ptr %a) {
116 ; CHECK-LABEL: @call(
117 ; CHECK-NEXT: call void [[A:%.*]]()
118 ; CHECK-NEXT: ret void
124 declare void @varargs(...)
125 define void @varargs_cast_typed_to_opaque_same_type(i32* %a) {
126 ; CHECK-LABEL: @varargs_cast_typed_to_opaque_same_type(
127 ; CHECK-NEXT: call void (...) @varargs(ptr byval(i32) [[A:%.*]])
128 ; CHECK-NEXT: ret void
130 %b = bitcast i32* %a to ptr
131 call void (...) @varargs(ptr byval(i32) %b)
135 define void @varargs_cast_typed_to_opaque_different_type(i32* %a) {
136 ; CHECK-LABEL: @varargs_cast_typed_to_opaque_different_type(
137 ; CHECK-NEXT: call void (...) @varargs(ptr byval(float) [[A:%.*]])
138 ; CHECK-NEXT: ret void
140 %b = bitcast i32* %a to ptr
141 call void (...) @varargs(ptr byval(float) %b)
145 define void @varargs_cast_typed_to_opaque_different_size(i32* %a) {
146 ; CHECK-LABEL: @varargs_cast_typed_to_opaque_different_size(
147 ; CHECK-NEXT: call void (...) @varargs(ptr byval(i64) [[A:%.*]])
148 ; CHECK-NEXT: ret void
150 %b = bitcast i32* %a to ptr
151 call void (...) @varargs(ptr byval(i64) %b)
155 define void @varargs_cast_opaque_to_typed(ptr %a) {
156 ; CHECK-LABEL: @varargs_cast_opaque_to_typed(
157 ; CHECK-NEXT: call void (...) @varargs(ptr byval(i8) [[A:%.*]])
158 ; CHECK-NEXT: ret void
160 %b = bitcast ptr %a to i8*
161 call void (...) @varargs(i8* byval(i8) %b)
165 define ptr @geps_combinable(ptr %a) {
166 ; CHECK-LABEL: @geps_combinable(
167 ; CHECK-NEXT: [[A3:%.*]] = getelementptr { i32, { i32, i32 } }, ptr [[A:%.*]], i64 0, i32 1, i32 1
168 ; CHECK-NEXT: ret ptr [[A3]]
170 %a2 = getelementptr { i32, { i32, i32 } }, ptr %a, i32 0, i32 1
171 %a3 = getelementptr { i32, i32 }, ptr %a2, i32 0, i32 1
175 define ptr @geps_not_combinable(ptr %a) {
176 ; CHECK-LABEL: @geps_not_combinable(
177 ; CHECK-NEXT: [[A2:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 0, i32 1
178 ; CHECK-NEXT: [[A3:%.*]] = getelementptr { i32, i32 }, ptr [[A2]], i64 0, i32 1
179 ; CHECK-NEXT: ret ptr [[A3]]
181 %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
182 %a3 = getelementptr { i32, i32 }, ptr %a2, i32 0, i32 1
186 define i1 @compare_geps_same_indices(ptr %a, ptr %b, i64 %idx) {
187 ; CHECK-LABEL: @compare_geps_same_indices(
188 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A:%.*]], [[B:%.*]]
189 ; CHECK-NEXT: ret i1 [[C]]
191 %a2 = getelementptr i32, ptr %a, i64 %idx
192 %b2 = getelementptr i32, ptr %b, i64 %idx
193 %c = icmp eq ptr %a2, %b2
197 define i1 @compare_geps_same_indices_different_types(ptr %a, ptr %b, i64 %idx) {
198 ; CHECK-LABEL: @compare_geps_same_indices_different_types(
199 ; CHECK-NEXT: [[A2:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 [[IDX:%.*]]
200 ; CHECK-NEXT: [[B2:%.*]] = getelementptr i64, ptr [[B:%.*]], i64 [[IDX]]
201 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A2]], [[B2]]
202 ; CHECK-NEXT: ret i1 [[C]]
204 %a2 = getelementptr i32, ptr %a, i64 %idx
205 %b2 = getelementptr i64, ptr %b, i64 %idx
206 %c = icmp eq ptr %a2, %b2
210 define ptr @indexed_compare(ptr %A, i64 %offset) {
211 ; CHECK-LABEL: @indexed_compare(
213 ; CHECK-NEXT: br label [[BB:%.*]]
215 ; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i64 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[OFFSET:%.*]], [[ENTRY:%.*]] ]
216 ; CHECK-NEXT: [[RHS_ADD]] = add nsw i64 [[RHS_IDX]], 1
217 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[RHS_IDX]], 100
218 ; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]]
220 ; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[RHS_IDX]]
221 ; CHECK-NEXT: ret ptr [[RHS_PTR]]
224 %tmp = getelementptr inbounds i32, ptr %A, i64 %offset
228 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]
229 %LHS = getelementptr inbounds i32, ptr %A, i32 100
230 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1
231 %cond = icmp ult ptr %LHS, %RHS
232 br i1 %cond, label %bb2, label %bb
238 define ptr @indexed_compare_different_types(ptr %A, i64 %offset) {
239 ; CHECK-LABEL: @indexed_compare_different_types(
241 ; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[OFFSET:%.*]]
242 ; CHECK-NEXT: br label [[BB:%.*]]
244 ; CHECK-NEXT: [[RHS:%.*]] = phi ptr [ [[RHS_NEXT:%.*]], [[BB]] ], [ [[TMP]], [[ENTRY:%.*]] ]
245 ; CHECK-NEXT: [[LHS:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 100
246 ; CHECK-NEXT: [[RHS_NEXT]] = getelementptr inbounds i32, ptr [[RHS]], i64 1
247 ; CHECK-NEXT: [[COND:%.*]] = icmp ult ptr [[LHS]], [[RHS]]
248 ; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]]
250 ; CHECK-NEXT: ret ptr [[RHS]]
253 %tmp = getelementptr inbounds i32, ptr %A, i64 %offset
257 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]
258 %LHS = getelementptr inbounds i64, ptr %A, i32 100
259 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1
260 %cond = icmp ult ptr %LHS, %RHS
261 br i1 %cond, label %bb2, label %bb
267 define ptr addrspace(1) @gep_of_addrspace_cast(ptr %ptr) {
268 ; CHECK-LABEL: @gep_of_addrspace_cast(
269 ; CHECK-NEXT: [[CAST1:%.*]] = addrspacecast ptr [[PTR:%.*]] to ptr addrspace(1)
270 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr addrspace(1) [[CAST1]], i64 1
271 ; CHECK-NEXT: ret ptr addrspace(1) [[GEP]]
273 %cast1 = addrspacecast ptr %ptr to ptr addrspace(1)
274 %gep = getelementptr inbounds i32, ptr addrspace(1) %cast1, i64 1
275 ret ptr addrspace(1) %gep