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

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 15 14:56:50 PDT 2018


Hi Mikael,
This is a pre-existing problem in SCEV. I'm working on a fix.

-Krzysztof


On 6/15/2018 3:05 AM, Mikael Holmén wrote:
> 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
>>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation


More information about the llvm-commits mailing list