[llvm] r334318 - [SCEV] Look through zero-extends in howFarToZero
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 20 06:23:18 PDT 2018
Proposed fix: https://reviews.llvm.org/D48283
-Krzysztof
On 6/15/2018 4:56 PM, Krzysztof Parzyszek via llvm-commits wrote:
> 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