[PATCH] SCEV incorrectly marks certain expressions as nsw

Sanjoy Das sanjoy at playingwithpointers.com
Sat Feb 14 00:54:34 PST 2015


Hi atrick, hfinkel,

Unfortunately, I could not come up with a test case for this one; but I don't think `getPreStartForSignExtend` can assume `AR` is `nsw` -- there is one place in scalar evolution that calls `getSignExtendAddRecStart(AR, ...)` without proving that `AR` is `nsw` 

(line 1564)

          OperandExtendedAdd =
            getAddExpr(WideStart,
                       getMulExpr(WideMaxBECount,
                                  getZeroExtendExpr(Step, WideTy)));
          if (SAdd == OperandExtendedAdd) {
            // If AR wraps around then
            //
            //    abs(Step) * MaxBECount > unsigned-max(AR->getType())
            // => SAdd != OperandExtendedAdd
            //
            // Thus (AR is not NW => SAdd != OperandExtendedAdd) <=>
            // (SAdd == OperandExtendedAdd => AR is NW)

            const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNW);

            // Return the expression with the addrec on the outside.
            return getAddRecExpr(getSignExtendAddRecStart(AR, Ty, this),
                                 getZeroExtendExpr(Step, Ty),
                                 L, AR->getNoWrapFlags());
          }
        }

http://reviews.llvm.org/D7640

Files:
  lib/Analysis/ScalarEvolution.cpp

Index: lib/Analysis/ScalarEvolution.cpp
===================================================================
--- lib/Analysis/ScalarEvolution.cpp
+++ lib/Analysis/ScalarEvolution.cpp
@@ -1327,12 +1327,12 @@
   return nullptr;
 }
 
-// The recurrence AR has been shown to have no signed wrap. Typically, if we can
-// prove NSW for AR, then we can just as easily prove NSW for its preincrement
-// or postincrement sibling. This allows normalizing a sign extended AddRec as
-// such: {sext(Step + Start),+,Step} => {(Step + sext(Start),+,Step} As a
-// result, the expression "Step + sext(PreIncAR)" is congruent with
-// "sext(PostIncAR)"
+// The recurrence AR has been shown to have no signed wrap or something close to
+// it.  Typically, if we can prove NSW for AR, then we can just as easily prove
+// NSW for its preincrement or postincrement sibling. This allows normalizing a
+// sign extended AddRec as such: {sext(Step + Start),+,Step} => {(Step +
+// sext(Start),+,Step} As a result, the expression "Step + sext(PreIncAR)" is
+// congruent with "sext(PostIncAR)"
 static const SCEV *getPreStartForSignExtend(const SCEVAddRecExpr *AR,
                                             Type *Ty,
                                             ScalarEvolution *SE) {
@@ -1392,7 +1392,7 @@
                    SE->getSignExtendExpr(Step, WideTy));
   if (SE->getSignExtendExpr(Start, WideTy) == OperandExtendedStart) {
     // Cache knowledge of PreAR NSW.
-    if (PreAR)
+    if (PreAR && AR->getNoWrapFlags(SCEV::FlagNSW))
       const_cast<SCEVAddRecExpr *>(PreAR)->setNoWrapFlags(SCEV::FlagNSW);
     // FIXME: this optimization needs a unit test
     DEBUG(dbgs() << "SCEV: untested prestart overflow check\n");

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7640.19964.patch
Type: text/x-patch
Size: 1716 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150214/b825fdf9/attachment.bin>


More information about the llvm-commits mailing list