[PATCH] D62544: [InstCombine] Optimize always overflowing signed saturating add/sub
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue May 28 12:00:56 PDT 2019
nikic created this revision.
nikic added reviewers: lebedev.ri, spatel.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
Based on the overflow direction information added in D62463 <https://reviews.llvm.org/D62463>, we can now fold always overflowing signed saturating add/sub to signed min/max.
Repository:
rL LLVM
https://reviews.llvm.org/D62544
Files:
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/saturating-add-sub.ll
Index: llvm/test/Transforms/InstCombine/saturating-add-sub.ll
===================================================================
--- llvm/test/Transforms/InstCombine/saturating-add-sub.ll
+++ llvm/test/Transforms/InstCombine/saturating-add-sub.ll
@@ -341,10 +341,7 @@
define i8 @test_scalar_sadd_always_overflows_low(i8 %a) {
; CHECK-LABEL: @test_scalar_sadd_always_overflows_low(
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], -120
-; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP]], i8 [[A]], i8 -120
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[MIN]], i8 -10)
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 -128
;
%cmp = icmp slt i8 %a, -120
%min = select i1 %cmp, i8 %a, i8 -120
@@ -354,10 +351,7 @@
define i8 @test_scalar_sadd_always_overflows_high(i8 %a) {
; CHECK-LABEL: @test_scalar_sadd_always_overflows_high(
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], 120
-; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP]], i8 [[A]], i8 120
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[MAX]], i8 10)
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 127
;
%cmp = icmp sgt i8 %a, 120
%max = select i1 %cmp, i8 %a, i8 120
@@ -829,10 +823,7 @@
define i8 @test_scalar_ssub_always_overflows_low(i8 %a) {
; CHECK-LABEL: @test_scalar_ssub_always_overflows_low(
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], 120
-; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP]], i8 [[A]], i8 120
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 -10, i8 [[MAX]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 -128
;
%cmp = icmp sgt i8 %a, 120
%max = select i1 %cmp, i8 %a, i8 120
@@ -842,10 +833,7 @@
define i8 @test_scalar_ssub_always_overflows_high(i8 %a) {
; CHECK-LABEL: @test_scalar_ssub_always_overflows_high(
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], -120
-; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP]], i8 [[A]], i8 -120
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 10, i8 [[MIN]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 127
;
%cmp = icmp slt i8 %a, -120
%min = select i1 %cmp, i8 %a, i8 -120
Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2053,6 +2053,7 @@
case Intrinsic::usub_sat:
case Intrinsic::ssub_sat: {
SaturatingInst *SI = cast<SaturatingInst>(II);
+ Type *Ty = SI->getType();
Value *Arg0 = SI->getLHS();
Value *Arg1 = SI->getRHS();
@@ -2067,14 +2068,18 @@
return BinaryOperator::CreateNSW(SI->getBinaryOp(), Arg0, Arg1);
else
return BinaryOperator::CreateNUW(SI->getBinaryOp(), Arg0, Arg1);
- case OverflowResult::AlwaysOverflowsLow:
- if (SI->isSigned()) break; // TODO: Support signed.
- return replaceInstUsesWith(*SI,
- ConstantInt::getNullValue(II->getType()));
- case OverflowResult::AlwaysOverflowsHigh:
- if (SI->isSigned()) break; // TODO: Support signed.
- return replaceInstUsesWith(*SI,
- ConstantInt::getAllOnesValue(II->getType()));
+ case OverflowResult::AlwaysOverflowsLow: {
+ unsigned BitWidth = Ty->getScalarSizeInBits();
+ APInt Min = SI->isSigned() ? APInt::getSignedMinValue(BitWidth)
+ : APInt::getMinValue(BitWidth);
+ return replaceInstUsesWith(*SI, ConstantInt::get(Ty, Min));
+ }
+ case OverflowResult::AlwaysOverflowsHigh: {
+ unsigned BitWidth = Ty->getScalarSizeInBits();
+ APInt Max = SI->isSigned() ? APInt::getSignedMaxValue(BitWidth)
+ : APInt::getMaxValue(BitWidth);
+ return replaceInstUsesWith(*SI, ConstantInt::get(Ty, Max));
+ }
}
// ssub.sat(X, C) -> sadd.sat(X, -C) if C != MIN
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62544.201738.patch
Type: text/x-patch
Size: 3997 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190528/0ef81adc/attachment.bin>
More information about the llvm-commits
mailing list