Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / InstSimplify / cmp-alloca-offsets.ll
blob79fd9a22ba5cc9944aeb1b530f843278c2348b9a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3 target datalayout = "p:32:32-p1:64:64"
5 ; This is a collection of tests checking whether we can prove pointers
6 ; derived from two allocas as inequal *via offset checks*.  Note that
7 ; instcombine has alternate approaches (one cmp rule, and compare
8 ; bases of common offset) that also handles these, but with different
9 ; logic.
11 ; %a follows %b, derived equal
12 define i1 @adjacent_alloca() {
13 ; CHECK-LABEL: @adjacent_alloca(
14 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, i32 4, align 1
15 ; CHECK-NEXT:    [[B:%.*]] = alloca i8, i32 4, align 1
16 ; CHECK-NEXT:    [[B_OFF:%.*]] = getelementptr i8, ptr [[B]], i64 4
17 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne ptr [[A]], [[B_OFF]]
18 ; CHECK-NEXT:    ret i1 [[RES]]
20   %a = alloca i8, i32 4
21   %b = alloca i8, i32 4
22   %b.off = getelementptr i8, ptr %b, i64 4
23   %res = icmp ne ptr %a, %b.off
24   ret i1 %res
27 ; %b follows %a, derived equal
28 define i1 @adjacent_alloca2() {
29 ; CHECK-LABEL: @adjacent_alloca2(
30 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, i32 4, align 1
31 ; CHECK-NEXT:    [[B:%.*]] = alloca i8, i32 4, align 1
32 ; CHECK-NEXT:    [[A_OFF:%.*]] = getelementptr i8, ptr [[A]], i64 4
33 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B]]
34 ; CHECK-NEXT:    ret i1 [[RES]]
36   %a = alloca i8, i32 4
37   %b = alloca i8, i32 4
38   %a.off = getelementptr i8, ptr %a, i64 4
39   %res = icmp ne ptr %a.off, %b
40   ret i1 %res
43 define i1 @positive_non_equal_end() {
44 ; CHECK-LABEL: @positive_non_equal_end(
45 ; CHECK-NEXT:    ret i1 true
47   %a = alloca i8, i32 4
48   %b = alloca i8, i32 4
49   %a.off = getelementptr i8, ptr %a, i64 4
50   %b.off = getelementptr i8, ptr %b, i64 4
51   %res = icmp ne ptr %a.off, %b.off
52   ret i1 %res
55 ; %b follows %a, derived equal
56 define i1 @positive_equal_past_end() {
57 ; CHECK-LABEL: @positive_equal_past_end(
58 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, i32 4, align 1
59 ; CHECK-NEXT:    [[B:%.*]] = alloca i8, i32 4, align 1
60 ; CHECK-NEXT:    [[A_OFF:%.*]] = getelementptr i8, ptr [[A]], i64 8
61 ; CHECK-NEXT:    [[B_OFF:%.*]] = getelementptr i8, ptr [[B]], i64 12
62 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B_OFF]]
63 ; CHECK-NEXT:    ret i1 [[RES]]
65   %a = alloca i8, i32 4
66   %b = alloca i8, i32 4
67   %a.off = getelementptr i8, ptr %a, i64 8
68   %b.off = getelementptr i8, ptr %b, i64 12
69   %res = icmp ne ptr %a.off, %b.off
70   ret i1 %res
73 define i1 @positive_non_equal() {
74 ; CHECK-LABEL: @positive_non_equal(
75 ; CHECK-NEXT:    ret i1 true
77   %a = alloca i8, i32 4
78   %b = alloca i8, i32 4
79   %a.off = getelementptr i8, ptr %a, i64 3
80   %b.off = getelementptr i8, ptr %b, i64 3
81   %res = icmp ne ptr %a.off, %b.off
82   ret i1 %res
85 ; %a follows %b, derived equal
86 define i1 @one_neg_equal1() {
87 ; CHECK-LABEL: @one_neg_equal1(
88 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, i32 4, align 1
89 ; CHECK-NEXT:    [[B:%.*]] = alloca i8, i32 4, align 1
90 ; CHECK-NEXT:    [[A_OFF:%.*]] = getelementptr i8, ptr [[A]], i64 -1
91 ; CHECK-NEXT:    [[B_OFF:%.*]] = getelementptr i8, ptr [[B]], i64 3
92 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B_OFF]]
93 ; CHECK-NEXT:    ret i1 [[RES]]
95   %a = alloca i8, i32 4
96   %b = alloca i8, i32 4
97   %a.off = getelementptr i8, ptr %a, i64 -1
98   %b.off = getelementptr i8, ptr %b, i64 3
99   %res = icmp ne ptr %a.off, %b.off
100   ret i1 %res
103 ; %b follows %a, derived equal
104 define i1 @one_neg_equal2() {
105 ; CHECK-LABEL: @one_neg_equal2(
106 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, i32 4, align 1
107 ; CHECK-NEXT:    [[B:%.*]] = alloca i8, i32 4, align 1
108 ; CHECK-NEXT:    [[A_OFF:%.*]] = getelementptr i8, ptr [[A]], i64 3
109 ; CHECK-NEXT:    [[B_OFF:%.*]] = getelementptr i8, ptr [[B]], i64 -1
110 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B_OFF]]
111 ; CHECK-NEXT:    ret i1 [[RES]]
113   %a = alloca i8, i32 4
114   %b = alloca i8, i32 4
115   %a.off = getelementptr i8, ptr %a, i64 3
116   %b.off = getelementptr i8, ptr %b, i64 -1
117   %res = icmp ne ptr %a.off, %b.off
118   ret i1 %res
121 ; %b follows %a, derived equal
122 define i1 @both_neg_equal() {
123 ; CHECK-LABEL: @both_neg_equal(
124 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, i32 4, align 1
125 ; CHECK-NEXT:    [[B:%.*]] = alloca i8, i32 4, align 1
126 ; CHECK-NEXT:    [[A_OFF:%.*]] = getelementptr i8, ptr [[A]], i64 -4
127 ; CHECK-NEXT:    [[B_OFF:%.*]] = getelementptr i8, ptr [[B]], i64 -8
128 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B_OFF]]
129 ; CHECK-NEXT:    ret i1 [[RES]]
131   %a = alloca i8, i32 4
132   %b = alloca i8, i32 4
133   %a.off = getelementptr i8, ptr %a, i64 -4
134   %b.off = getelementptr i8, ptr %b, i64 -8
135   %res = icmp ne ptr %a.off, %b.off
136   ret i1 %res
139 define i1 @mixed_offsets1() {
140 ; CHECK-LABEL: @mixed_offsets1(
141 ; CHECK-NEXT:    ret i1 true
143   %a = alloca i8, i32 4
144   %b = alloca i8, i32 4
145   %a.off = getelementptr i8, ptr %a, i64 -1
146   %b.off = getelementptr i8, ptr %b, i64 2
147   %res = icmp ne ptr %a.off, %b.off
148   ret i1 %res
151 define i1 @mixed_offsets2() {
152 ; CHECK-LABEL: @mixed_offsets2(
153 ; CHECK-NEXT:    ret i1 true
155   %a = alloca i8, i32 4
156   %b = alloca i8, i32 4
157   %a.off = getelementptr i8, ptr %a, i64 1
158   %b.off = getelementptr i8, ptr %b, i64 -2
159   %res = icmp ne ptr %a.off, %b.off
160   ret i1 %res
163 define i1 @negative_in_other() {
164 ; CHECK-LABEL: @negative_in_other(
165 ; CHECK-NEXT:    ret i1 true
167   %a = alloca i8, i32 4
168   %b = alloca i8, i32 4
169   %a.off = getelementptr i8, ptr %a, i64 -3
170   %b.off = getelementptr i8, ptr %b, i64 -2
171   %res = icmp ne ptr %a.off, %b.off
172   ret i1 %res
175 define i1 @mixed_alloca_size1() {
176 ; CHECK-LABEL: @mixed_alloca_size1(
177 ; CHECK-NEXT:    ret i1 true
179   %a = alloca i8, i32 2
180   %b = alloca i8, i32 4
181   %a.off = getelementptr i8, ptr %a, i64 1
182   %b.off = getelementptr i8, ptr %b, i64 3
183   %res = icmp ne ptr %a.off, %b.off
184   ret i1 %res
187 define i1 @mixed_alloca_size2() {
188 ; CHECK-LABEL: @mixed_alloca_size2(
189 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, i32 4, align 1
190 ; CHECK-NEXT:    [[B:%.*]] = alloca i8, i32 2, align 1
191 ; CHECK-NEXT:    [[A_OFF:%.*]] = getelementptr i8, ptr [[A]], i64 1
192 ; CHECK-NEXT:    [[B_OFF:%.*]] = getelementptr i8, ptr [[B]], i64 3
193 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B_OFF]]
194 ; CHECK-NEXT:    ret i1 [[RES]]
196   %a = alloca i8, i32 4
197   %b = alloca i8, i32 2
198   %a.off = getelementptr i8, ptr %a, i64 1
199   %b.off = getelementptr i8, ptr %b, i64 3
200   %res = icmp ne ptr %a.off, %b.off
201   ret i1 %res
204 define i1 @mixed_alloca_size3() {
205 ; CHECK-LABEL: @mixed_alloca_size3(
206 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, i32 2, align 1
207 ; CHECK-NEXT:    [[B:%.*]] = alloca i8, i32 4, align 1
208 ; CHECK-NEXT:    [[A_OFF:%.*]] = getelementptr i8, ptr [[A]], i64 -1
209 ; CHECK-NEXT:    [[B_OFF:%.*]] = getelementptr i8, ptr [[B]], i64 -3
210 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B_OFF]]
211 ; CHECK-NEXT:    ret i1 [[RES]]
213   %a = alloca i8, i32 2
214   %b = alloca i8, i32 4
215   %a.off = getelementptr i8, ptr %a, i64 -1
216   %b.off = getelementptr i8, ptr %b, i64 -3
217   %res = icmp ne ptr %a.off, %b.off
218   ret i1 %res
221 define i1 @mixed_alloca_size4() {
222 ; CHECK-LABEL: @mixed_alloca_size4(
223 ; CHECK-NEXT:    ret i1 true
225   %a = alloca i8, i32 4
226   %b = alloca i8, i32 2
227   %a.off = getelementptr i8, ptr %a, i64 -1
228   %b.off = getelementptr i8, ptr %b, i64 -3
229   %res = icmp ne ptr %a.off, %b.off
230   ret i1 %res
233 attributes #0 = { null_pointer_is_valid }