This is an archive of the discontinued LLVM Phabricator instance.

[LV] Check if ops can safely be truncated in computeMinimumValueSizes.
ClosedPublic

Authored by fhahn on Jul 7 2023, 6:38 AM.

Details

Summary

Update computeMinimumValueSizes to check if an instruction's operands
can safely be truncated.

If more than MinBW bits are demanded by for the operand or if the
operand is a constant and cannot be safely truncated, it is not safe to
evaluate the instruction in the narrower MinBW. Skip those cases.

Fixes https://github.com/llvm/llvm-project/issues/47927

Diff Detail

Event Timeline

fhahn created this revision.Jul 7 2023, 6:38 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 7 2023, 6:38 AM
fhahn requested review of this revision.Jul 7 2023, 6:38 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 7 2023, 6:38 AM
Herald added a subscriber: wangpc. · View Herald Transcript
nikic added a subscriber: nikic.Jul 7 2023, 7:23 AM
nikic added inline comments.
llvm/lib/Analysis/VectorUtils.cpp
586

We're effectively working around this.

Does make me wonder: If we make the Worklist work on Uses rather than Values, could we handle this directly in this loop?

662–663

dyn_cast up here, use below?

fhahn updated this revision to Diff 538183.Jul 7 2023, 10:08 AM

Updated to use dyn_cast.

fhahn marked 2 inline comments as done.Jul 7 2023, 10:19 AM
fhahn added inline comments.
llvm/lib/Analysis/VectorUtils.cpp
586

I'm not sure if it would be worth checking the uses here, but it might be an option to check the operands earlier here

662–663

updated, thanks!

nikic added inline comments.Jul 7 2023, 12:58 PM
llvm/lib/Analysis/VectorUtils.cpp
679

Hm, is this special case for constants correct? Consider a variant on the test case that does something like %l = shl i32 %f, 24. Then only the low 8 bits of %f would be demanded, and 24 can be truncated to 8 bits, but it still changes the result: Now the shift would return poison (while previously the shl + trunc would produce zero).

681
fhahn marked 3 inline comments as done.Jul 7 2023, 2:03 PM
fhahn added inline comments.
llvm/lib/Analysis/VectorUtils.cpp
679

Yep, it seems like there are multiple issues with this code. For the lshr case, DemandedBits seems sufficient to rule out narrowing (by making sure we don't drop bits contributing to the result).

In addition to that for the shl case (and others where smaller widths may cause new poison), we would also need to take into account the semantics of the specific instructions. Do we have any existing APIs that would be suitable to check?

nikic added inline comments.Jul 7 2023, 2:19 PM
llvm/lib/Analysis/VectorUtils.cpp
679

I think if we only use the demanded bits check below, that should always be correct. Would it be sufficient to only have the constant special case for shift amounts (with the appropriate bit width check)? That's probably the main case where we don't get meaningful demanded bits on one of the operands.

fhahn updated this revision to Diff 538789.Jul 10 2023, 1:14 PM
fhahn marked an inline comment as done.

Check constant shift amount range.

fhahn marked 2 inline comments as done.Jul 10 2023, 1:14 PM
fhahn added inline comments.
llvm/lib/Analysis/VectorUtils.cpp
679

Updated to check the constant shift amount. Was that what you had in mind?

nikic added inline comments.Jul 11 2023, 3:03 AM
llvm/lib/Analysis/VectorUtils.cpp
679

Not quite. This is the code I would expect:

if (any_of(MI->operands(), [&DB, MinBW](Use &U) {
      auto *CI = dyn_cast<ConstantInt>(U); 
      if (isa<ShlOperator, LShrOperator, AShrOperator>(U.getUser()) &&
          U.getOperandNo() == 1 && CI) 
        return CI->getValue().uge(MinBW);
         
      uint64_t BW = bit_width(DB.getDemandedBits(&U).getZExtValue());
      return bit_ceil(BW) > MinBW;
    }))
  continue;

That is, use demanded bits for everything apart from shift amounts, including all other constant operands. That way it's always conservatively correct.

fhahn updated this revision to Diff 539071.Jul 11 2023, 6:50 AM
fhahn marked an inline comment as done.

Update check as suggested, thanks!

fhahn marked an inline comment as done.Jul 11 2023, 6:51 AM
fhahn added inline comments.
llvm/lib/Analysis/VectorUtils.cpp
679

Sounds good to me! Updated, thanks.

fhahn updated this revision to Diff 539073.Jul 11 2023, 6:52 AM
fhahn marked an inline comment as done.

Adjust test

nikic accepted this revision.Jul 11 2023, 6:54 AM

LG

llvm/lib/Analysis/VectorUtils.cpp
676

shit -> shift :P

llvm/test/Transforms/LoopVectorize/trunc-shifts.ll
5–6

Drop FIXME

This revision is now accepted and ready to land.Jul 11 2023, 6:54 AM
This revision was landed with ongoing or failed builds.Jul 11 2023, 12:19 PM
This revision was automatically updated to reflect the committed changes.
fhahn marked an inline comment as done.
fhahn marked an inline comment as done.Jul 11 2023, 12:19 PM
fhahn added inline comments.
llvm/lib/Analysis/VectorUtils.cpp
676

A very unfortunate typo, should be fixed in the committed version :)

llvm/test/Transforms/LoopVectorize/trunc-shifts.ll
5–6

Thanks, removed in the committed version.