This is an archive of the discontinued LLVM Phabricator instance.

[IR] Avoid creation of GEPs into vectors (in one place)
ClosedPublic

Authored by jsilvanus on Jan 19 2023, 11:04 AM.

Details

Summary

The method DataLayout::getGEPIndexForOffset(Type *&ElemTy, APInt &Offset)
allows to generate GEP indices for a given byte-based offset.
This allows to generate "natural" GEPs using the given type structure
if the byte offset happens to match a nested element object.

With opaque pointers and a general move towards byte-based GEPs [1],
this function may be questionable in the future.

This patch avoids creation of GEPs into vectors in routines that use
DataLayout::getGEPIndexForOffset by not returning indices in that case.

The reason is that A) GEPs into vectors have been discouraged for a long
time [2], and B) that GEPs into vectors are currently broken if the element
type is overaligned [1]. This is also demonstrated by a lit test where
previously InstCombine replaced valid loads by poison. Note that
the result of InstCombine on that test is *still* invalid, because
padding bytes are assumed.
Moreover, GEPs into vectors may be outright forbidden in the future [1].

[1]: https://discourse.llvm.org/t/67497
[2]: https://llvm.org/docs/GetElementPtr.html

The test case is new. It will be precommitted if this patch is accepted.

Diff Detail

Event Timeline

jsilvanus created this revision.Jan 19 2023, 11:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 19 2023, 11:04 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
jsilvanus requested review of this revision.Jan 19 2023, 11:04 AM
Herald added a project: Restricted Project. · View Herald Transcript
nikic added a subscriber: nikic.
nikic added inline comments.
llvm/test/Transforms/InstCombine/load-gep-overalign.ll
1–2

Pass datalayout to opt instead. You should be able to use default DL in one case, and minimal DL (omitting irrelevant other type specifications) in the other.

Review feedback: Simplify testcase by passing DL to opt

Thanks for the suggestion, that is much cleaner indeed. I updated the patch accordingly.

nikic accepted this revision.Jan 20 2023, 2:43 AM

This change has two effects: First. we will no longer generate GEPs indexing into vectors during transforms. With opaque pointers, the main remaining transform of this kind is the one that canonicalized constant expression GEPs, and which is also the one leading to the miscompile here.

Second, this API is also used to index into constant aggregates based on offsets. For example, I expect that this change will regress operations like "load ptr at offset 4 of <2 x ptr> <ptr @g, ptr @g>, because we will now fail to index into the vector constant. Integer/float load folding should still work via the reinterpret load fold (which is, incidentally, the second one involved in the miscompile here, introducing those "padding" bytes). It can probably also negatively affect the global ctor evaluator.

I think overall, those optimization regressions are unlikely to matter (vector of pointer global initializers sound pretty exotic) and this does mitigate an active miscompile, so I'm okay with doing the change. We might want to undo it later, if we change our canonical form for constant GEPs.

So LGTM.

This revision is now accepted and ready to land.Jan 20 2023, 2:43 AM

Thanks for the review.
Your example of accessing a known pointer in a vector is interesting.

For the sake of completeness, it would be possible to restrict this patch to vectors of overaligned elements, which would still fix the first issue in the test case, but avoid possible regressions you mentioned.
But based on the discourse discussion I did not do that because it would introduce a pooly tested special case.

Moreover, none of the existing test cases is affected by the change, which I also took as an indication that performance regressions would be unlikely.

jsilvanus updated this revision to Diff 491272.Jan 23 2023, 2:48 AM
Update changed testcases.
This revision was landed with ongoing or failed builds.Jan 23 2023, 4:26 AM
This revision was automatically updated to reflect the committed changes.