This is an archive of the discontinued LLVM Phabricator instance.

[AttributeFuncs] Consider `align` in `typeIncompatible`
ClosedPublic

Authored by jdoerfert on Sep 8 2020, 11:18 AM.

Details

Summary

Alignment attributes need to be dropped for non-pointer values.
This also introduces a check into the verifier to ensure you don't use
align on anything but a pointer. Test needed to be adjusted
accordingly.

Diff Detail

Event Timeline

jdoerfert created this revision.Sep 8 2020, 11:18 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 8 2020, 11:18 AM
jdoerfert requested review of this revision.Sep 8 2020, 11:18 AM
jdoerfert updated this revision to Diff 290562.EditedSep 8 2020, 12:20 PM

@serge-sans-paille did update the .bc file, many thanks!

fhahn added inline comments.Sep 9 2020, 8:49 AM
llvm/test/Bitcode/attributes-3.3.ll
105

just to clarify, attributes-3.3.ll.bc needs to be updated, because it contains bitcode that defines a function with align on a non-pointer argument?

jdoerfert added inline comments.Sep 9 2020, 1:23 PM
llvm/test/Bitcode/attributes-3.3.ll
105

it was updated because of that, yes.

fhahn accepted this revision.Sep 10 2020, 6:18 AM

LGTM, thanks!

This revision is now accepted and ready to land.Sep 10 2020, 6:18 AM
This revision was automatically updated to reflect the committed changes.

I wonder if align attribute is legal for vectors of pointers?
This is allowed:

define align 8 i32* @test_scalar(i32* %in) {
  ret i32* %in
}

but this is not:

define align 8 <4 x i32*> @test_vector(<4 x i32*> %in) {
  ret <4 x i32*> %in
}

Is it intentional behavior or just has been overlooked?

I wonder if align attribute is legal for vectors of pointers?
This is allowed:

define align 8 i32* @test_scalar(i32* %in) {
  ret i32* %in
}

but this is not:

define align 8 <4 x i32*> @test_vector(<4 x i32*> %in) {
  ret <4 x i32*> %in
}

Is it intentional behavior or just has been overlooked?

The way I read the lang ref this is intentional. Not to say one should not define what it means for vectors of pointers and then allow it. I feel align is not the only one missing for them though.
You want to give it a try?

The way I read the lang ref this is intentional. Not to say one should not define what it means for vectors of pointers and then allow it. I feel align is not the only one missing for them though.
You want to give it a try?

Not yet. We have a downstream code which generates this (align on vector of pointers) . I'm trying to figure out where I need to fix it :)
If we really need this, I'll give it a try.

anna added a subscriber: anna.Oct 14 2020, 5:29 AM

I wonder if align attribute is legal for vectors of pointers?
This is allowed:

define align 8 i32* @test_scalar(i32* %in) {
  ret i32* %in
}

but this is not:

define align 8 <4 x i32*> @test_vector(<4 x i32*> %in) {
  ret <4 x i32*> %in
}

Is it intentional behavior or just has been overlooked?

The way I read the lang ref this is intentional. Not to say one should not define what it means for vectors of pointers and then allow it. I feel align is not the only one missing for them though.
You want to give it a try?

@jdoerfert I'm wondering why we need to specially treat vector of pointers? We can add a LangRef statement for this, but vector is just another type. The way I read it, whatever is done for the scalar type, we do so for the vector type by considering each element.
So, in this case, the align 8 <4 x i32*> implies that each pointer in the vector is aligned by 8 bytes.

@jdoerfert I'm wondering why we need to specially treat vector of pointers? We can add a LangRef statement for this, but vector is just another type. The way I read it, whatever is done for the scalar type, we do so for the vector type by considering each element. So, in this case, the align 8 <4 x i32*> implies that each pointer in the vector is aligned by 8 bytes.

I don't read it that way because it is not clear this is the case/what we want for all attributes. We cannot silently pick and choose when attributes are applied element wise and when not. Take

`align 8 inalloca noundef <4 x i32*>`

for which I do not know what applies element wise and what applies to the vector value. TBH, maybe we need both ...

A reasonable first step would be to have a statement staying some attributes apply element-wise, let's say all that apply only to pointer types.
Afterwards, typeIncompatible can be adjusted easily. It's important that it's not only align though.

dexonsmith added inline comments.
llvm/test/Bitcode/attributes-3.3.ll
105

Hmm, I'm just seeing this now -- but attributes-3.3.ll.bc should not have been changed. Can that part of the change be reverted? Instead, the bitcode reader should have been adjusted to auto-upgrade the bitcode and strip the align attribute where appropriate.

Note that eventually the problem hit in production and @steven_wu added the bitcode upgrade in https://reviews.llvm.org/D102201. The whole reason we have these bitcode tests is to catch upgrade issues before commit.

jdoerfert added inline comments.May 15 2021, 9:39 AM
llvm/test/Bitcode/attributes-3.3.ll
105

With D102201 landed we can revert attributes-3.3.ll.bc. It makes sense to do it that way.

dexonsmith added inline comments.May 17 2021, 11:46 AM
llvm/test/Bitcode/attributes-3.3.ll
105

Huh; it looks like D102201 is insufficient, since it only fixes return types. attributes-3.3.ll.bc from 0a8e12fdbbf54e81954b091ac9fb11cd5f5148e1 has an attribute on parameter.

Would you please add the upgrade for parameters? I'm happy to review.

The reason I only fix return type in D102201 is that I identify the source of such incompatibility, which is coming from an optimization pass, so that can be wild spread incompatibility. The optimization pass explicitly happens when it is return type and check to remove all attributes that is incompatibly returned from typeIncompatible.

Fixing attribute on parameter will be nice but on the other hand, I am not sure if there is bitcode is the wild that consist of such incompatibility.

The reason I only fix return type in D102201 is that I identify the source of such incompatibility, which is coming from an optimization pass, so that can be wild spread incompatibility. The optimization pass explicitly happens when it is return type and check to remove all attributes that is incompatibly returned from typeIncompatible.

Fixing attribute on parameter will be nice but on the other hand, I am not sure if there is bitcode is the wild that consist of such incompatibility.

I can imagine some IPOs to produce such arguments. I'll try to get to it. @steven_wu, if you want to just also do the argument case that would be appreciated.