1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=poison-checking -S -poison-checking-function-local < %s | FileCheck %s
4 ; This file contains tests to exercise the custom flag validation rules
6 define i32 @add_noflags(i32 %a, i32 %b) {
7 ; CHECK-LABEL: @add_noflags(
8 ; CHECK-NEXT: [[RES:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
9 ; CHECK-NEXT: ret i32 [[RES]]
15 define i32 @add_nsw(i32 %a, i32 %b) {
16 ; CHECK-LABEL: @add_nsw(
17 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
18 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
19 ; CHECK-NEXT: [[RES:%.*]] = add nsw i32 [[A]], [[B]]
20 ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
21 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
22 ; CHECK-NEXT: ret i32 [[RES]]
24 %res = add nsw i32 %a, %b
28 define i32 @add_nuw(i32 %a, i32 %b) {
29 ; CHECK-LABEL: @add_nuw(
30 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
31 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
32 ; CHECK-NEXT: [[RES:%.*]] = add nuw i32 [[A]], [[B]]
33 ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
34 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
35 ; CHECK-NEXT: ret i32 [[RES]]
37 %res = add nuw i32 %a, %b
41 define i32 @add_nsw_nuw(i32 %a, i32 %b) {
42 ; CHECK-LABEL: @add_nsw_nuw(
43 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
44 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
45 ; CHECK-NEXT: [[TMP3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A]], i32 [[B]])
46 ; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1
47 ; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]]
48 ; CHECK-NEXT: [[RES:%.*]] = add nuw nsw i32 [[A]], [[B]]
49 ; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP5]], true
50 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP6]])
51 ; CHECK-NEXT: ret i32 [[RES]]
53 %res = add nsw nuw i32 %a, %b
57 define i32 @sub_noflags(i32 %a, i32 %b) {
58 ; CHECK-LABEL: @sub_noflags(
59 ; CHECK-NEXT: [[RES:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
60 ; CHECK-NEXT: ret i32 [[RES]]
66 define i32 @sub_nsw(i32 %a, i32 %b) {
67 ; CHECK-LABEL: @sub_nsw(
68 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
69 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
70 ; CHECK-NEXT: [[RES:%.*]] = sub nsw i32 [[A]], [[B]]
71 ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
72 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
73 ; CHECK-NEXT: ret i32 [[RES]]
75 %res = sub nsw i32 %a, %b
79 define i32 @sub_nuw(i32 %a, i32 %b) {
80 ; CHECK-LABEL: @sub_nuw(
81 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
82 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
83 ; CHECK-NEXT: [[RES:%.*]] = sub nuw i32 [[A]], [[B]]
84 ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
85 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
86 ; CHECK-NEXT: ret i32 [[RES]]
88 %res = sub nuw i32 %a, %b
92 define i32 @sub_nsw_nuw(i32 %a, i32 %b) {
93 ; CHECK-LABEL: @sub_nsw_nuw(
94 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
95 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
96 ; CHECK-NEXT: [[TMP3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
97 ; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1
98 ; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]]
99 ; CHECK-NEXT: [[RES:%.*]] = sub nuw nsw i32 [[A]], [[B]]
100 ; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP5]], true
101 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP6]])
102 ; CHECK-NEXT: ret i32 [[RES]]
104 %res = sub nsw nuw i32 %a, %b
108 define i32 @mul_noflags(i32 %a, i32 %b) {
109 ; CHECK-LABEL: @mul_noflags(
110 ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A:%.*]], [[B:%.*]]
111 ; CHECK-NEXT: ret i32 [[RES]]
113 %res = mul i32 %a, %b
117 define i32 @mul_nsw(i32 %a, i32 %b) {
118 ; CHECK-LABEL: @mul_nsw(
119 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
120 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
121 ; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], [[B]]
122 ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
123 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
124 ; CHECK-NEXT: ret i32 [[RES]]
126 %res = mul nsw i32 %a, %b
130 define i32 @mul_nuw(i32 %a, i32 %b) {
131 ; CHECK-LABEL: @mul_nuw(
132 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
133 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
134 ; CHECK-NEXT: [[RES:%.*]] = mul nuw i32 [[A]], [[B]]
135 ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
136 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
137 ; CHECK-NEXT: ret i32 [[RES]]
139 %res = mul nuw i32 %a, %b
143 define i32 @mul_nsw_nuw(i32 %a, i32 %b) {
144 ; CHECK-LABEL: @mul_nsw_nuw(
145 ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]])
146 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
147 ; CHECK-NEXT: [[TMP3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[A]], i32 [[B]])
148 ; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1
149 ; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]]
150 ; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], [[B]]
151 ; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP5]], true
152 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP6]])
153 ; CHECK-NEXT: ret i32 [[RES]]
155 %res = mul nsw nuw i32 %a, %b
159 define i32 @sdiv_noflags(i32 %a, i32 %b) {
160 ; CHECK-LABEL: @sdiv_noflags(
161 ; CHECK-NEXT: [[RES:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]
162 ; CHECK-NEXT: ret i32 [[RES]]
164 %res = sdiv i32 %a, %b
168 define i32 @sdiv_exact(i32 %a, i32 %b) {
169 ; CHECK-LABEL: @sdiv_exact(
170 ; CHECK-NEXT: [[TMP1:%.*]] = srem i32 [[A:%.*]], [[B:%.*]]
171 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
172 ; CHECK-NEXT: [[RES:%.*]] = sdiv exact i32 [[A]], [[B]]
173 ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
174 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
175 ; CHECK-NEXT: ret i32 [[RES]]
177 %res = sdiv exact i32 %a, %b
181 define i32 @udiv_noflags(i32 %a, i32 %b) {
182 ; CHECK-LABEL: @udiv_noflags(
183 ; CHECK-NEXT: [[RES:%.*]] = udiv i32 [[A:%.*]], [[B:%.*]]
184 ; CHECK-NEXT: ret i32 [[RES]]
186 %res = udiv i32 %a, %b
190 define i32 @udiv_exact(i32 %a, i32 %b) {
191 ; CHECK-LABEL: @udiv_exact(
192 ; CHECK-NEXT: [[TMP1:%.*]] = urem i32 [[A:%.*]], [[B:%.*]]
193 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
194 ; CHECK-NEXT: [[RES:%.*]] = udiv exact i32 [[A]], [[B]]
195 ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
196 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
197 ; CHECK-NEXT: ret i32 [[RES]]
199 %res = udiv exact i32 %a, %b
203 define i32 @ashr_noflags(i32 %a, i32 %b) {
204 ; CHECK-LABEL: @ashr_noflags(
205 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32
206 ; CHECK-NEXT: [[RES:%.*]] = ashr i32 [[A:%.*]], [[B]]
207 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
208 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
209 ; CHECK-NEXT: ret i32 [[RES]]
211 %res = ashr i32 %a, %b
215 define i32 @ashr_exact(i32 %a, i32 %b) {
216 ; CHECK-LABEL: @ashr_exact(
217 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32
218 ; CHECK-NEXT: [[RES:%.*]] = ashr exact i32 [[A:%.*]], [[B]]
219 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
220 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
221 ; CHECK-NEXT: ret i32 [[RES]]
223 %res = ashr exact i32 %a, %b
227 define i32 @lshr_noflags(i32 %a, i32 %b) {
228 ; CHECK-LABEL: @lshr_noflags(
229 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32
230 ; CHECK-NEXT: [[RES:%.*]] = lshr i32 [[A:%.*]], [[B]]
231 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
232 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
233 ; CHECK-NEXT: ret i32 [[RES]]
235 %res = lshr i32 %a, %b
239 define i32 @lshr_exact(i32 %a, i32 %b) {
240 ; CHECK-LABEL: @lshr_exact(
241 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32
242 ; CHECK-NEXT: [[RES:%.*]] = lshr exact i32 [[A:%.*]], [[B]]
243 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
244 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
245 ; CHECK-NEXT: ret i32 [[RES]]
247 %res = lshr exact i32 %a, %b
251 define i32 @shl_noflags(i32 %a, i32 %b) {
252 ; CHECK-LABEL: @shl_noflags(
253 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32
254 ; CHECK-NEXT: [[RES:%.*]] = shl i32 [[A:%.*]], [[B]]
255 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
256 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
257 ; CHECK-NEXT: ret i32 [[RES]]
259 %res = shl i32 %a, %b
263 define i32 @shl_nsw(i32 %a, i32 %b) {
264 ; CHECK-LABEL: @shl_nsw(
265 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32
266 ; CHECK-NEXT: [[RES:%.*]] = shl nsw i32 [[A:%.*]], [[B]]
267 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
268 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
269 ; CHECK-NEXT: ret i32 [[RES]]
271 %res = shl nsw i32 %a, %b
275 define i32 @shl_nuw(i32 %a, i32 %b) {
276 ; CHECK-LABEL: @shl_nuw(
277 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32
278 ; CHECK-NEXT: [[RES:%.*]] = shl nuw i32 [[A:%.*]], [[B]]
279 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
280 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
281 ; CHECK-NEXT: ret i32 [[RES]]
283 %res = shl nuw i32 %a, %b
287 define i32 @shl_nsw_nuw(i32 %a, i32 %b) {
288 ; CHECK-LABEL: @shl_nsw_nuw(
289 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32
290 ; CHECK-NEXT: [[RES:%.*]] = shl nuw nsw i32 [[A:%.*]], [[B]]
291 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
292 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
293 ; CHECK-NEXT: ret i32 [[RES]]
295 %res = shl nsw nuw i32 %a, %b
299 define i32 @extractelement(<4 x i32> %v, i32 %idx) {
300 ; CHECK-LABEL: @extractelement(
301 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[IDX:%.*]], 4
302 ; CHECK-NEXT: [[RES:%.*]] = extractelement <4 x i32> [[V:%.*]], i32 [[IDX]]
303 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
304 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
305 ; CHECK-NEXT: ret i32 [[RES]]
307 %res = extractelement <4 x i32> %v, i32 %idx
311 define <4 x i32> @insertelement(<4 x i32> %v, i32 %idx, i32 %val) {
312 ; CHECK-LABEL: @insertelement(
313 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[IDX:%.*]], 4
314 ; CHECK-NEXT: [[RES:%.*]] = insertelement <4 x i32> [[V:%.*]], i32 [[VAL:%.*]], i32 [[IDX]]
315 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
316 ; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]])
317 ; CHECK-NEXT: ret <4 x i32> [[RES]]
319 %res = insertelement <4 x i32> %v, i32 %val, i32 %idx