This is an archive of the discontinued LLVM Phabricator instance.

[ConstantHoist] Remove check for notional overindexing
ClosedPublic

Authored by nikic on Jan 13 2022, 1:44 AM.

Details

Summary

ConstantHoist currently only hoists GEPs if there is no notional overindexing. However, I don't see in what way overindexing is supposed to be relevant to this transform. I believe the only part it cares about is that the GEP has constant indices (which is already checked by accumulateConstantOffset).

In the attached test case this makes ConstantHoist apply to the GEP with trailing 10 index, which is nominally out of bounds. (The corresponding store may not even be UB, though even if it were there is no reason why this transform should care.)

Diff Detail

Event Timeline

nikic created this revision.Jan 13 2022, 1:44 AM
nikic requested review of this revision.Jan 13 2022, 1:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 13 2022, 1:44 AM

There are a few different properties isGEPWithNoNotionalOverIndexing checks for:

  1. We have a GEP constant expression.
  2. All the operands beyond the first are undef or ConstantInt.
  3. All the integer indexes are in bounds.

The replacement checks:

  1. We have a GEP constant expression.
  2. All the operands beyond the first are ConstantInt.

So basically, this is just removing the third condition.

accumulateConstantOffset already checks that all the operands are ConstantInt, so the second condition is redundant; should be fine to just check isa<GEPOperator>, I think.

If we stop checking for over-indexing, do we need to worry about "inbounds" markings? Before this patch, all the transformed GEPs were effectively inbounds, but with this patch they aren't.

nikic updated this revision to Diff 399934.Jan 14 2022, 2:02 AM
nikic edited the summary of this revision. (Show Details)

Drop all constant check, leave it to accumulateConstantOffset().

nikic added a comment.Jan 14 2022, 2:06 AM

There are a few different properties isGEPWithNoNotionalOverIndexing checks for:

  1. We have a GEP constant expression.
  2. All the operands beyond the first are undef or ConstantInt.
  3. All the integer indexes are in bounds.

The replacement checks:

  1. We have a GEP constant expression.
  2. All the operands beyond the first are ConstantInt.

So basically, this is just removing the third condition.

accumulateConstantOffset already checks that all the operands are ConstantInt, so the second condition is redundant; should be fine to just check isa<GEPOperator>, I think.

Right, done.

If we stop checking for over-indexing, do we need to worry about "inbounds" markings? Before this patch, all the transformed GEPs were effectively inbounds, but with this patch they aren't.

I don't think so. We're just hoisting address arithmetic here, it should not matter whether it is inbounds or not.

If we stop checking for over-indexing, do we need to worry about "inbounds" markings? Before this patch, all the transformed GEPs were effectively inbounds, but with this patch they aren't.

I don't think so. We're just hoisting address arithmetic here, it should not matter whether it is inbounds or not.

I'm not saying the transformation inherently cares about "inbounds".

The case I'm worried about is the case where we choose an "inbounds" GEP as the base, but it's poison because it's out of bounds. We do the transform, then all the other transformed GEPs are poisoned. I think we could solve this by generating a new constant expression for the base that isn't marked "inbounds". Currently, we just reuse the existing constant expression.

nikic updated this revision to Diff 400554.Jan 17 2022, 7:45 AM

Okay, I see what you mean now. I've updated the implementation to perform an explicit inbounds check.

As the code requires a GlobalVariable base pointer, the notional overindexing check did effectively guarantee that it is inbounds, because there would be a bitcast sitting in between otherwise -- of course, this is not true anymore with opaque pointers, as the GEP type is entirely independent of the global type in that case.

This revision is now accepted and ready to land.Jan 18 2022, 12:56 PM
This revision was landed with ongoing or failed builds.Jan 19 2022, 2:34 AM
This revision was automatically updated to reflect the committed changes.