@@ -241,3 +241,41 @@ define i1 @pr21445(i8 %a) {
241
241
%cmp = icmp ne i32 %mul , %and
242
242
ret i1 %cmp
243
243
}
244
+
245
+ ; Negative test: mul(zext x, zext y) may overflow.
246
+ define i32 @mul_may_overflow (i32 %x , i32 %y ) {
247
+ ; CHECK-LABEL: @mul_may_overflow(
248
+ ; CHECK-NEXT: entry:
249
+ ; CHECK-NEXT: [[L:%.*]] = zext i32 [[X:%.*]] to i34
250
+ ; CHECK-NEXT: [[R:%.*]] = zext i32 [[Y:%.*]] to i34
251
+ ; CHECK-NEXT: [[MUL34:%.*]] = mul i34 [[L]], [[R]]
252
+ ; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i34 [[MUL34]], 4294967296
253
+ ; CHECK-NEXT: [[RETVAL:%.*]] = zext i1 [[OVERFLOW]] to i32
254
+ ; CHECK-NEXT: ret i32 [[RETVAL]]
255
+ ;
256
+ entry:
257
+ %l = zext i32 %x to i34
258
+ %r = zext i32 %y to i34
259
+ %mul34 = mul i34 %l , %r
260
+ %overflow = icmp ule i34 %mul34 , 4294967295
261
+ %retval = zext i1 %overflow to i32
262
+ ret i32 %retval
263
+ }
264
+
265
+ define i32 @mul_known_nuw (i32 %x , i32 %y ) {
266
+ ; CHECK-LABEL: @mul_known_nuw(
267
+ ; CHECK-NEXT: entry:
268
+ ; CHECK-NEXT: [[UMUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
269
+ ; CHECK-NEXT: [[TMP0:%.*]] = extractvalue { i32, i1 } [[UMUL]], 1
270
+ ; CHECK-NEXT: [[OVERFLOW:%.*]] = xor i1 [[TMP0]], true
271
+ ; CHECK-NEXT: [[RETVAL:%.*]] = zext i1 [[OVERFLOW]] to i32
272
+ ; CHECK-NEXT: ret i32 [[RETVAL]]
273
+ ;
274
+ entry:
275
+ %l = zext i32 %x to i34
276
+ %r = zext i32 %y to i34
277
+ %mul34 = mul nuw i34 %l , %r
278
+ %overflow = icmp ule i34 %mul34 , 4294967295
279
+ %retval = zext i1 %overflow to i32
280
+ ret i32 %retval
281
+ }
0 commit comments