From: Nikita Popov Date: Tue, 9 Apr 2019 20:02:23 +0000 (+0000) Subject: [InstCombine] Add with.overflow always overflow tests; NFC X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b182ab7d784ff9f8da60cc0c1329633043c0485e;p=llvm [InstCombine] Add with.overflow always overflow tests; NFC The uadd and umul cases are currently handled, the usub, sadd, ssub and smul cases are not. usub, sadd and ssub already have the necessary ValueTracking support, smul doesn't. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358031 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Transforms/InstCombine/with_overflow.ll b/test/Transforms/InstCombine/with_overflow.ll index c03c3693c0b..d5854f4a2f1 100644 --- a/test/Transforms/InstCombine/with_overflow.ll +++ b/test/Transforms/InstCombine/with_overflow.ll @@ -2,7 +2,11 @@ ; RUN: opt -instcombine -S < %s | FileCheck %s declare { i8, i1 } @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone +declare { i8, i1 } @llvm.sadd.with.overflow.i8(i8, i8) nounwind readnone +declare { i8, i1 } @llvm.usub.with.overflow.i8(i8, i8) nounwind readnone +declare { i8, i1 } @llvm.ssub.with.overflow.i8(i8, i8) nounwind readnone declare { i8, i1 } @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone +declare { i8, i1 } @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone @@ -522,3 +526,78 @@ define { i32, i1 } @umul_canonicalize_constant_arg0(i32 %x) nounwind { %a = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 42, i32 %x) ret { i32, i1 } %a } + +; Always overflow tests + +define { i8, i1 } @uadd_always_overflow(i8 %x) nounwind { +; CHECK-LABEL: @uadd_always_overflow( +; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -64 +; CHECK-NEXT: [[A:%.*]] = add nsw i8 [[Y]], 64 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i8, i1 } { i8 undef, i1 true }, i8 [[A]], 0 +; CHECK-NEXT: ret { i8, i1 } [[TMP1]] +; + %y = or i8 %x, 192 + %a = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %y, i8 64) + ret { i8, i1 } %a +} + +define { i8, i1 } @usub_always_overflow(i8 %x) nounwind { +; CHECK-LABEL: @usub_always_overflow( +; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 64 +; CHECK-NEXT: [[A:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 63, i8 [[Y]]) +; CHECK-NEXT: ret { i8, i1 } [[A]] +; + %y = or i8 %x, 64 + %a = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 63, i8 %y) + ret { i8, i1 } %a +} + +define { i8, i1 } @umul_always_overflow(i8 %x) nounwind { +; CHECK-LABEL: @umul_always_overflow( +; CHECK-NEXT: [[A:%.*]] = shl i8 [[X:%.*]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i8, i1 } { i8 undef, i1 true }, i8 [[A]], 0 +; CHECK-NEXT: ret { i8, i1 } [[TMP1]] +; + %y = or i8 %x, 128 + %a = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %y, i8 2) + ret { i8, i1 } %a +} + +define { i8, i1 } @sadd_always_overflow(i8 %x) nounwind { +; CHECK-LABEL: @sadd_always_overflow( +; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X:%.*]], 100 +; CHECK-NEXT: [[Y:%.*]] = select i1 [[C]], i8 [[X]], i8 100 +; CHECK-NEXT: [[A:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[Y]], i8 28) +; CHECK-NEXT: ret { i8, i1 } [[A]] +; + %c = icmp sgt i8 %x, 100 + %y = select i1 %c, i8 %x, i8 100 + %a = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %y, i8 28) + ret { i8, i1 } %a +} + +define { i8, i1 } @ssub_always_overflow(i8 %x) nounwind { +; CHECK-LABEL: @ssub_always_overflow( +; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X:%.*]], 29 +; CHECK-NEXT: [[Y:%.*]] = select i1 [[C]], i8 [[X]], i8 29 +; CHECK-NEXT: [[A:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 -100, i8 [[Y]]) +; CHECK-NEXT: ret { i8, i1 } [[A]] +; + %c = icmp sgt i8 %x, 29 + %y = select i1 %c, i8 %x, i8 29 + %a = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 -100, i8 %y) + ret { i8, i1 } %a +} + +define { i8, i1 } @smul_always_overflow(i8 %x) nounwind { +; CHECK-LABEL: @smul_always_overflow( +; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X:%.*]], 100 +; CHECK-NEXT: [[Y:%.*]] = select i1 [[C]], i8 [[X]], i8 100 +; CHECK-NEXT: [[A:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 2) +; CHECK-NEXT: ret { i8, i1 } [[A]] +; + %c = icmp sgt i8 %x, 100 + %y = select i1 %c, i8 %x, i8 100 + %a = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %y, i8 2) + ret { i8, i1 } %a +}