1
1
; 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
4
3
5
4
; Some extra tests using 16-bit pointers and 16-bit index type size. This
6
5
; 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) {
14
13
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i8(
15
14
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
16
15
; 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]]
17
19
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
18
20
; CHECK-NEXT: ret i32 [[RES]]
19
21
;
@@ -31,6 +33,9 @@ define i32 @possible_out_of_bounds_gep_i16(i1 %c0, i1 %c1) {
31
33
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i16(
32
34
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
33
35
; 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]]
34
39
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
35
40
; CHECK-NEXT: ret i32 [[RES]]
36
41
;
@@ -48,6 +53,9 @@ define i32 @possible_out_of_bounds_gep_i32(i1 %c0, i1 %c1) {
48
53
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i32(
49
54
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
50
55
; 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]]
51
59
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
52
60
; CHECK-NEXT: ret i32 [[RES]]
53
61
;
@@ -62,19 +70,17 @@ entry:
62
70
}
63
71
64
72
; 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 .
66
74
define 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]]
78
84
;
79
85
entry:
80
86
%obj = alloca [5 x i8 ], align 1
@@ -88,20 +94,18 @@ entry:
88
94
}
89
95
90
96
; 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).
93
100
define 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]]
105
109
;
106
110
entry:
107
111
%obj = alloca [5 x i8 ]
@@ -114,17 +118,13 @@ entry:
114
118
}
115
119
116
120
define 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]]
128
128
;
129
129
entry:
130
130
%obj = alloca [5 x i8 ]
@@ -139,6 +139,8 @@ define i32 @out_of_bounds_gep_i32(i1 %c0, i1 %c1) {
139
139
; CHECK-LABEL: define i32 @out_of_bounds_gep_i32(
140
140
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
141
141
; CHECK-NEXT: [[ENTRY:.*:]]
142
+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
143
+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 10
142
144
; CHECK-NEXT: ret i32 0
143
145
;
144
146
entry:
@@ -154,6 +156,8 @@ define i32 @out_of_bounds_gep_i32_trunc(i1 %c0, i1 %c1) {
154
156
; CHECK-LABEL: define i32 @out_of_bounds_gep_i32_trunc(
155
157
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
156
158
; CHECK-NEXT: [[ENTRY:.*:]]
159
+ ; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
160
+ ; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 -65526
157
161
; CHECK-NEXT: ret i32 0
158
162
;
159
163
entry:
@@ -168,19 +172,18 @@ entry:
168
172
; In this test the index will be out-of-bounds, but the current analysis won't
169
173
; detect that. The analysis will find out that %offset is in the range [-2,
170
174
; 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).
172
178
define 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]]
184
187
;
185
188
entry:
186
189
%obj = alloca [5 x i8 ]
@@ -195,19 +198,16 @@ entry:
195
198
; With 16-bit index size %offset is either 32767 or -32768. Thus, when
196
199
; aggregating the possible offsets it we know that it is in the range [-32768,
197
200
; 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.
200
203
define 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
211
211
;
212
212
entry:
213
213
%obj = alloca [5 x i8 ]
@@ -224,6 +224,9 @@ define i32 @possible_out_of_bounds_gep_i8_neg(i1 %c0, i1 %c1) {
224
224
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i8_neg(
225
225
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
226
226
; 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]]
227
230
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 3
228
231
; CHECK-NEXT: ret i32 [[RES]]
229
232
;
@@ -242,6 +245,9 @@ define i32 @possible_out_of_bounds_gep_i16_neg(i1 %c0, i1 %c1) {
242
245
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i16_neg(
243
246
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
244
247
; 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]]
245
251
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 3
246
252
; CHECK-NEXT: ret i32 [[RES]]
247
253
;
0 commit comments