This is an archive of the discontinued LLVM Phabricator instance.

[LSR] Handle case 1*reg => reg. PR50918
ClosedPublic

Authored by mkazantsev on Jun 28 2021, 2:53 AM.

Details

Summary

This patch addresses assertion failure in case when the only found formula for LSR
is 1*reg => reg which was supposed to be an impossible situation, however there
is a test that shows it is possible.

In this case, we can use scale register with scale of 1 as the missing base register.

Diff Detail

Event Timeline

mkazantsev created this revision.Jun 28 2021, 2:53 AM
mkazantsev requested review of this revision.Jun 28 2021, 2:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 28 2021, 2:53 AM
reames added inline comments.Jun 28 2021, 5:20 PM
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
514

Given the comment indicates an unimplemented case here, why not just implement it?

Adding the following code just above the assert appears to address your test case.

+
+ if (BaseRegs.empty() && ScaledReg && Scale == 1) {
+ BaseRegs.push_back(ScaledReg);
+ Scale = 0;
+ ScaledReg = nullptr;
+ return;
+ }

Any reason why this is a poor approach?

Another note on LSRInstance::GenerateReassociationsImpl() where 1*reg is created, eventually trigger this assertion.

Looks like LSR is rewriting Formula

reg((-64 + (32 * ((112 * (((trunc i32 undef to i8) * ((trunc i32 %tmp3 to i8) + {94,+,-3}<%bb1>)) + {-94,+,3}<%bb1>)) + (-56 * (trunc i32 %tmp3 to i8)) + {-110,+,88}<%bb1>)))) + 1*reg({0,+,-128}<%bb21>)

into

reg({0,+,-128}<%bb21>) + imm(256)

I am not sure this rewrite is correct ?

llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
488–489

We will still need to keep this logic unchanged.

BaseRegs could be erased in LSRInstance::GenerateReassociationsImpl(), it's possible to have a non-canonical formula 1*reg, which need to be canonicalized later on.

if (InnerSumSC && SE.getTypeSizeInBits(InnerSumSC->getType()) <= 64 &&
    TTI.isLegalAddImmediate((uint64_t)F.UnfoldedOffset +
                            InnerSumSC->getValue()->getZExtValue())) {
  F.UnfoldedOffset =
      (uint64_t)F.UnfoldedOffset + InnerSumSC->getValue()->getZExtValue();
  if (IsScaledReg)
    F.ScaledReg = nullptr;
  else
    // This may create a non-canonical formula 1*reg
    F.BaseRegs.erase(F.BaseRegs.begin() + Idx);  
} else if (IsScaledReg)
  F.ScaledReg = InnerSum;
else
  F.BaseRegs[Idx] = InnerSum;

Another note on LSRInstance::GenerateReassociationsImpl() where 1*reg is created, eventually trigger this assertion.

Looks like LSR is rewriting Formula

reg((-64 + (32 * ((112 * (((trunc i32 undef to i8) * ((trunc i32 %tmp3 to i8) + {94,+,-3}<%bb1>)) + {-94,+,3}<%bb1>)) + (-56 * (trunc i32 %tmp3 to i8)) + {-110,+,88}<%bb1>)))) + 1*reg({0,+,-128}<%bb21>)

into

reg({0,+,-128}<%bb21>) + imm(256)

I am not sure this rewrite is correct ?

Yes it is, because 1st register contains undef and therefore whole thing is undef.

mkazantsev added inline comments.Jun 29 2021, 9:04 PM
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
514

It seems that null scaled reg is not allowed, because this code always sets it to non-null.

if (!ScaledReg) {
  ScaledReg = BaseRegs.pop_back_val();
  Scale = 1;
}

I don't know if there are other places that rely on this.

reames added inline comments.Jul 6 2021, 11:49 AM
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
514

This comment is incorrect. ScaledReg can be null, see isCanonical and the return just above this line.

The actual invariant appears to be that if ScaledReg is null, BaseRegs must have 0 or 1 element. Which makes sense, because we're then describing either a constant, or register indexing mode.

mkazantsev planned changes to this revision.Jul 7 2021, 5:02 AM
mkazantsev updated this revision to Diff 356922.Jul 7 2021, 5:18 AM
mkazantsev edited the summary of this revision. (Show Details)

Thanks Philip!

huihuiz accepted this revision.Jul 13 2021, 9:05 PM

I think this fix looks right, but wait a bit for @reames , in case he caught anything unusual ?

This revision is now accepted and ready to land.Jul 13 2021, 9:05 PM
reames accepted this revision.Jul 14 2021, 2:45 PM

LGTM as well.

This revision was automatically updated to reflect the committed changes.