1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify,verify -S | FileCheck %s
4 define i1 @ule_null_constexpr(ptr %x) {
5 ; CHECK-LABEL: @ule_null_constexpr(
6 ; CHECK-NEXT: ret i1 true
8 %cmp = icmp ule ptr null, @ule_null_constexpr
12 define i1 @ugt_null_constexpr(ptr %x) {
13 ; CHECK-LABEL: @ugt_null_constexpr(
14 ; CHECK-NEXT: ret i1 false
16 %cmp = icmp ugt ptr null, @ugt_null_constexpr
20 define i1 @uge_constexpr_null(ptr %x) {
21 ; CHECK-LABEL: @uge_constexpr_null(
22 ; CHECK-NEXT: ret i1 true
24 %cmp = icmp uge ptr @ugt_null_constexpr, null
28 define i1 @ult_constexpr_null(ptr %x) {
29 ; CHECK-LABEL: @ult_constexpr_null(
30 ; CHECK-NEXT: ret i1 false
32 %cmp = icmp ult ptr @ugt_null_constexpr, null
36 ; Negative test - we don't know if the constexpr is null.
38 define i1 @ule_constexpr_null(ptr %x) {
39 ; CHECK-LABEL: @ule_constexpr_null(
40 ; CHECK-NEXT: ret i1 false
42 %cmp = icmp ule ptr @ugt_null_constexpr, null
46 ; Negative test - we don't know if the constexpr is *signed* less-than null.
48 define i1 @slt_constexpr_null(ptr %x) {
49 ; CHECK-LABEL: @slt_constexpr_null(
50 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr @ugt_null_constexpr, null
51 ; CHECK-NEXT: ret i1 [[CMP]]
53 %cmp = icmp slt ptr @ugt_null_constexpr, null
57 ; Negative test - we don't try to evaluate this comparison of constant expressions.
59 define i1 @ult_constexpr_constexpr_one(ptr %x) {
60 ; CHECK-LABEL: @ult_constexpr_constexpr_one(
61 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr @ugt_null_constexpr, inttoptr (i32 1 to ptr)
62 ; CHECK-NEXT: ret i1 [[CMP]]
64 %cmp = icmp ult ptr @ugt_null_constexpr, inttoptr (i32 1 to ptr)
68 @g = global [2 x i32] [i32 1, i32 2]
70 @g2_weak = extern_weak global i32
73 define i1 @global_ne_null() {
74 ; CHECK-LABEL: @global_ne_null(
75 ; CHECK-NEXT: ret i1 true
77 %cmp = icmp ne ptr @g, null
81 define i1 @global_ugt_null() {
82 ; CHECK-LABEL: @global_ugt_null(
83 ; CHECK-NEXT: ret i1 true
85 %cmp = icmp ugt ptr @g, null
89 define i1 @global_sgt_null() {
90 ; CHECK-LABEL: @global_sgt_null(
91 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr @g, null
92 ; CHECK-NEXT: ret i1 [[CMP]]
94 %cmp = icmp sgt ptr @g, null
98 ; Should not fold to true, as the gep computes a null value.
99 define i1 @global_out_of_bounds_gep_ne_null() {
100 ; CHECK-LABEL: @global_out_of_bounds_gep_ne_null(
101 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr @g3, i64 sub (i64 0, i64 ptrtoint (ptr @g3 to i64))), null
102 ; CHECK-NEXT: ret i1 [[CMP]]
104 %cmp = icmp ne ptr getelementptr (i8, ptr @g3, i64 sub (i64 0, i64 ptrtoint (ptr @g3 to i64))), null
108 define i1 @global_inbounds_gep_ne_null() {
109 ; CHECK-LABEL: @global_inbounds_gep_ne_null(
110 ; CHECK-NEXT: ret i1 true
112 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
113 %cmp = icmp ne ptr %gep, null
117 define i1 @global_gep_ugt_null() {
118 ; CHECK-LABEL: @global_gep_ugt_null(
119 ; CHECK-NEXT: ret i1 true
121 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
122 %cmp = icmp ugt ptr %gep, null
126 define i1 @global_gep_sgt_null() {
127 ; CHECK-LABEL: @global_gep_sgt_null(
128 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds (i8, ptr @g, i64 8), null
129 ; CHECK-NEXT: ret i1 [[CMP]]
131 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
132 %cmp = icmp sgt ptr %gep, null
136 ; @g2_weak may be null, in which case this is a zero-index GEP and the pointers
138 define i1 @null_gep_ne_null() {
139 ; CHECK-LABEL: @null_gep_ne_null(
140 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null
141 ; CHECK-NEXT: ret i1 [[CMP]]
143 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
144 %cmp = icmp ne ptr %gep, null
148 define i1 @null_gep_ugt_null() {
149 ; CHECK-LABEL: @null_gep_ugt_null(
150 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null
151 ; CHECK-NEXT: ret i1 [[CMP]]
153 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
154 %cmp = icmp ugt ptr %gep, null
158 define i1 @null_gep_sgt_null() {
159 ; CHECK-LABEL: @null_gep_sgt_null(
160 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null
161 ; CHECK-NEXT: ret i1 [[CMP]]
163 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
164 %cmp = icmp sgt ptr %gep, null
168 define i1 @null_gep_ne_null_constant_int() {
169 ; CHECK-LABEL: @null_gep_ne_null_constant_int(
170 ; CHECK-NEXT: ret i1 true
172 %gep = getelementptr i8, ptr null, i64 1
173 %cmp = icmp ne ptr %gep, null
177 define i1 @null_gep_ugt_null_constant_int() {
178 ; CHECK-LABEL: @null_gep_ugt_null_constant_int(
179 ; CHECK-NEXT: ret i1 true
181 %gep = getelementptr i8, ptr null, i64 1
182 %cmp = icmp ugt ptr %gep, null
186 define i1 @null_gep_ne_global() {
187 ; CHECK-LABEL: @null_gep_ne_global(
188 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g3 to i64)), @g3
189 ; CHECK-NEXT: ret i1 [[CMP]]
191 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g3 to i64)
192 %cmp = icmp ne ptr %gep, @g3
196 define i1 @null_gep_ult_global() {
197 ; CHECK-LABEL: @null_gep_ult_global(
198 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g3 to i64)), @g3
199 ; CHECK-NEXT: ret i1 [[CMP]]
201 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g3 to i64)
202 %cmp = icmp ult ptr %gep, @g3
206 define i1 @null_gep_slt_global() {
207 ; CHECK-LABEL: @null_gep_slt_global(
208 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr getelementptr ([2 x i32], ptr null, i64 ptrtoint (ptr @g2 to i64)), @g
209 ; CHECK-NEXT: ret i1 [[CMP]]
211 %gep = getelementptr [2 x i32], ptr null, i64 ptrtoint (ptr @g2 to i64)
212 %cmp = icmp slt ptr %gep, @g
216 define i1 @global_gep_ne_global() {
217 ; CHECK-LABEL: @global_gep_ne_global(
218 ; CHECK-NEXT: ret i1 true
220 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
221 %cmp = icmp ne ptr %gep, @g
225 define i1 @global_gep_ugt_global() {
226 ; CHECK-LABEL: @global_gep_ugt_global(
227 ; CHECK-NEXT: ret i1 true
229 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
230 %cmp = icmp ugt ptr %gep, @g
234 define i1 @global_gep_sgt_global() {
235 ; CHECK-LABEL: @global_gep_sgt_global(
236 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds (i8, ptr @g, i64 8), @g
237 ; CHECK-NEXT: ret i1 [[CMP]]
239 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
240 %cmp = icmp sgt ptr %gep, @g
244 ; This should not fold to true, as the offset is negative.
245 define i1 @global_gep_ugt_global_neg_offset() {
246 ; CHECK-LABEL: @global_gep_ugt_global_neg_offset(
247 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr getelementptr (i8, ptr @g, i64 -8), @g
248 ; CHECK-NEXT: ret i1 [[CMP]]
250 %gep = getelementptr [2 x i32], ptr @g, i64 -1
251 %cmp = icmp ugt ptr %gep, @g
255 define i1 @global_gep_sgt_global_neg_offset() {
256 ; CHECK-LABEL: @global_gep_sgt_global_neg_offset(
257 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr (i8, ptr @g, i64 -8), @g
258 ; CHECK-NEXT: ret i1 [[CMP]]
260 %gep = getelementptr [2 x i32], ptr @g, i64 -1
261 %cmp = icmp sgt ptr %gep, @g
265 define i1 @global_gep_ugt_global_gep() {
266 ; CHECK-LABEL: @global_gep_ugt_global_gep(
267 ; CHECK-NEXT: ret i1 true
269 %gep2 = getelementptr inbounds [2 x i32], ptr @g, i64 0, i64 1
270 %cmp = icmp ugt ptr %gep2, @g
274 ; Should not fold due to signed comparison.
275 define i1 @global_gep_sgt_global_gep() {
276 ; CHECK-LABEL: @global_gep_sgt_global_gep(
277 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds (i8, ptr @g, i64 4), @g
278 ; CHECK-NEXT: ret i1 [[CMP]]
280 %gep2 = getelementptr inbounds [2 x i32], ptr @g, i64 0, i64 1
281 %cmp = icmp sgt ptr %gep2, @g
285 define i1 @global_gep_ugt_global_gep_complex() {
286 ; CHECK-LABEL: @global_gep_ugt_global_gep_complex(
287 ; CHECK-NEXT: ret i1 true
289 %gep3 = getelementptr inbounds i8, ptr @g, i64 2
290 %cmp = icmp ugt ptr %gep3, @g
296 define i1 @global_no_cfi() {
297 ; CHECK-LABEL: @global_no_cfi(
298 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr @func, no_cfi @func
299 ; CHECK-NEXT: ret i1 [[CMP]]
301 %cmp = icmp eq ptr @func, no_cfi @func
305 define i1 @blockaddr_no_cfi() {
306 ; CHECK-LABEL: @blockaddr_no_cfi(
307 ; CHECK-NEXT: br label [[BB:%.*]]
309 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr blockaddress(@blockaddr_no_cfi, [[BB]]), no_cfi @func
310 ; CHECK-NEXT: ret i1 [[CMP]]
315 %cmp = icmp eq ptr blockaddress(@blockaddr_no_cfi, %bb), no_cfi @func
319 define i1 @global_no_cfi_dso_local_equivalent() {
320 ; CHECK-LABEL: @global_no_cfi_dso_local_equivalent(
321 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr dso_local_equivalent @func, no_cfi @func
322 ; CHECK-NEXT: ret i1 [[CMP]]
324 %cmp = icmp eq ptr dso_local_equivalent @func, no_cfi @func