[LLVMdev] ScalarEvolution::createNodeForPHI
Hal Finkel
hfinkel at anl.gov
Wed Oct 2 16:30:49 PDT 2013
----- Original Message -----
>
> On Oct 1, 2013, at 6:45 AM, Michele Scandale
> <michele.scandale at gmail.com> wrote:
>
> > Hello to everybody,
> >
> > I'm working on some improvements on trip count computation with
> > ScalarEvolution
> > analysis.
> > Considering the following test
> >
> > ;----------------------------------------------------------------------------;
> > define void @foo(i32 %a, i32 %b, i32 %s) #0 {
> > entry:
> > %cmp = icmp sgt i32 %s, 0
> > %cmp15 = icmp sgt i32 %a, %b
> > %or.cond = and i1 %cmp, %cmp15
> > br i1 %or.cond, label %for.body, label %if.end
> >
> > for.body:
> > %i.06 = phi i32 [ %sub, %for.body ], [ %a, %entry ]
> > tail call void @f(i32 %i.06) #2
> > %sub = sub nsw i32 %i.06, %s
> > %cmp1 = icmp sgt i32 %sub, %b
> > br i1 %cmp1, label %for.body, label %if.end
> >
> > if.end:
> > ret void
> > }
> > ;----------------------------------------------------------------------------;
> >
> > I've noticed that the SCEV for %i.06 and %sub are the following:
> >
> > %i.06 = phi i32 [ %sub, %for.body ], [ %a, %entry ]
> > --> {%a,+,(-1 * %s)}<%for.body>
> >
> > %sub = sub nsw i32 %i.06, %s
> > --> {((-1 * %s) + %a),+,(-1 * %s)}<%for.body>
> >
> > but the NSW flag that is present in the SUB instruction is not
> > propagated in the
> > AddRec.
> >
> > Looking in the source code I analyzed the construction of the SCEV
> > for a PHINode
> > and during the analysis of the loop-invariant part of the increment
> > the flags
> > NSW/NUW are set according to the Operator BEValueV
> > (ScalarEvoluton.cpp:3099-3113), but only Add and GEP operators are
> > checked.
> >
> > //-------------------------------------------------------------------------//
> > if (const AddOperator *OBO = dyn_cast<AddOperator>(BEValueV)) {
> > if (OBO->hasNoUnsignedWrap())
> > Flags = setFlags(Flags, SCEV::FlagNUW);
> > if (OBO->hasNoSignedWrap())
> > Flags = setFlags(Flags, SCEV::FlagNSW);
> > } else if (const GEPOperator *GEP =
> > dyn_cast<GEPOperator>(BEValueV)) {
> > // If the increment is an inbounds GEP, then we know the address
> > // space cannot be wrapped around. We cannot make any guarantee
> > // about signed or unsigned overflow because pointers are
> > // unsigned but we may have a negative index from the base
> > // pointer.
> > if (GEP->isInBounds())
> > Flags = setFlags(Flags, SCEV::FlagNW);
> > }
> > //-------------------------------------------------------------------------//
> >
> > Is there any reason to not check also Sub operator in a similar way
> > to the Add
> > operator?
> >
> > //-------------------------------------------------------------------------//
> > if (const SubOperator *OBO = dyn_cast<SubOperator>(BEValueV)) {
> > if (OBO->hasNoUnsignedWrap())
> > Flags = setFlags(Flags, SCEV::FlagNUW);
> > if (OBO->hasNoSignedWrap())
> > Flags = setFlags(Flags, SCEV::FlagNSW);
> > }
> > //-------------------------------------------------------------------------//
>
>
> I’m not sure how to make sense of an NUW flag coming from a sub.
I thought that sub nuw a, b just meant that we were allowed to assume that a >= b. No?
-Hal
>
> NSW is just a misnomer for signed overflow. SCEV canonicalizes sub
> a,b to add a, (-b). Unfortunately, signed overflow is not the same
> thing for sub and add...
>
> sub nsw %a, %b != add nsw %a, (-1 * %b)
>
> sub nsw i32, -1, INT_MIN is true.
>
> add nsw i32, -1, (-1 * INT_MIN) is false.
>
> NSW flags just aren’t an effective way to tell SCEV about overflow.
> Ideally we could reason more generally about the loop’s undefined
> behavior. For example, I’d like to query the range of values that a
> variable can hold before the loop hits undefined behavior. I don’t
> know how to implement something like this yet. Ideas are welcome.
>
> Reading this code again, even the addition case looks too aggressive
> to me.
> See:
> llvm.org/PR17452 - SCEV createNodeForPHI is too optimistic about NSW.
>
> -Andy
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the llvm-dev
mailing list