[llvm] r334318 - [SCEV] Look through zero-extends in howFarToZero

Mikael Holmén via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 15 01:05:31 PDT 2018


Hi Krzysztof,

With this patch, the following crashes when doing howFarToZero.

  opt bbi-15347.ll -o - -S -indvars

gives:

opt: ../lib/Support/APInt.cpp:1535: llvm::APInt llvm::APInt::udiv(const 
llvm::APInt &) const: Assertion `RHS.U.VAL != 0 && "Divide by zero?"' 
failed.
Stack dump:
0.      Program arguments: build-all/bin/opt bbi-15347.ll -o - -S -indvars
1.      Running pass 'Function Pass Manager' on module 'bbi-15347.ll'.
2.      Running pass 'Loop Pass Manager' on function '@f1'
3.      Running pass 'Induction Variable Simplification' on basic block 
'%lbl1'
#0 0x0000000001fde964 PrintStackTraceSignalHandler(void*) 
(build-all/bin/opt+0x1fde964)
#1 0x0000000001fdcbb0 llvm::sys::RunSignalHandlers() 
(build-all/bin/opt+0x1fdcbb0)
#2 0x0000000001fdecc8 SignalHandler(int) (build-all/bin/opt+0x1fdecc8)
#3 0x00007f9187030330 __restore_rt 
(/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)
#4 0x00007f9185c1fc37 gsignal 
/build/eglibc-ripdx6/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
#5 0x00007f9185c23028 abort 
/build/eglibc-ripdx6/eglibc-2.19/stdlib/abort.c:91:0
#6 0x00007f9185c18bf6 __assert_fail_base 
/build/eglibc-ripdx6/eglibc-2.19/assert/assert.c:92:0
#7 0x00007f9185c18ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)
#8 0x0000000001f73558 llvm::APInt::udiv(llvm::APInt const&) const 
(build-all/bin/opt+0x1f73558)
#9 0x0000000001f78a03 llvm::APInt::sdiv(llvm::APInt const&) const 
(build-all/bin/opt+0x1f78a03)
#10 0x00000000015a6ce0 SolveQuadraticEquation(llvm::SCEVAddRecExpr 
const*, llvm::ScalarEvolution&) (build-all/bin/opt+0x15a6ce0)
#11 0x00000000015a176e llvm::ScalarEvolution::howFarToZero(llvm::SCEV 
const*, llvm::Loop const*, bool, bool) (build-all/bin/opt+0x15a176e)
#12 0x000000000159dc5b 
llvm::ScalarEvolution::computeExitLimitFromICmp(llvm::Loop const*, 
llvm::ICmpInst*, bool, bool, bool) (build-all/bin/opt+0x159dc5b)
#13 0x000000000159d493 
llvm::ScalarEvolution::computeExitLimitFromCondImpl(llvm::ScalarEvolution::ExitLimitCache&, 
llvm::Loop const*, llvm::Value*, bool, bool, bool) 
(build-all/bin/opt+0x159d493)
#14 0x000000000159ce8f 
llvm::ScalarEvolution::computeExitLimitFromCondCached(llvm::ScalarEvolution::ExitLimitCache&, 
llvm::Loop const*, llvm::Value*, bool, bool, bool) 
(build-all/bin/opt+0x159ce8f)
#15 0x000000000159c4fc 
llvm::ScalarEvolution::computeExitLimit(llvm::Loop const*, 
llvm::BasicBlock*, bool) (build-all/bin/opt+0x159c4fc)
#16 0x000000000159a219 
llvm::ScalarEvolution::computeBackedgeTakenCount(llvm::Loop const*, 
bool) (build-all/bin/opt+0x159a219)
#17 0x0000000001598fcc 
llvm::ScalarEvolution::getBackedgeTakenInfo(llvm::Loop const*) 
(build-all/bin/opt+0x1598fcc)
#18 0x0000000001599d8f 
llvm::ScalarEvolution::getBackedgeTakenCount(llvm::Loop const*) 
(build-all/bin/opt+0x1599d8f)
#19 0x0000000001dd992a (anonymous 
namespace)::IndVarSimplify::run(llvm::Loop*) (build-all/bin/opt+0x1dd992a)
#20 0x0000000001ddee2c (anonymous 
namespace)::IndVarSimplifyLegacyPass::runOnLoop(llvm::Loop*, 
llvm::LPPassManager&) (build-all/bin/opt+0x1ddee2c)
#21 0x0000000001522ab5 
llvm::LPPassManager::runOnFunction(llvm::Function&) 
(build-all/bin/opt+0x1522ab5)
#22 0x0000000001a6d13a 
llvm::FPPassManager::runOnFunction(llvm::Function&) 
(build-all/bin/opt+0x1a6d13a)
#23 0x0000000001a6d398 llvm::FPPassManager::runOnModule(llvm::Module&) 
(build-all/bin/opt+0x1a6d398)
#24 0x0000000001a6d8cd llvm::legacy::PassManagerImpl::run(llvm::Module&) 
(build-all/bin/opt+0x1a6d8cd)
#25 0x0000000000744b9c main (build-all/bin/opt+0x744b9c)
#26 0x00007f9185c0af45 __libc_start_main 
/build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:321:0
#27 0x000000000072defd _start (build-all/bin/opt+0x72defd)

Regards,
Mikael


On 06/08/2018 10:43 PM, Krzysztof Parzyszek via llvm-commits wrote:
> Author: kparzysz
> Date: Fri Jun  8 13:43:07 2018
> New Revision: 334318
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=334318&view=rev
> Log:
> [SCEV] Look through zero-extends in howFarToZero
> 
> An expression like
>    (zext i2 {(trunc i32 (1 + %B) to i2),+,1}<%while.body> to i32)
> will become zero exactly when the nested value becomes zero in its type.
> Strip injective operations from the input value in howFarToZero to make
> the value simpler.
> 
> Differential Revision: https://reviews.llvm.org/D47951
> 
> Added:
>      llvm/trunk/test/Analysis/ScalarEvolution/strip-injective-zext.ll
> Modified:
>      llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
>      llvm/trunk/lib/Analysis/ScalarEvolution.cpp
> 
> Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=334318&r1=334317&r2=334318&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
> +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri Jun  8 13:43:07 2018
> @@ -1833,6 +1833,9 @@ private:
>     const SCEV *getOrCreateMulExpr(SmallVectorImpl<const SCEV *> &Ops,
>                                    SCEV::NoWrapFlags Flags);
>   
> +  /// Return x if \p Val is f(x) where f is a 1-1 function.
> +  const SCEV *stripInjectiveFunctions(const SCEV *Val) const;
> +
>     /// Find all of the loops transitively used in \p S, and fill \p LoopsUsed.
>     /// A loop is considered "used" by an expression if it contains
>     /// an add rec on said loop.
> 
> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=334318&r1=334317&r2=334318&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri Jun  8 13:43:07 2018
> @@ -8150,6 +8150,14 @@ const SCEV *ScalarEvolution::getSCEVAtSc
>     return getSCEVAtScope(getSCEV(V), L);
>   }
>   
> +const SCEV *ScalarEvolution::stripInjectiveFunctions(const SCEV *S) const {
> +  if (const SCEVZeroExtendExpr *ZExt = dyn_cast<SCEVZeroExtendExpr>(S))
> +    return stripInjectiveFunctions(ZExt->getOperand());
> +  if (const SCEVSignExtendExpr *SExt = dyn_cast<SCEVSignExtendExpr>(S))
> +    return stripInjectiveFunctions(SExt->getOperand());
> +  return S;
> +}
> +
>   /// Finds the minimum unsigned root of the following equation:
>   ///
>   ///     A * X = B (mod N)
> @@ -8279,7 +8287,9 @@ ScalarEvolution::howFarToZero(const SCEV
>       return getCouldNotCompute();  // Otherwise it will loop infinitely.
>     }
>   
> -  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(V);
> +  const SCEVAddRecExpr *AddRec =
> +      dyn_cast<SCEVAddRecExpr>(stripInjectiveFunctions(V));
> +
>     if (!AddRec && AllowPredicates)
>       // Try to make this an AddRec using runtime tests, in the first X
>       // iterations of this loop, where X is the SCEV expression found by the
> 
> Added: llvm/trunk/test/Analysis/ScalarEvolution/strip-injective-zext.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/strip-injective-zext.ll?rev=334318&view=auto
> ==============================================================================
> --- llvm/trunk/test/Analysis/ScalarEvolution/strip-injective-zext.ll (added)
> +++ llvm/trunk/test/Analysis/ScalarEvolution/strip-injective-zext.ll Fri Jun  8 13:43:07 2018
> @@ -0,0 +1,45 @@
> +; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
> +
> +; The initial SCEV for the backedge count is
> +;   (zext i2 {(trunc i32 (1 + %a1) to i2),+,1}<%b2> to i32).
> +; In howFarToZero, this was further converted to an add-rec, the complexity
> +; of which defeated the calculation of the backedge taken count.
> +; Since such zero-extensions preserve the values being extended, strip
> +; them in howFarToZero to simplify the input SCEV.
> +
> +; Check that the backedge taken count was actually computed:
> +; CHECK: Determining loop execution counts for: @f0
> +; CHECK-NEXT: Loop %b2: backedge-taken count is (-1 * (trunc i32 (1 + %a1) to i2))
> +
> +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
> +
> +define i32 @f0(i32 %a0, i32 %a1, i32* nocapture %a2) #0 {
> +b0:
> +  %v0 = and i32 %a1, 3
> +  %v1 = icmp eq i32 %v0, 0
> +  br i1 %v1, label %b4, label %b1
> +
> +b1:                                               ; preds = %b0
> +  %v2 = shl i32 %a0, 7
> +  %v3 = add i32 %v2, -128
> +  br label %b2
> +
> +b2:                                               ; preds = %b2, %b1
> +  %v4 = phi i32 [ %a1, %b1 ], [ %v9, %b2 ]
> +  %v5 = phi i32* [ %a2, %b1 ], [ %v8, %b2 ]
> +  %v6 = getelementptr inbounds i32, i32* %v5, i32 0
> +  store i32 %v3, i32* %v6, align 4
> +  %v8 = getelementptr inbounds i32, i32* %v5, i32 1
> +  %v9 = add nsw i32 %v4, 1
> +  %v10 = and i32 %v9, 3
> +  %v11 = icmp eq i32 %v10, 0
> +  br i1 %v11, label %b3, label %b2
> +
> +b3:                                               ; preds = %b2
> +  br label %b4
> +
> +b4:                                               ; preds = %b3, %b0
> +  ret i32 0
> +}
> +
> +attributes #0 = { norecurse nounwind }
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> 
-------------- next part --------------
target triple = "x86_64-unknown-linux-gnu"

define void @f1() {
entry:
  br label %lbl1

lbl1:                                             ; preds = %lbl1, %entry
  %a.0 = phi i16 [ 2, %entry ], [ %inc, %lbl1 ]
  %b.0 = phi i16 [ 1, %entry ], [ %add, %lbl1 ]
  %inc = add nsw i16 %a.0, 1
  %add = add nsw i16 %b.0, %a.0
  %and = and i16 %add, 1
  %tobool = icmp ne i16 %and, 0
  br i1 %tobool, label %lbl1, label %if.end

if.end:                                           ; preds = %lbl1
  ret void
}


More information about the llvm-commits mailing list