[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