This is an archive of the discontinued LLVM Phabricator instance.

[IndVarSimplify] Add AShr exact flags using induction variables ranges.
ClosedPublic

Authored by dmgreen on Jun 14 2017, 8:45 AM.

Details

Summary

This is an attempt to fix a regression we saw in benchmarks of FFT like code after computeKnownBitsFromShiftOperator was made more strict with respect to possibly shifting past the bitwidth. It adds exact flags to AShr/LShr flags where we can statically prove it is valid using the range of induction variables. This allows further optimisations to remove extra loads.

Diff Detail

Repository
rL LLVM

Event Timeline

dmgreen created this revision.Jun 14 2017, 8:45 AM

Ping. Anyone fancy taking a look at this, or suggesting a better place for it?

The definition of shifts past the bitwidth has recently been changed (or clarified?) to poison, not undef. I'm unsure how poison plays together with computeKnownBits, and whether the original cause of the regressions (back in https://reviews.llvm.org/rL297724) is now correct or not. It can still produce end to end compilation errors if it's reverted, which I guess is proof enough that it's needed! There may well be other ways to fix this though.

sanjoy requested changes to this revision.Jun 20 2017, 10:03 AM
sanjoy added inline comments.
lib/Transforms/Utils/SimplifyIndVar.cpp
529 ↗(On Diff #102558)

Please clang-format the change.

532 ↗(On Diff #102558)

LLVM style is auto *User or auto *U (I prefer the latter since there is also a llvm::User).

535 ↗(On Diff #102558)

Use llvm::PatternMatch here. You can then fold in the dyn_cast<ConstantInt>(AShr->getOperand(1)) check into the same patternmatch expression.

If you do the dyn_cast<ConstantInt>(AShr->getOperand(1)) check, then the AShr->getOperand(0) != BO check should not be necessary.

542 ↗(On Diff #102558)

Do you really mean getUpper or do you want getUnsignedMax?

Secondly, BO will always be an integer (as opposed to a vector of integers); since the induction variable is an integer.

Thirdly, if I'm not missing something, the IVRange.getUpper().uge(BO->getType()->getPrimitiveSizeInBits()) check should be unnecessary. If the IV is larger than the bitwidth then BO is poison, and so is AShr (and making it exact does not make it any more poison).

545 ↗(On Diff #102558)

In cases like this, I think a more indented version is easier to read:

if (IVOperand == BO->getOperand(1) && IVMax.ult(BitWidth))
  if (auto *AShrCI = dyn_cast<ConstantInt>(AShr->getOperand(1))
    if (IVMin.uge(AShrOp2->getValue()) {
      AShr->setIsExact(true);
      Changed = true;
    }
546 ↗(On Diff #102558)

Perhaps you need IVRange.getUnsignedMin() instead of IVRange.getLower()?

test/Transforms/IndVarSimplify/strengthen-overflow.ll
116 ↗(On Diff #102558)

Add a few more tests here, check that

  • We don't do this transform when illegal (e.g. shl by 2, ashr by 3).
  • We do the transform when the shl amount is strictly greater than the ashr amount
  • If I'm right about shl ing more than the bitwidth amount above, then please add a test case that checks that situation.
123 ↗(On Diff #102558)

I think most of the load/store stuff here can be pruned.

This revision now requires changes to proceed.Jun 20 2017, 10:03 AM
dmgreen updated this revision to Diff 103376.Jun 21 2017, 7:27 AM
dmgreen edited edge metadata.

Hello, Thanks for the review. It sounds like you are happy with where this is, so I will upload a cleaned up version. Thanks for the pointers.

Unfortunately it looks like something else I need for this has broken over in r305481 :( I'll have to try and investigate that to see exactly why it's stopping the full case from optimising.

To this, I've added LShr's, as well as AShr's and the extra testing. Let me know if anything else needs changing, but no need to hurry as I need to look into that other thing now too.

lib/Transforms/Utils/SimplifyIndVar.cpp
542 ↗(On Diff #102558)

This is my understanding, yes. But I thought the same for shifts in computeKnownBits, so I thought it best to be careful. In the case for the original test it was known what the upper bound for the loop is. Removing the need for this will only make this fire for more loops, which should be good.

test/Transforms/IndVarSimplify/strengthen-overflow.ll
123 ↗(On Diff #102558)

Sounds good. This was a bit strategic, in case I had to explain where the benefits come in ;)

sanjoy accepted this revision.Jul 3 2017, 1:52 PM
sanjoy added inline comments.
lib/Transforms/Utils/SimplifyIndVar.cpp
33 ↗(On Diff #103376)

Don't open this namespace globally -- just open it in the function you're using it in.

539 ↗(On Diff #103376)

The name and documentation of this function is now out of sync. I'd instead just split out a separate strengthenRightShift, and put that logic in there.

This revision is now accepted and ready to land.Jul 3 2017, 1:52 PM
dmgreen updated this revision to Diff 105152.Jul 4 2017, 4:23 AM
dmgreen edited the summary of this revision. (Show Details)
This revision was automatically updated to reflect the committed changes.