[PATCH] D62792: [SimplifyIndVar] Simplify non-overflowing saturating add/sub

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 15 01:47:21 PDT 2019


This revision was automatically updated to reflect the committed changes.
Closed by commit rL363489: [SimplifyIndVar] Simplify non-overflowing saturating add/sub (authored by nikic, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D62792?vs=202589&id=204907#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62792/new/

https://reviews.llvm.org/D62792

Files:
  llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp
  llvm/trunk/test/Transforms/IndVarSimplify/eliminate-sat.ll


Index: llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp
===================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -81,6 +81,7 @@
     bool replaceIVUserWithLoopInvariant(Instruction *UseInst);
 
     bool eliminateOverflowIntrinsic(WithOverflowInst *WO);
+    bool eliminateSaturatingIntrinsic(SaturatingInst *SI);
     bool eliminateTrunc(TruncInst *TI);
     bool eliminateIVUser(Instruction *UseInst, Instruction *IVOperand);
     bool makeIVComparisonInvariant(ICmpInst *ICmp, Value *IVOperand);
@@ -477,6 +478,25 @@
   return true;
 }
 
+bool SimplifyIndvar::eliminateSaturatingIntrinsic(SaturatingInst *SI) {
+  const SCEV *LHS = SE->getSCEV(SI->getLHS());
+  const SCEV *RHS = SE->getSCEV(SI->getRHS());
+  if (!willNotOverflow(SE, SI->getBinaryOp(), SI->isSigned(), LHS, RHS))
+    return false;
+
+  BinaryOperator *BO = BinaryOperator::Create(
+      SI->getBinaryOp(), SI->getLHS(), SI->getRHS(), SI->getName(), SI);
+  if (SI->isSigned())
+    BO->setHasNoSignedWrap();
+  else
+    BO->setHasNoUnsignedWrap();
+
+  SI->replaceAllUsesWith(BO);
+  DeadInsts.emplace_back(SI);
+  Changed = true;
+  return true;
+}
+
 bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) {
   // It is always legal to replace
   //   icmp <pred> i32 trunc(iv), n
@@ -614,6 +634,10 @@
     if (eliminateOverflowIntrinsic(WO))
       return true;
 
+  if (auto *SI = dyn_cast<SaturatingInst>(UseInst))
+    if (eliminateSaturatingIntrinsic(SI))
+      return true;
+
   if (auto *TI = dyn_cast<TruncInst>(UseInst))
     if (eliminateTrunc(TI))
       return true;
Index: llvm/trunk/test/Transforms/IndVarSimplify/eliminate-sat.ll
===================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/eliminate-sat.ll
+++ llvm/trunk/test/Transforms/IndVarSimplify/eliminate-sat.ll
@@ -12,8 +12,8 @@
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
-; CHECK-NEXT:    [[SAT:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[I]], i32 1)
-; CHECK-NEXT:    store volatile i32 [[SAT]], i32* [[P:%.*]]
+; CHECK-NEXT:    [[SAT1:%.*]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    store volatile i32 [[SAT1]], i32* [[P:%.*]]
 ; CHECK-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
@@ -41,8 +41,8 @@
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
-; CHECK-NEXT:    [[SAT:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[I]], i32 1)
-; CHECK-NEXT:    store volatile i32 [[SAT]], i32* [[P:%.*]]
+; CHECK-NEXT:    [[SAT1:%.*]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    store volatile i32 [[SAT1]], i32* [[P:%.*]]
 ; CHECK-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
@@ -70,8 +70,8 @@
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
-; CHECK-NEXT:    [[SAT:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[I]], i32 1)
-; CHECK-NEXT:    store volatile i32 [[SAT]], i32* [[P:%.*]]
+; CHECK-NEXT:    [[SAT1:%.*]] = sub nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    store volatile i32 [[SAT1]], i32* [[P:%.*]]
 ; CHECK-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
@@ -99,8 +99,8 @@
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
-; CHECK-NEXT:    [[SAT:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[I]], i32 1)
-; CHECK-NEXT:    store volatile i32 [[SAT]], i32* [[P:%.*]]
+; CHECK-NEXT:    [[SAT1:%.*]] = sub nsw i32 [[I]], 1
+; CHECK-NEXT:    store volatile i32 [[SAT1]], i32* [[P:%.*]]
 ; CHECK-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62792.204907.patch
Type: text/x-patch
Size: 4366 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190615/a66eba31/attachment.bin>


More information about the llvm-commits mailing list