[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / InstCombine / gep-inbounds-null.ll
blobcd7eac6bcba28beb98cd7f724bd1d5f0e15a4be2
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S < %s -passes=instcombine | FileCheck %s
4 ;; Start by showing the results of constant folding (which doesn't use
5 ;; the poison implied by gep for the nonnull cases).
7 define i1 @test_ne_constants_null() {
8 ; CHECK-LABEL: @test_ne_constants_null(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    ret i1 false
12 entry:
13   %cnd = icmp ne ptr null, null
14   ret i1 %cnd
17 define i1 @test_ne_constants_nonnull() {
18 ; CHECK-LABEL: @test_ne_constants_nonnull(
19 ; CHECK-NEXT:  entry:
20 ; CHECK-NEXT:    ret i1 true
22 entry:
23   %gep = getelementptr inbounds i8, ptr null, i64 1
24   %cnd = icmp ne ptr %gep, null
25   ret i1 %cnd
28 define i1 @test_eq_constants_null() {
29 ; CHECK-LABEL: @test_eq_constants_null(
30 ; CHECK-NEXT:  entry:
31 ; CHECK-NEXT:    ret i1 true
33 entry:
34   %cnd = icmp eq ptr null, null
35   ret i1 %cnd
38 define i1 @test_eq_constants_nonnull() {
39 ; CHECK-LABEL: @test_eq_constants_nonnull(
40 ; CHECK-NEXT:  entry:
41 ; CHECK-NEXT:    ret i1 false
43 entry:
44   %gep = getelementptr inbounds i8, ptr null, i64 1
45   %cnd = icmp eq ptr %gep, null
46   ret i1 %cnd
49 ;; Then show the results for non-constants.  These use the inbounds provided
50 ;; UB fact to ignore the possible overflow cases.
52 define i1 @test_ne(ptr %base, i64 %idx) {
53 ; CHECK-LABEL: @test_ne(
54 ; CHECK-NEXT:  entry:
55 ; CHECK-NEXT:    [[CND:%.*]] = icmp ne ptr [[BASE:%.*]], null
56 ; CHECK-NEXT:    ret i1 [[CND]]
58 entry:
59   %gep = getelementptr inbounds i8, ptr %base, i64 %idx
60   %cnd = icmp ne ptr %gep, null
61   ret i1 %cnd
64 define i1 @test_eq(ptr %base, i64 %idx) {
65 ; CHECK-LABEL: @test_eq(
66 ; CHECK-NEXT:  entry:
67 ; CHECK-NEXT:    [[CND:%.*]] = icmp eq ptr [[BASE:%.*]], null
68 ; CHECK-NEXT:    ret i1 [[CND]]
70 entry:
71   %gep = getelementptr inbounds i8, ptr %base, i64 %idx
72   %cnd = icmp eq ptr %gep, null
73   ret i1 %cnd
76 define <2 x i1> @test_vector_base(<2 x ptr> %base, i64 %idx) {
77 ; CHECK-LABEL: @test_vector_base(
78 ; CHECK-NEXT:  entry:
79 ; CHECK-NEXT:    [[CND:%.*]] = icmp eq <2 x ptr> [[BASE:%.*]], zeroinitializer
80 ; CHECK-NEXT:    ret <2 x i1> [[CND]]
82 entry:
83   %gep = getelementptr inbounds i8, <2 x ptr> %base, i64 %idx
84   %cnd = icmp eq <2 x ptr> %gep, zeroinitializer
85   ret <2 x i1> %cnd
88 define <2 x i1> @test_vector_index(ptr %base, <2 x i64> %idx) {
89 ; CHECK-LABEL: @test_vector_index(
90 ; CHECK-NEXT:  entry:
91 ; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x ptr> poison, ptr [[BASE:%.*]], i64 0
92 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq <2 x ptr> [[DOTSPLATINSERT]], zeroinitializer
93 ; CHECK-NEXT:    [[CND:%.*]] = shufflevector <2 x i1> [[TMP0]], <2 x i1> poison, <2 x i32> zeroinitializer
94 ; CHECK-NEXT:    ret <2 x i1> [[CND]]
96 entry:
97   %gep = getelementptr inbounds i8, ptr %base, <2 x i64> %idx
98   %cnd = icmp eq <2 x ptr> %gep, zeroinitializer
99   ret <2 x i1> %cnd
102 define <2 x i1> @test_vector_both(<2 x ptr> %base, <2 x i64> %idx) {
103 ; CHECK-LABEL: @test_vector_both(
104 ; CHECK-NEXT:  entry:
105 ; CHECK-NEXT:    [[CND:%.*]] = icmp eq <2 x ptr> [[BASE:%.*]], zeroinitializer
106 ; CHECK-NEXT:    ret <2 x i1> [[CND]]
108 entry:
109   %gep = getelementptr inbounds i8, <2 x ptr> %base, <2 x i64> %idx
110   %cnd = icmp eq <2 x ptr> %gep, zeroinitializer
111   ret <2 x i1> %cnd
114 ;; These two show instsimplify's reasoning getting to the non-zero offsets
115 ;; before instcombine does.
117 define i1 @test_eq_pos_idx(ptr %base) {
118 ; CHECK-LABEL: @test_eq_pos_idx(
119 ; CHECK-NEXT:  entry:
120 ; CHECK-NEXT:    ret i1 false
122 entry:
123   %gep = getelementptr inbounds i8, ptr %base, i64 1
124   %cnd = icmp eq ptr %gep, null
125   ret i1 %cnd
128 define i1 @test_eq_neg_idx(ptr %base) {
129 ; CHECK-LABEL: @test_eq_neg_idx(
130 ; CHECK-NEXT:  entry:
131 ; CHECK-NEXT:    ret i1 false
133 entry:
134   %gep = getelementptr inbounds i8, ptr %base, i64 -1
135   %cnd = icmp eq ptr %gep, null
136   ret i1 %cnd
139 ;; Show an example with a zero sized type since that's
140 ;; a cornercase which keeps getting mentioned.  The GEP
141 ;; produces %base regardless of the value of the index
142 ;; expression.
143 define i1 @test_size0(ptr %base, i64 %idx) {
144 ; CHECK-LABEL: @test_size0(
145 ; CHECK-NEXT:  entry:
146 ; CHECK-NEXT:    [[CND:%.*]] = icmp ne ptr [[BASE:%.*]], null
147 ; CHECK-NEXT:    ret i1 [[CND]]
149 entry:
150   %gep = getelementptr inbounds {}, ptr %base, i64 %idx
151   %cnd = icmp ne ptr %gep, null
152   ret i1 %cnd
154 define i1 @test_size0_nonzero_offset(ptr %base) {
155 ; CHECK-LABEL: @test_size0_nonzero_offset(
156 ; CHECK-NEXT:  entry:
157 ; CHECK-NEXT:    [[CND:%.*]] = icmp ne ptr [[BASE:%.*]], null
158 ; CHECK-NEXT:    ret i1 [[CND]]
160 entry:
161   %gep = getelementptr inbounds {}, ptr %base, i64 15
162   %cnd = icmp ne ptr %gep, null
163   ret i1 %cnd
167 define i1 @test_index_type(ptr %base, i64 %idx) {
168 ; CHECK-LABEL: @test_index_type(
169 ; CHECK-NEXT:  entry:
170 ; CHECK-NEXT:    [[CND:%.*]] = icmp eq ptr [[BASE:%.*]], null
171 ; CHECK-NEXT:    ret i1 [[CND]]
173 entry:
174   %gep = getelementptr inbounds [10 x i8], ptr %base, i64 %idx, i64 %idx
175   %cnd = icmp eq ptr %gep, null
176   ret i1 %cnd
180 ;; Finally, some negative tests for basic correctness checking.
182 define i1 @neq_noinbounds(ptr %base, i64 %idx) {
183 ; CHECK-LABEL: @neq_noinbounds(
184 ; CHECK-NEXT:  entry:
185 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
186 ; CHECK-NEXT:    [[CND:%.*]] = icmp ne ptr [[GEP]], null
187 ; CHECK-NEXT:    ret i1 [[CND]]
189 entry:
190   %gep = getelementptr i8, ptr %base, i64 %idx
191   %cnd = icmp ne ptr %gep, null
192   ret i1 %cnd
195 define i1 @neg_objectatnull(ptr addrspace(2) %base, i64 %idx) {
196 ; CHECK-LABEL: @neg_objectatnull(
197 ; CHECK-NEXT:  entry:
198 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(2) [[BASE:%.*]], i64 [[IDX:%.*]]
199 ; CHECK-NEXT:    [[CND:%.*]] = icmp eq ptr addrspace(2) [[GEP]], null
200 ; CHECK-NEXT:    ret i1 [[CND]]
202 entry:
203   %gep = getelementptr inbounds i8, ptr addrspace(2) %base, i64 %idx
204   %cnd = icmp eq ptr addrspace(2) %gep, null
205   ret i1 %cnd
208 ; Test for an assert from trying to create an invalid constantexpr
209 ; bitcast between different address spaces. The addrspacecast is
210 ; stripped off and the addrspace(0) null can be treated as invalid.
211 ; FIXME: This should be able to fold to ret i1 false
212 define i1 @invalid_bitcast_icmp_addrspacecast_as0_null(ptr addrspace(5) %ptr) {
213 ; CHECK-LABEL: @invalid_bitcast_icmp_addrspacecast_as0_null(
214 ; CHECK-NEXT:  bb:
215 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr addrspace(5) [[PTR:%.*]], addrspacecast (ptr null to ptr addrspace(5))
216 ; CHECK-NEXT:    ret i1 [[TMP2]]
219   %tmp1 = getelementptr inbounds i32, ptr addrspace(5) %ptr, i32 1
220   %tmp2 = icmp eq ptr addrspace(5) %tmp1, addrspacecast (ptr null to ptr addrspace(5))
221   ret i1 %tmp2
224 define i1 @invalid_bitcast_icmp_addrspacecast_as0_null_var(ptr addrspace(5) %ptr, i32 %idx) {
225 ; CHECK-LABEL: @invalid_bitcast_icmp_addrspacecast_as0_null_var(
226 ; CHECK-NEXT:  bb:
227 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr addrspace(5) [[PTR:%.*]], addrspacecast (ptr null to ptr addrspace(5))
228 ; CHECK-NEXT:    ret i1 [[TMP2]]
231   %tmp1 = getelementptr inbounds i32, ptr addrspace(5) %ptr, i32 %idx
232   %tmp2 = icmp eq ptr addrspace(5) %tmp1, addrspacecast (ptr null to ptr addrspace(5))
233   ret i1 %tmp2