11; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2- ; RUN: opt -passes='sroa,instcombine,lower-constant-intrinsics,dce' -S < %s | FileCheck --check-prefixes CHECK,CHECK-REF %s
3- ; RUN: opt -passes=lower-constant-intrinsics,dce -S < %s | FileCheck --check-prefixes CHECK,CHECK-TST %s
2+ ; RUN: opt -passes=lower-constant-intrinsics -S < %s | FileCheck %s
43
54; Some extra tests using 16-bit pointers and 16-bit index type size. This
65; allows us to for example test what happens when the index type used in a
@@ -14,6 +13,9 @@ define i32 @possible_out_of_bounds_gep_i8(i1 %c0, i1 %c1) {
1413; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i8(
1514; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
1615; CHECK-NEXT: [[ENTRY:.*:]]
16+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
17+ ; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i8 2, i8 10
18+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i8 [[OFFSET]]
1719; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
1820; CHECK-NEXT: ret i32 [[RES]]
1921;
@@ -31,6 +33,9 @@ define i32 @possible_out_of_bounds_gep_i16(i1 %c0, i1 %c1) {
3133; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i16(
3234; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
3335; CHECK-NEXT: [[ENTRY:.*:]]
36+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
37+ ; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i16 2, i16 10
38+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i16 [[OFFSET]]
3439; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
3540; CHECK-NEXT: ret i32 [[RES]]
3641;
@@ -48,6 +53,9 @@ define i32 @possible_out_of_bounds_gep_i32(i1 %c0, i1 %c1) {
4853; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i32(
4954; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
5055; CHECK-NEXT: [[ENTRY:.*:]]
56+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
57+ ; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i32 2, i32 10
58+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 [[OFFSET]]
5159; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
5260; CHECK-NEXT: ret i32 [[RES]]
5361;
@@ -62,19 +70,17 @@ entry:
6270}
6371
6472; SROA would produce IR like this if applied to @possible_out_of_bounds_gep_i16.
65- ; FIXME: The %objsize_min result here looks wrong .
73+ ; FIXME: The %objsize_min result here is invalid .
6674define i32 @possible_out_of_bounds_gep_i16_sroa (i1 %c0 , i1 %c1 ) {
67- ; CHECK-REF-LABEL: define i32 @possible_out_of_bounds_gep_i16_sroa(
68- ; CHECK-REF-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
69- ; CHECK-REF-NEXT: [[ENTRY:.*:]]
70- ; CHECK-REF-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
71- ; CHECK-REF-NEXT: ret i32 [[RES]]
72- ;
73- ; CHECK-TST-LABEL: define i32 @possible_out_of_bounds_gep_i16_sroa(
74- ; CHECK-TST-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
75- ; CHECK-TST-NEXT: [[ENTRY:.*:]]
76- ; CHECK-TST-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 65531
77- ; CHECK-TST-NEXT: ret i32 [[RES]]
75+ ; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i16_sroa(
76+ ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
77+ ; CHECK-NEXT: [[ENTRY:.*:]]
78+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
79+ ; CHECK-NEXT: [[DOTSROA_GEP:%.*]] = getelementptr i8, ptr [[OBJ]], i16 2
80+ ; CHECK-NEXT: [[DOTSROA_GEP1:%.*]] = getelementptr i8, ptr [[OBJ]], i16 10
81+ ; CHECK-NEXT: [[OFFSET_SROA_SEL:%.*]] = select i1 [[C0]], ptr [[DOTSROA_GEP]], ptr [[DOTSROA_GEP1]]
82+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 65531
83+ ; CHECK-NEXT: ret i32 [[RES]]
7884;
7985entry:
8086 %obj = alloca [5 x i8 ], align 1
@@ -88,20 +94,18 @@ entry:
8894}
8995
9096; Indices are truncated to the pointer size in a gep. So "i32 -65526" should
91- ; be truncated to "i16 10".
92- ; FIXME: The TST result here is incorrect!
97+ ; be treated as "i16 10" and we expect same result as for
98+ ; @possible_out_of_bounds_gep_i16 above.
99+ ; FIXME: The result here is incorrect (max/min is swapped).
93100define i32 @possible_out_of_bounds_gep_i32_trunc (i1 %c0 , i1 %c1 ) {
94- ; CHECK-REF-LABEL: define i32 @possible_out_of_bounds_gep_i32_trunc(
95- ; CHECK-REF-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
96- ; CHECK-REF-NEXT: [[ENTRY:.*:]]
97- ; CHECK-REF-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
98- ; CHECK-REF-NEXT: ret i32 [[RES]]
99- ;
100- ; CHECK-TST-LABEL: define i32 @possible_out_of_bounds_gep_i32_trunc(
101- ; CHECK-TST-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
102- ; CHECK-TST-NEXT: [[ENTRY:.*:]]
103- ; CHECK-TST-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 0, i32 3
104- ; CHECK-TST-NEXT: ret i32 [[RES]]
101+ ; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i32_trunc(
102+ ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
103+ ; CHECK-NEXT: [[ENTRY:.*:]]
104+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
105+ ; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i32 2, i32 -65526
106+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 [[OFFSET]]
107+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 0, i32 3
108+ ; CHECK-NEXT: ret i32 [[RES]]
105109;
106110entry:
107111 %obj = alloca [5 x i8 ]
@@ -114,17 +118,13 @@ entry:
114118}
115119
116120define i32 @out_of_bounds_gep_i8 (i1 %c0 , i1 %c1 ) {
117- ; CHECK-REF-LABEL: define i32 @out_of_bounds_gep_i8(
118- ; CHECK-REF-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
119- ; CHECK-REF-NEXT: [[ENTRY:.*:]]
120- ; CHECK-REF-NEXT: [[RES:%.*]] = sext i1 [[C1]] to i32
121- ; CHECK-REF-NEXT: ret i32 [[RES]]
122- ;
123- ; CHECK-TST-LABEL: define i32 @out_of_bounds_gep_i8(
124- ; CHECK-TST-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
125- ; CHECK-TST-NEXT: [[ENTRY:.*:]]
126- ; CHECK-TST-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 0
127- ; CHECK-TST-NEXT: ret i32 [[RES]]
121+ ; CHECK-LABEL: define i32 @out_of_bounds_gep_i8(
122+ ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
123+ ; CHECK-NEXT: [[ENTRY:.*:]]
124+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
125+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i8 -128
126+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 0
127+ ; CHECK-NEXT: ret i32 [[RES]]
128128;
129129entry:
130130 %obj = alloca [5 x i8 ]
@@ -139,6 +139,8 @@ define i32 @out_of_bounds_gep_i32(i1 %c0, i1 %c1) {
139139; CHECK-LABEL: define i32 @out_of_bounds_gep_i32(
140140; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
141141; CHECK-NEXT: [[ENTRY:.*:]]
142+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
143+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 10
142144; CHECK-NEXT: ret i32 0
143145;
144146entry:
@@ -154,6 +156,8 @@ define i32 @out_of_bounds_gep_i32_trunc(i1 %c0, i1 %c1) {
154156; CHECK-LABEL: define i32 @out_of_bounds_gep_i32_trunc(
155157; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
156158; CHECK-NEXT: [[ENTRY:.*:]]
159+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
160+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 -65526
157161; CHECK-NEXT: ret i32 0
158162;
159163entry:
@@ -168,19 +172,18 @@ entry:
168172; In this test the index will be out-of-bounds, but the current analysis won't
169173; detect that. The analysis will find out that %offset is in the range [-2,
170174; 10] which includes valid offsets that aren't out-of-bounds. Therefore we can
171- ; expect the result -1 for %objsize_max.
175+ ; expect to get -1 for %objsize_max even if an advanced analysis should be
176+ ; able to derive that we are out-of-bounds (returning 0 also for
177+ ; %objsize_max).
172178define i32 @out_of_bounds_gep_i16_pos_neg (i1 %c0 , i1 %c1 ) {
173- ; CHECK-REF-LABEL: define i32 @out_of_bounds_gep_i16_pos_neg(
174- ; CHECK-REF-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
175- ; CHECK-REF-NEXT: [[ENTRY:.*:]]
176- ; CHECK-REF-NEXT: [[RES:%.*]] = sext i1 [[C1]] to i32
177- ; CHECK-REF-NEXT: ret i32 [[RES]]
178- ;
179- ; CHECK-TST-LABEL: define i32 @out_of_bounds_gep_i16_pos_neg(
180- ; CHECK-TST-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
181- ; CHECK-TST-NEXT: [[ENTRY:.*:]]
182- ; CHECK-TST-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 0
183- ; CHECK-TST-NEXT: ret i32 [[RES]]
179+ ; CHECK-LABEL: define i32 @out_of_bounds_gep_i16_pos_neg(
180+ ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
181+ ; CHECK-NEXT: [[ENTRY:.*:]]
182+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
183+ ; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i32 10, i32 -2
184+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 [[OFFSET]]
185+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 0
186+ ; CHECK-NEXT: ret i32 [[RES]]
184187;
185188entry:
186189 %obj = alloca [5 x i8 ]
@@ -195,19 +198,16 @@ entry:
195198; With 16-bit index size %offset is either 32767 or -32768. Thus, when
196199; aggregating the possible offsets it we know that it is in the range [-32768,
197200; 32767], which includes valid offsets that aren't out-of-bounds. This is
198- ; similar to the out_of_bounds_gep_i16_pos_neg test above, and we can expect
199- ; the result -1 for %objsize_max.
201+ ; similar to the out_of_bounds_gep_i16_pos_neg test above, and the current
202+ ; implementation is expected to derive the result -1 for %objsize_max.
200203define i32 @out_of_bounds_gep_i32_trunc_select (i1 %c0 , i1 %c1 ) {
201- ; CHECK-REF-LABEL: define i32 @out_of_bounds_gep_i32_trunc_select(
202- ; CHECK-REF-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
203- ; CHECK-REF-NEXT: [[ENTRY:.*:]]
204- ; CHECK-REF-NEXT: [[RES:%.*]] = sext i1 [[C1]] to i32
205- ; CHECK-REF-NEXT: ret i32 [[RES]]
206- ;
207- ; CHECK-TST-LABEL: define i32 @out_of_bounds_gep_i32_trunc_select(
208- ; CHECK-TST-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
209- ; CHECK-TST-NEXT: [[ENTRY:.*:]]
210- ; CHECK-TST-NEXT: ret i32 0
204+ ; CHECK-LABEL: define i32 @out_of_bounds_gep_i32_trunc_select(
205+ ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
206+ ; CHECK-NEXT: [[ENTRY:.*:]]
207+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
208+ ; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i32 32767, i32 32768
209+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 [[OFFSET]]
210+ ; CHECK-NEXT: ret i32 0
211211;
212212entry:
213213 %obj = alloca [5 x i8 ]
@@ -224,6 +224,9 @@ define i32 @possible_out_of_bounds_gep_i8_neg(i1 %c0, i1 %c1) {
224224; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i8_neg(
225225; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
226226; CHECK-NEXT: [[ENTRY:.*:]]
227+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
228+ ; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i8 2, i8 -10
229+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i8 [[OFFSET]]
227230; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 3
228231; CHECK-NEXT: ret i32 [[RES]]
229232;
@@ -242,6 +245,9 @@ define i32 @possible_out_of_bounds_gep_i16_neg(i1 %c0, i1 %c1) {
242245; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i16_neg(
243246; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
244247; CHECK-NEXT: [[ENTRY:.*:]]
248+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
249+ ; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i16 2, i16 -10
250+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i16 [[OFFSET]]
245251; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 3
246252; CHECK-NEXT: ret i32 [[RES]]
247253;
0 commit comments