[llvm-dev] LoopVectorize fails to vectorize loops with induction variables with PtrToInt/IntToPtr conversions

Adrien Guinet via llvm-dev llvm-dev at lists.llvm.org
Tue Jun 20 11:41:49 PDT 2017


On 06/20/2017 03:26 AM, Hal Finkel wrote:
> Hi, Adrien,

Hello Hal!

Thanks for your answer!

> Thanks for reporting this. I recommend that you file a bug report at
> https://bugs.llvm.org/

Will do!

> Whenever I see reports of missed optimization opportunities in the face
> of ptrtoint/inttoptr, my first question is: why are these instructions
> present in the first place? At the IR level, use of inttoptr is highly
> discouraged. Our aliasing analysis, for example, does not look through
> them, and so you'll generally see a lot of missed optimizations when
> they're around.
> In this case, inttoptr seems to be introduced by SROA. SROA should not
> be introducing inttoptr, but rather should be using GEPs on i8* (at
> least), to avoid introducing pointers that our AA can't analyze.

It looks so indeed!

> Beyond that, if we need to handle inttoptr/ptrtoint in SCEV, then maybe
> there's a way to make it smarter about the expressions with which it can
> deal.

One of the solution I was thinking of was making SCEV "understand"
inttoptr(ptrtoint()), as this is clearly a no-op (and what is happening
here), but it seems not that straightforward to do (hence this
discussion to discuss what should be done :)).

> I'm actually not sure to what "aliasing rules" the comment you
> quote below is referring. I can certainly understand not being able to
> place "inbounds" on some generated GEPs, but otherwise this seems
> non-obvious to me (i.e. either the expander can identify a base pointer
> from which to generate the GEP, or it can't, in which case it needs to
> generate a inttoptr).

The way I understand it is that, for a pointer to a fixed-size array P,
by using I=ptrtoint(P)/arithmetic operations(I)/inttoptr(I) we can
potentially end-up with a pointer which is not in the original values
that could be computed from the original array (like an out-of-bound
pointer), and thus not "reconstruct" a GEP from it. That's why SCEV
wouldn't consider them. IIRC, I tried to add ptrtoint/inttoptr as
"no-op" in SCEV, but then the cost-model seemed to be broken (a very
high value was given at some point), and thus vectorization still didn't
happen.

I was also thinking: even if SROA is fixed, nothing prevents another
pass from introducing such constructions in the future, so maybe the
solution is to have a pass (like the one I wrote) that try and cleanup
before any usage of SCEV? (or done by InstCombine for instance, as this
basically removes the inttoptr(ptrtoint()) combination).
Or having the "inttoptr(ptrtoint())" composition understood by SCEV as a
no-op might also be a cleaner "long-term" solution...

What do you think?


More information about the llvm-dev mailing list