This is an archive of the discontinued LLVM Phabricator instance.

[SCEVExpander] Try harder to avoid introducing inttoptr
ClosedPublic

Authored by loladiro on May 12 2017, 6:56 AM.

Details

Summary

This fixes introduction of an incorrect inttoptr/ptrtoint pair in
the included test case which makes use of non-integral pointers. I
suspect there are more cases like this left, but this takes care of
the one I was seeing at the moment.

Diff Detail

Repository
rL LLVM

Event Timeline

loladiro created this revision.May 12 2017, 6:56 AM
sanjoy added inline comments.May 16 2017, 1:33 PM
lib/Analysis/ScalarEvolutionExpander.cpp
494 ↗(On Diff #98758)

Just to be clear, this is intentionally kicking in for all pointers? If so, a test case showing that will be great.

498 ↗(On Diff #98758)

auto *.

1322 ↗(On Diff #98758)

s/is the/if the/

1396 ↗(On Diff #98758)

This is annoying, but won't a non-null PostLoopScale with an ni pointer type fail here?

loladiro added inline comments.May 16 2017, 1:42 PM
lib/Analysis/ScalarEvolutionExpander.cpp
494 ↗(On Diff #98758)

Yes, I think it's just generally better to attempt to do this rather than create the inttoptr/ptrtoint pairs. I'll add a test case.

1396 ↗(On Diff #98758)

I think in the cases I saw, Result was of integer type at this point, so that would have been fine. It may be possible to get a pointer typed one, but it seems a bit weird to be multiplying something that would be pointer valued at this point (i.e. I can see multiplying an offset, but once you apply a base pointer, seem like you wouldn't be multiplying any more)?

loladiro added inline comments.May 16 2017, 2:55 PM
lib/Analysis/ScalarEvolutionExpander.cpp
494 ↗(On Diff #98758)

Hmm, looks like all other callers make sure this doesn't happen in the caller, so it looks like the non-integral case is the only way to currently reach here. Doesn't mean of course that the other callers will handle the non-integral case properly. If you prefer, I can lift this check into the ptr and swap the operands there (it's a bit awkward, because one's a Value* and one's a SEC* and it may be the wrong way around), but either way is fine with me. Let me know which you think is cleaner.

sanjoy added inline comments.May 16 2017, 4:24 PM
lib/Analysis/ScalarEvolutionExpander.cpp
494 ↗(On Diff #98758)

Hmm, looks like all other callers make sure this doesn't happen in the caller

Can you be more specific? "Other callers" exclusive to which one?

If ni pointers are the only case we see here, I'd suggest changing the AddExpr->getType()->isPointerTy() check to check that AddExpr->getType() is a ni pointer.

1396 ↗(On Diff #98758)

SGTM

loladiro added inline comments.May 16 2017, 4:32 PM
lib/Analysis/ScalarEvolutionExpander.cpp
494 ↗(On Diff #98758)

The one that adds PostLoopOffset in expandAddRecExprLiterally. The change I introduced there forces the offset expansion type to be an integer when before it would have probably been pointer valued.

loladiro updated this revision to Diff 99267.May 17 2017, 4:16 AM

Changed the patch to do the argument re-arranging in the caller instead. I think
that's more localized to just this non-integral pointer change.

sanjoy requested changes to this revision.May 20 2017, 6:22 PM

Thank you for doing this!

lib/Analysis/ScalarEvolutionExpander.cpp
1307 ↗(On Diff #99267)

Did you consider just making this Type *ExpandTy = PostLoopScale ? IntTy : Normalized->getType();?

1392 ↗(On Diff #99267)

This is to prevent an ptrtoint on the expansion of PostLoopOffset, right? If so, I think phrasing this in terms of the type of PostLoopOffset may be more obvious.

test/Transforms/LoopStrengthReduce/nonintegral.ll
19 ↗(On Diff #99267)

Run -metarenamer on -instnamer on this?

Also, a C++ unit test that directly uses SCEVExpander will be more robust. This test case can become a no-op if LSR heuristics change.

This revision now requires changes to proceed.May 20 2017, 6:22 PM
loladiro added inline comments.May 20 2017, 9:31 PM
lib/Analysis/ScalarEvolutionExpander.cpp
1307 ↗(On Diff #99267)

Yes, I think I tried that first. You do still want to make it match the type of S eventually at the very end.

1392 ↗(On Diff #99267)

Well, either way. Without this, it'll try to gep (inttoptr Result to i8*), i64 (ptrtoint PostLoopOffset)

loladiro updated this revision to Diff 99804.May 22 2017, 1:39 PM
loladiro edited edge metadata.

Add a C++ test to make sure the SCEV code path is tested

sanjoy accepted this revision.May 25 2017, 11:03 PM

lgtm

This revision is now accepted and ready to land.May 25 2017, 11:03 PM
This revision was automatically updated to reflect the committed changes.
GorNishanov added inline comments.
llvm/trunk/unittests/Analysis/ScalarEvolutionTest.cpp
917

Looks like a typo:

lvm/unittests/Analysis/ScalarEvolutionTest.cpp:917:43: error: braces around scalar initializer [-Werror,-Wbraced-scalar-init]

Value *GepBase = Builder.CreateGEP(Arg, {ConstantInt::get(T_int64, 1)});

Fixed:

commit bdea69f0470dbc8282263f26d2b3fafbc812a010
Author: gornishanov <gornishanov@91177308-0d34-0410-b5e6-96231b3b80d8>
Date: Sat May 27 05:24:30 2017 +0000

ScalarEvolution unit test: fix typo that breaks check-all

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304063 91177308-0d34-0410-b5e6-96231b3b80d8

Thanks! I'm a little confused why the compiler is complaining there - I see this pattern used all over the place for 1-element array construction, but your fix is of course fine.