1
+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1
2
; RUN: opt -S -guard-widening < %s | FileCheck %s
2
3
3
4
declare void @llvm.experimental.guard (i1 ,...)
4
5
5
6
define void @f_0 (i32 %x , i32* %length_buf ) {
6
7
; CHECK-LABEL: @f_0(
7
- ; CHECK-NOT: @llvm.experimental.guard
8
- ; CHECK: %wide.chk2 = and i1 %chk3, %chk0
9
- ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk2) [ "deopt"() ]
10
- ; CHECK: ret void
8
+ ; CHECK-NEXT: entry:
9
+ ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0:![0-9]+]]
10
+ ; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
11
+ ; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], 1
12
+ ; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]
13
+ ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
14
+ ; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X]], 2
15
+ ; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]
16
+ ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK0]]
17
+ ; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X]], 3
18
+ ; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]
19
+ ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK0]]
20
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
21
+ ; CHECK-NEXT: ret void
22
+ ;
11
23
entry:
12
24
%length = load i32 , i32* %length_buf , !range !0
13
25
%chk0 = icmp ult i32 %x , %length
@@ -29,10 +41,21 @@ entry:
29
41
30
42
define void @f_1 (i32 %x , i32* %length_buf ) {
31
43
; CHECK-LABEL: @f_1(
32
- ; CHECK-NOT: llvm.experimental.guard
33
- ; CHECK: %wide.chk2 = and i1 %chk3, %chk0
34
- ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk2) [ "deopt"() ]
35
- ; CHECK: ret void
44
+ ; CHECK-NEXT: entry:
45
+ ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]
46
+ ; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
47
+ ; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], 1
48
+ ; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]
49
+ ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
50
+ ; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_INC1]], 2
51
+ ; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]
52
+ ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK0]]
53
+ ; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_INC2]], 3
54
+ ; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]
55
+ ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK0]]
56
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
57
+ ; CHECK-NEXT: ret void
58
+ ;
36
59
entry:
37
60
%length = load i32 , i32* %length_buf , !range !0
38
61
%chk0 = icmp ult i32 %x , %length
@@ -54,10 +77,22 @@ entry:
54
77
55
78
define void @f_2 (i32 %a , i32* %length_buf ) {
56
79
; CHECK-LABEL: @f_2(
57
- ; CHECK-NOT: llvm.experimental.guard
58
- ; CHECK: %wide.chk2 = and i1 %chk3, %chk0
59
- ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk2) [ "deopt"() ]
60
- ; CHECK: ret void
80
+ ; CHECK-NEXT: entry:
81
+ ; CHECK-NEXT: [[X:%.*]] = and i32 [[A:%.*]], -256
82
+ ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]
83
+ ; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X]], [[LENGTH]]
84
+ ; CHECK-NEXT: [[X_INC1:%.*]] = or i32 [[X]], 1
85
+ ; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]
86
+ ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
87
+ ; CHECK-NEXT: [[X_INC2:%.*]] = or i32 [[X]], 2
88
+ ; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]
89
+ ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK0]]
90
+ ; CHECK-NEXT: [[X_INC3:%.*]] = or i32 [[X]], 3
91
+ ; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]
92
+ ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK0]]
93
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
94
+ ; CHECK-NEXT: ret void
95
+ ;
61
96
entry:
62
97
%x = and i32 %a , 4294967040 ;; 4294967040 == 0xffffff00
63
98
%length = load i32 , i32* %length_buf , !range !0
@@ -80,10 +115,22 @@ entry:
80
115
81
116
define void @f_3 (i32 %a , i32* %length_buf ) {
82
117
; CHECK-LABEL: @f_3(
83
- ; CHECK-NOT: llvm.experimental.guard
84
- ; CHECK: %wide.chk2 = and i1 %chk3, %chk0
85
- ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk2) [ "deopt"() ]
86
- ; CHECK: ret void
118
+ ; CHECK-NEXT: entry:
119
+ ; CHECK-NEXT: [[X:%.*]] = and i32 [[A:%.*]], -256
120
+ ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]
121
+ ; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X]], [[LENGTH]]
122
+ ; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], 1
123
+ ; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]
124
+ ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
125
+ ; CHECK-NEXT: [[X_INC2:%.*]] = or i32 [[X_INC1]], 2
126
+ ; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]
127
+ ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK0]]
128
+ ; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_INC2]], 3
129
+ ; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]
130
+ ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK0]]
131
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
132
+ ; CHECK-NEXT: ret void
133
+ ;
87
134
entry:
88
135
%x = and i32 %a , 4294967040 ;; 4294967040 == 0xffffff00
89
136
%length = load i32 , i32* %length_buf , !range !0
@@ -106,12 +153,23 @@ entry:
106
153
107
154
define void @f_4 (i32 %x , i32* %length_buf ) {
108
155
; CHECK-LABEL: @f_4(
109
- ; CHECK-NOT: llvm.experimental.guard
156
+ ; CHECK-NEXT: entry:
157
+ ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]
158
+ ; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
159
+ ; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], -1024
160
+ ; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]
161
+ ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
162
+ ; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X]], 2
163
+ ; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]
164
+ ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK1]]
165
+ ; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X]], 3
166
+ ; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]
167
+ ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK1]]
168
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
169
+ ; CHECK-NEXT: ret void
170
+ ;
110
171
111
172
; Note: we NOT guarding on "and i1 %chk3, %chk0", that would be incorrect.
112
- ; CHECK: %wide.chk2 = and i1 %chk3, %chk1
113
- ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk2) [ "deopt"() ]
114
- ; CHECK: ret void
115
173
entry:
116
174
%length = load i32 , i32* %length_buf , !range !0
117
175
%chk0 = icmp ult i32 %x , %length
@@ -133,10 +191,21 @@ entry:
133
191
134
192
define void @f_5 (i32 %x , i32* %length_buf ) {
135
193
; CHECK-LABEL: @f_5(
136
- ; CHECK-NOT: llvm.experimental.guard
137
- ; CHECK: %wide.chk2 = and i1 %chk1, %chk2
138
- ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk2) [ "deopt"() ]
139
- ; CHECK: ret void
194
+ ; CHECK-NEXT: entry:
195
+ ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]
196
+ ; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
197
+ ; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], 1
198
+ ; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]
199
+ ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
200
+ ; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_INC1]], -200
201
+ ; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]
202
+ ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK1]], [[CHK2]]
203
+ ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK1]], [[CHK2]]
204
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
205
+ ; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_INC2]], 3
206
+ ; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]
207
+ ; CHECK-NEXT: ret void
208
+ ;
140
209
entry:
141
210
%length = load i32 , i32* %length_buf , !range !0
142
211
%chk0 = icmp ult i32 %x , %length
@@ -170,11 +239,21 @@ entry:
170
239
;
171
240
define void @f_6 (i32 %x , i32* %length_buf ) {
172
241
; CHECK-LABEL: @f_6(
173
- ; CHECK-NOT: llvm.experimental.guard
174
- ; CHECK: %wide.chk = and i1 %chk0, %chk1
175
- ; CHECK: %wide.chk1 = and i1 %wide.chk, %chk2
176
- ; CHECK: %wide.chk2 = and i1 %wide.chk1, %chk3
177
- ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk2) [ "deopt"() ]
242
+ ; CHECK-NEXT: entry:
243
+ ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]
244
+ ; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
245
+ ; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], -2147483647
246
+ ; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]
247
+ ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
248
+ ; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X]], 2
249
+ ; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]
250
+ ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[CHK2]]
251
+ ; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X]], 3
252
+ ; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]
253
+ ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK1]], [[CHK3]]
254
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
255
+ ; CHECK-NEXT: ret void
256
+ ;
178
257
entry:
179
258
%length = load i32 , i32* %length_buf , !range !0
180
259
%chk0 = icmp ult i32 %x , %length
@@ -197,11 +276,35 @@ entry:
197
276
198
277
define void @f_7 (i32 %x , i32* %length_buf ) {
199
278
; CHECK-LABEL: @f_7(
279
+ ; CHECK-NEXT: entry:
280
+ ; CHECK-NEXT: [[LENGTH_A:%.*]] = load volatile i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]
281
+ ; CHECK-NEXT: [[LENGTH_B:%.*]] = load volatile i32, i32* [[LENGTH_BUF]], align 4, !range [[RNG0]]
282
+ ; CHECK-NEXT: [[CHK0_A:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH_A]]
283
+ ; CHECK-NEXT: [[CHK0_B:%.*]] = icmp ult i32 [[X]], [[LENGTH_B]]
284
+ ; CHECK-NEXT: [[CHK0:%.*]] = and i1 [[CHK0_A]], [[CHK0_B]]
285
+ ; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], 1
286
+ ; CHECK-NEXT: [[CHK1_A:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH_A]]
287
+ ; CHECK-NEXT: [[CHK1_B:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH_B]]
288
+ ; CHECK-NEXT: [[CHK1:%.*]] = and i1 [[CHK1_A]], [[CHK1_B]]
289
+ ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
290
+ ; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X]], 2
291
+ ; CHECK-NEXT: [[CHK2_A:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH_A]]
292
+ ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[CHK2_A]], [[CHK0_A]]
293
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[CHK0_B]], [[TMP0]]
294
+ ; CHECK-NEXT: [[CHK2_B:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH_B]]
295
+ ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2_B]], [[TMP1]]
296
+ ; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X]], 3
297
+ ; CHECK-NEXT: [[CHK3_B:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH_B]]
298
+ ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[CHK3_B]], [[CHK0_B]]
299
+ ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[CHK0_A]], [[TMP2]]
300
+ ; CHECK-NEXT: [[CHK3_A:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH_A]]
301
+ ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3_A]], [[TMP3]]
302
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
303
+ ; CHECK-NEXT: [[CHK2:%.*]] = and i1 [[CHK2_A]], [[CHK2_B]]
304
+ ; CHECK-NEXT: [[CHK3:%.*]] = and i1 [[CHK3_A]], [[CHK3_B]]
305
+ ; CHECK-NEXT: ret void
306
+ ;
200
307
201
- ; CHECK: [[COND_0:%[^ ]+]] = and i1 %chk3.b, %chk0.b
202
- ; CHECK: [[COND_1:%[^ ]+]] = and i1 %chk0.a, [[COND_0]]
203
- ; CHECK: [[COND_2:%[^ ]+]] = and i1 %chk3.a, [[COND_1]]
204
- ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_2]]) [ "deopt"() ]
205
308
206
309
entry:
207
310
%length_a = load volatile i32 , i32* %length_buf , !range !0
0 commit comments