[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