This is an archive of the discontinued LLVM Phabricator instance.

[SROA] Assert the AllocSize of i8 to be 1
AbandonedPublic

Authored by jsilvanus on Nov 25 2022, 5:56 AM.

Details

Summary

When SROA rewrites GEPs, it tries to generate "natural"
GEPs that apply to the underlying type of the alloca.
If that fails, SROA falls back to using an i8-based GEP
with the byte-offset as index.

This however requires the AllocSize of i8 to be 1, which
is not the case with nontrivial alignment requirements,
which may e.g. occur with DXIL.
Add assertions checking this assumption.

Diff Detail

Event Timeline

jsilvanus created this revision.Nov 25 2022, 5:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 25 2022, 5:56 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
jsilvanus requested review of this revision.Nov 25 2022, 5:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 25 2022, 5:56 AM

Are you interested in a lit test checking that the assertion fires? Are we testing individual asserts this way?

lebedev.ri requested changes to this revision.Nov 25 2022, 6:39 AM

Are you interested in a lit test checking that the assertion fires? Are we testing individual asserts this way?

I'm mainly unconvinced as to why this change is correct..

This revision now requires changes to proceed.Nov 25 2022, 6:39 AM
jsilvanus added a comment.EditedNov 25 2022, 6:55 AM

In these places, we try to obtain a pointer based on a base pointer and a byte offset, and do so using a GEP on i8, using the offset as index.
This will fail if the AllocSize of i8 is not 1. The added assertions detect such cases instead of generating wrong code.

I can't comment on whether the existing behavior is correct, that is, whether overaligned i8 should be supported.

I would still like to see a test for this change, and an end-to-end micompile, to better understand where things go wrong.

jsilvanus updated this revision to Diff 477972.EditedNov 25 2022, 8:22 AM

Add test case that triggers the assert.

If we want to keep it, we'd need change it in some way to pass again, e.g. mark as XFAIL, or check for the assert. I'm not sure on what's the recommended way to do such things, but for now it should suffice to demonstrate the issue.

jsilvanus updated this revision to Diff 477974.Nov 25 2022, 8:27 AM

Fix constant in test case.

Ok, that is weird. I'm guessing the test case should return 2? https://alive2.llvm.org/ce/z/BMccF9
I think this is hinting that a pretty fundamental assumption about i8's in LLVM does not hold,
and there are likely many more problems like this.

Does it work if you assert that the offset is a multiple of getTypeAllocSize and divide it by that?

jsilvanus updated this revision to Diff 477986.EditedNov 25 2022, 8:56 AM

Yes, you are right, I miscalculated by one bit :) Updated the test accordingly.

I was expecting this assumption to be rather wide-spread, and I am not even sure
SROA is supposed to correctly handle such cases. This why I just added an assertion
that at least uncovers the issue, rather than reporting a bug in SROA.

The offset in the example is not a multiple of the AllocSize of i8:
The offset is 5 (coming from the corresponding GEP in the test case),
but the alloc size of i8 is 4.

I would say that backend/front-end is essentially non-conforming
as far as LLVM is concerned - there is a very hard sentiment that
LLVM should only support the cases where byte is 8 bits,
which is essentially not the case here. If this doesn't hold,
e.g. the "simple GEPs" proposal, which does this same expansion,
goes out of the window.

I would suggest posting to discuss.

TBN, this wouldn't be a problem if we had a true byte type, @nlopes.

I don't need support for overaligned i8s, it is fine for me to have LLVM require natural alignment on i8.

But having explicit asserts maybe helps save some people's time in the future -- it certainly would have for me.
Also, it explicitly documents the assumption underlying these GEPs.

I'm not the sure the test brings additional value beyond motivating this change.
There are probably many other places that can be broken by using such a data layout, and as long as
there is no effort to make overaligned i8s work I see little value in documenting these.

Thus, I'd propose to not commit the test and just add the assertions.
But if you feel this issue should be discussed further, I'm fine to open a thread on that.

For what it's worth, I ran into a similar, separate issue with incorrect GEP offsets during SROA with vectors of overaligned elements that I *do* intend to fix, because that should work.

I don't need support for overaligned i8s, it is fine for me to have LLVM require natural alignment on i8.

But having explicit asserts maybe helps save some people's time in the future -- it certainly would have for me.
Also, it explicitly documents the assumption underlying these GEPs.

I'm not the sure the test brings additional value beyond motivating this change.
There are probably many other places that can be broken by using such a data layout, and as long as
there is no effort to make overaligned i8s work I see little value in documenting these.

Thus, I'd propose to not commit the test and just add the assertions.
But if you feel this issue should be discussed further, I'm fine to open a thread on that.

For what it's worth, I ran into a similar, separate issue with incorrect GEP offsets during SROA with vectors of overaligned elements that I *do* intend to fix, because that should work.

Thank you for looking into this.
I do agree that this looks like a problem that needs to be improved.
There is a caveat here: while we should assert liberally, reachable assertions should be fixed in some way.

Indeed, the problem appears to happen the moment we create a datalayout with overaligned byte type.
So let's just detect that there, diagnose it as invalid, and refuse to create it?

I've started a discourse discussion on the topic: https://discourse.llvm.org/t/status-of-overaligned-i8/66913

Thanks!

This is the patch for the mentioned issue of GEPs into vectors of overaligned elements: https://reviews.llvm.org/D139034

lebedev.ri resigned from this revision.Jan 12 2023, 5:15 PM

This review seems to be stuck/dead, consider abandoning if no longer relevant.

jsilvanus abandoned this revision.Jan 13 2023, 12:11 AM

Abandoning, we will require i8 to be naturally aligned in the datalayout as discussed on discourse. Sorry for leaving it open for so long.