[PATCH] D12073: Make ScalarEvolution::isKnownPredicate a little smarter
    Sanjoy Das via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Mon Aug 17 22:15:47 PDT 2015
    
    
  
sanjoy added a comment.
In http://reviews.llvm.org/D12073#226151, @hfinkel wrote:
>
> There are now three failing tests, mostly due to IV widening that now does not happen. The new known-predicate results are:
> 
> test/Transforms/IndVarSimplify/elim-extend.ll:
> 
> - {%init,+,1}<nsw><%loop> sle {(1 + %init),+,1}<nsw><%loop>
> - {(sext i32 %init to i64),+,1}<nsw><%loop> sle {(1 + (sext i32 %init to i64)),+,1}<nsw><%loop>
> - {-1,+,1}<nsw><%outerloop> sle {1,+,1}<nuw><%outerloop>
> - {-1,+,1}<nsw><%outerloop> sle {1,+,1}<nuw><nsw><%outerloop>
> 
>   test/Transforms/IndVarSimplify/iv-sext.ll:
> - {-1,+,1}<nsw><%bb> sle {1,+,1}<nuw><%bb>
> - {-1,+,1}<nsw><%bb> sle {1,+,1}<nuw><nsw><%bb>
> 
>   test/Transforms/IndVarSimplify/strengthen-overflow.ll:
> - {%init,+,1}<nsw><%loop> sle {(1 + %init),+,1}<nsw><%loop>
> 
>   These look right, but some consumer of the information seems to make a worse no-wrap deductions as a result (thus, this patch is still WIP).
I suspect (haven't verified) this is due to SCEV's caching mechanism. You end up creating a "Sext(LHS)" too soon, before proving all of the things needed to show that LHS is nsw.  Then this suboptimal result gets cached.
In other words, I suspect the stack trace looks like this (youngest frame at top) initially:
  == false because of PendingLoopPredicates, set in frame (A)
  getImpliedCond(...)  // ends up looking at VAL
  getLoopBackedgeCount(...)
  getSignExtend(VAL)  // due to your change
  getImpliedCond(...)  // ends up looking at VAL .. (A)
  getLoopBackedgeCount(...)
  getSignExtend(VAL)
This goes on as
    getSignExtend(VAL)  ==> no simplification, and we end up with
          UniqueSCEVs[(SignExtend, VAL)] = SignExtendExpr VAL, and
  	does not set the <nsw> bit in VAL
    getImpliedCond(...)  // ends up looking at VAL .. (A)
    getLoopBackedgeCount(...)
    getSignExtend(VAL)
And then finally the oldest frame returns:
  getSignExtend(VAL)  // this returns a widened version of VAL (instead of
    an explicit sign extend), and also set VAL's nsw bit
However, the damage has been done since `UniqueSCEVs[(SignExtend, VAL)] == (SignExtendExpr VAL)` and that's the value `ScalarEvolution::getSignExtendExpr`  will return from now on.
If you implement your check without actually creating a sign extend, but by directly inferring no-overflow from the nsw or nuw flags, then I suspect this won't happen.
================
Comment at: lib/Analysis/ScalarEvolution.cpp:7355
@@ +7354,3 @@
+  case ICmpInst::ICMP_SLT:
+    if (SE.isKnownNegative(SignedDiff()))
+      return true;
----------------
I think this change would be cleaner if `SignedDiff` took explicit `LHS` and `RHS` arguments.
http://reviews.llvm.org/D12073
    
    
More information about the llvm-commits
mailing list