In the current mangling scheme for overloaded intrinsics we include overloaded
type names in the intrinsic name. For example:
%struct.foobar = type { i32 }
declare <4 x %struct.foobar*> @llvm.masked.load.v4p0struct.foobar(<4 x
%struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>)
Verifier checks that an overloaded intrinsic name matches with its signature.
When different modules are loaded in LTO configuration with the same
LLVMContext, types with the same name from different modules are renamed so
their names are unique (%struct.foobar in the second module becomes
%struct.foobar.0). After renaming intrinsic names and signatures can become
inconsistent.
Usually it slips unnoticed because we don't verify individual modules and
eventually map isomorphic types to a single type. So isomorphic types get their
original names. Although in some cases it causes problems.
Initially I came across the problem with my recent change which added an
overloaded type to the masked load/store intrinsics
(http://reviews.llvm.org/D17270). The discrepancy between the name and the
signature triggers auto-upgrade bit from my patch converting an incorrect
mangling to the correct one. But later after remapping of isomorphic types when
we return to the original type name this “updated" intrinsic name become
invalid.
Another way to trigger the problem is to have different types with the same name
in different modules. Corresponding test case is attached. In this case types in
different modules will be renamed but the intrinsics from different modules will
have the same name which will be caught by verifier.
As a possible solution we can use AutoUpgrade to handle the situation when the
name of the intrinsic doesn't match with its signature. In such cases we
have to rename the intrinsic. Then during linking if we map some isomorphic
types we have to update intrinsics names. To do that we have to teach IRMover to
update intrinsics signatures according to the types mapping.
Does this sound reasonable? Are there any other alternatives?
Artur
To reproduce:
$ clang -O3 -S -march=core-avx2 -emit-llvm bar.c
$ clang -O3 -S -march=core-avx2 -emit-llvm foo.c
$ llvm-as bar.ll
$ llvm-as foo.ll
$ llvm-lto foo.bc bar.bc
Invalid user of intrinsic instruction!
<4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x
i1>, <4 x %struct.foobar.0*>)* bitcast (<4 x %struct.foobar*>
(<4 x %struct.foobar*>*, i32, <4 x i1>, <4 x
%struct.foobar*>)* @llvm.masked.load.v4p0struct.foobar to <4 x
%struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>,
<4 x %struct.foobar.0*>)*)
Invalid user of intrinsic instruction!
void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32, <4
x i1>)* bitcast (void (<4 x %struct.foobar*>, <4 x
%struct.foobar*>*, i32, <4 x i1>)* @llvm.masked.store.v4p0struct.foobar
to void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32,
<4 x i1>)*)
LLVM ERROR: Broken module found, compilation aborted!
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/56f9e330/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bar.c
Type: application/octet-stream
Size: 218 bytes
Desc: bar.c
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/56f9e330/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: foo.c
Type: application/octet-stream
Size: 206 bytes
Desc: foo.c
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/56f9e330/attachment-0001.obj>
> On Apr 18, 2016, at 9:45 AM, Artur Pilipenko via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > In the current mangling scheme for overloaded intrinsics we include overloaded type names in the intrinsic name. For example: > > %struct.foobar = type { i32 } > declare <4 x %struct.foobar*> @llvm.masked.load.v4p0struct.foobar(<4 x %struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>) > > Verifier checks that an overloaded intrinsic name matches with its signature.I assume the verify does this just for internal consistency, if there is another good reason all of what I write below does not make sense probably... We could make it tolerating this by trying to remove the suffix for the types and accept that the intrinsic name matches the type name without the suffix?> > When different modules are loaded in LTO configuration with the same LLVMContext, types with the same name from different modules are renamed so their names are unique (%struct.foobar in the second module becomes %struct.foobar.0). After renaming intrinsic names and signatures can become inconsistent. > > Usually it slips unnoticed because we don't verify individual modules and eventually map isomorphic types to a single type. So isomorphic types get their original names. Although in some cases it causes problems. > > Initially I came across the problem with my recent change which added an overloaded type to the masked load/store intrinsics (http://reviews.llvm.org/D17270 <http://reviews.llvm.org/D17270>). The discrepancy between the name and the signature triggers auto-upgrade bit from my patch converting an incorrect mangling to the correct one. But later after remapping of isomorphic types when we return to the original type name this “updated" intrinsic name become invalid.In the same way, I'd try to avoid "autoupgrading" in this case? I'm puzzled by the fact that round-tripping to bitcode within the same version of LLVM triggers an "upgrade". -- Mehdi> > Another way to trigger the problem is to have different types with the same name in different modules. Corresponding test case is attached. In this case types in different modules will be renamed but the intrinsics from different modules will have the same name which will be caught by verifier. > > As a possible solution we can use AutoUpgrade to handle the situation when the name of the intrinsic doesn't match with its signature. In such cases we have to rename the intrinsic. Then during linking if we map some isomorphic types we have to update intrinsics names. To do that we have to teach IRMover to update intrinsics signatures according to the types mapping. > > Does this sound reasonable? Are there any other alternatives? > > Artur > > To reproduce: > $ clang -O3 -S -march=core-avx2 -emit-llvm bar.c > $ clang -O3 -S -march=core-avx2 -emit-llvm foo.c > $ llvm-as bar.ll > $ llvm-as foo.ll > $ llvm-lto foo.bc bar.bc > Invalid user of intrinsic instruction! > <4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>, <4 x %struct.foobar.0*>)* bitcast (<4 x %struct.foobar*> (<4 x %struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>)* @llvm.masked.load.v4p0struct.foobar to <4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>, <4 x %struct.foobar.0*>)*) > Invalid user of intrinsic instruction! > void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32, <4 x i1>)* bitcast (void (<4 x %struct.foobar*>, <4 x %struct.foobar*>*, i32, <4 x i1>)* @llvm.masked.store.v4p0struct.foobar to void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32, <4 x i1>)*) > LLVM ERROR: Broken module found, compilation aborted! > <bar.c><foo.c>_______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/6ae937ea/attachment.html>
On 18 Apr 2016, at 19:52, Mehdi Amini <mehdi.amini at
apple.com<mailto:mehdi.amini at apple.com>> wrote:
On Apr 18, 2016, at 9:45 AM, Artur Pilipenko via llvm-dev <llvm-dev at
lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote:
In the current mangling scheme for overloaded intrinsics we include overloaded
type names in the intrinsic name. For example:
%struct.foobar = type { i32 }
declare <4 x %struct.foobar*> @llvm.masked.load.v4p0struct.foobar(<4 x
%struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>)
Verifier checks that an overloaded intrinsic name matches with its signature.
I assume the verify does this just for internal consistency, if there is another
good reason all of what I write below does not make sense probably...
We could make it tolerating this by trying to remove the suffix for the types
and accept that the intrinsic name matches the type name without the suffix?
There is no guarantee that two types which names differ by the suffix are the
same. Even in LTO case we might have unrelated types with the same name in
different modules (it’s basically my second example). I’m reluctant to relax the
verification rules because it only wraps the underlying issue and potentially
allows incorrect code (the case when two unrelated types had the same name) to
pass verification.
When different modules are loaded in LTO configuration with the same
LLVMContext, types with the same name from different modules are renamed so
their names are unique (%struct.foobar in the second module becomes
%struct.foobar.0). After renaming intrinsic names and signatures can become
inconsistent.
Usually it slips unnoticed because we don't verify individual modules and
eventually map isomorphic types to a single type. So isomorphic types get their
original names. Although in some cases it causes problems.
Initially I came across the problem with my recent change which added an
overloaded type to the masked load/store intrinsics
(http://reviews.llvm.org/D17270). The discrepancy between the name and the
signature triggers auto-upgrade bit from my patch converting an incorrect
mangling to the correct one. But later after remapping of isomorphic types when
we return to the original type name this “updated" intrinsic name become
invalid.
In the same way, I'd try to avoid "autoupgrading" in this case?
I'm puzzled by the fact that round-tripping to bitcode within the same
version of LLVM triggers an "upgrade”.
In my view auto-upgrade is triggered on a malformed module (it wouldn’t pass
verification). That’s actually one of the reasons to verify that the name
matches with the signature - AutoUpgrade relies on that fact.
Artur
--
Mehdi
Another way to trigger the problem is to have different types with the same name
in different modules. Corresponding test case is attached. In this case types in
different modules will be renamed but the intrinsics from different modules will
have the same name which will be caught by verifier.
As a possible solution we can use AutoUpgrade to handle the situation when the
name of the intrinsic doesn't match with its signature. In such cases we
have to rename the intrinsic. Then during linking if we map some isomorphic
types we have to update intrinsics names. To do that we have to teach IRMover to
update intrinsics signatures according to the types mapping.
Does this sound reasonable? Are there any other alternatives?
Artur
To reproduce:
$ clang -O3 -S -march=core-avx2 -emit-llvm bar.c
$ clang -O3 -S -march=core-avx2 -emit-llvm foo.c
$ llvm-as bar.ll
$ llvm-as foo.ll
$ llvm-lto foo.bc bar.bc
Invalid user of intrinsic instruction!
<4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x
i1>, <4 x %struct.foobar.0*>)* bitcast (<4 x %struct.foobar*>
(<4 x %struct.foobar*>*, i32, <4 x i1>, <4 x
%struct.foobar*>)* @llvm.masked.load.v4p0struct.foobar to <4 x
%struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>,
<4 x %struct.foobar.0*>)*)
Invalid user of intrinsic instruction!
void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32, <4
x i1>)* bitcast (void (<4 x %struct.foobar*>, <4 x
%struct.foobar*>*, i32, <4 x i1>)* @llvm.masked.store.v4p0struct.foobar
to void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32,
<4 x i1>)*)
LLVM ERROR: Broken module found, compilation aborted!
<bar.c><foo.c>_______________________________________________
LLVM Developers mailing list
llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/f2009e67/attachment.html>
On Mon, Apr 18, 2016 at 9:45 AM, Artur Pilipenko via llvm-dev < llvm-dev at lists.llvm.org> wrote:> In the current mangling scheme for overloaded intrinsics we include > overloaded type names in the intrinsic name. For example: > > %struct.foobar = type { i32 } > declare <4 x %struct.foobar*> @llvm.masked.load.v4p0struct.foobar(<4 x > %struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>) > > Verifier checks that an overloaded intrinsic name matches with its > signature. > > When different modules are loaded in LTO configuration with the same > LLVMContext, types with the same name from different modules are renamedso> their names are unique (%struct.foobar in the second module becomes > %struct.foobar.0). After renaming intrinsic names and signatures canbecome> inconsistent. > > Usually it slips unnoticed because we don't verify individual modules and > eventually map isomorphic types to a single type. So isomorphic types get > their original names. Although in some cases it causes problems. > > Initially I came across the problem with my recent change which added an > overloaded type to the masked load/store intrinsics > (http://reviews.llvm.org/D17270). The discrepancy between the name and the > signature triggers auto-upgrade bit from my patch converting an incorrect > mangling to the correct one. But later after remapping of isomorphic types > when we return to the original type name this “updated" intrinsic name > become invalid. > > Another way to trigger the problem is to have different types with thesame> name in different modules. Corresponding test case is attached. In thiscase> types in different modules will be renamed but the intrinsics fromdifferent> modules will have the same name which will be caught by verifier. > > As a possible solution we can use AutoUpgrade to handle the situation when > the name of the intrinsic doesn't match with its signature. In such caseswe> have to rename the intrinsic. Then during linking if we map someisomorphic> types we have to update intrinsics names. To do that we have to teach > IRMover to update intrinsics signatures according to the types mapping. > > Does this sound reasonable? Are there any other alternatives?Would demoting pointer types to pNi8 work? As you say, that could potentially mask problems, but I don't think the type of the masked load/store matters, only the types of the pointer elements at the subsequent loads/stores. In other words, this sounds equivalent to opaque pointer types to me. A pointer load shouldn't care about the type. -Ahmed> Artur > > To reproduce: > $ clang -O3 -S -march=core-avx2 -emit-llvm bar.c > $ clang -O3 -S -march=core-avx2 -emit-llvm foo.c > $ llvm-as bar.ll > $ llvm-as foo.ll > $ llvm-lto foo.bc bar.bc > Invalid user of intrinsic instruction! > <4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>, <4 x > %struct.foobar.0*>)* bitcast (<4 x %struct.foobar*> (<4 x%struct.foobar*>*,> i32, <4 x i1>, <4 x %struct.foobar*>)* @llvm.masked.load.v4p0struct.foobar > to <4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>, <4 x > %struct.foobar.0*>)*) > Invalid user of intrinsic instruction! > void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32, <4 x i1>)* > bitcast (void (<4 x %struct.foobar*>, <4 x %struct.foobar*>*, i32, <4 x > i1>)* @llvm.masked.store.v4p0struct.foobar to void (<4 x%struct.foobar.0*>,> <4 x %struct.foobar.0*>*, i32, <4 x i1>)*) > LLVM ERROR: Broken module found, compilation aborted! > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/a24d8f0f/attachment.html>
On 04/18/2016 09:45 AM, Artur Pilipenko via llvm-dev wrote:> In the current mangling scheme for overloaded intrinsics we include > overloaded type names in the intrinsic name. For example: > > %struct.foobar = type { i32 } > declare <4 x %struct.foobar*> @llvm.masked.load.v4p0struct.foobar(<4 x > %struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>) > > Verifier checks that an overloaded intrinsic name matches with its > signature. > > When different modules are loaded in LTO configuration with the same > LLVMContext, types with the same name from different modules are > renamed so their names are unique (%struct.foobar in the second module > becomes %struct.foobar.0). After renaming intrinsic names and > signatures can become inconsistent.This seems like a clear bug in the module loading. If we're changing type names, we need to change the intrinsic signatures as well.> > Usually it slips unnoticed because we don't verify individual modules > and eventually map isomorphic types to a single type. So isomorphic > types get their original names. Although in some cases it causes > problems. > > Initially I came across the problem with my recent change which added > an overloaded type to the masked load/store intrinsics > (http://reviews.llvm.org/D17270). The discrepancy between the name and > the signature triggers auto-upgrade bit from my patch converting an > incorrect mangling to the correct one. But later after remapping of > isomorphic types when we return to the original type name this > “updated" intrinsic name become invalid. > > Another way to trigger the problem is to have different types with the > same name in different modules. Corresponding test case is attached. > In this case types in different modules will be renamed but the > intrinsics from different modules will have the same name which will > be caught by verifier. > > As a possible solution we can use AutoUpgrade to handle the situation > when the name of the intrinsic doesn't match with its signature. In > such cases we have to rename the intrinsic. Then during linking if we > map some isomorphic types we have to update intrinsics names. To do > that we have to teach IRMover to update intrinsics signatures > according to the types mapping. > > Does this sound reasonable? Are there any other alternatives?Given our current intrinsic naming scheme, the approach you've described seems entirely reasonable. An alternate scheme would be to make the intrinsic signatures insensitive to the struct naming. (That was probably a bad idea on my part to start with, sorry!) I would argue that we should not block your original change on a re-architecting effort here.> > Artur > > To reproduce: > $ clang -O3 -S -march=core-avx2 -emit-llvm bar.c > $ clang -O3 -S -march=core-avx2 -emit-llvm foo.c > $ llvm-as bar.ll > $ llvm-as foo.ll > $ llvm-lto foo.bc bar.bc > Invalid user of intrinsic instruction! > <4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>, <4 x > %struct.foobar.0*>)* bitcast (<4 x %struct.foobar*> (<4 x > %struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>)* > @llvm.masked.load.v4p0struct.foobar to <4 x %struct.foobar.0*> (<4 x > %struct.foobar.0*>*, i32, <4 x i1>, <4 x %struct.foobar.0*>)*) > Invalid user of intrinsic instruction! > void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32, <4 x > i1>)* bitcast (void (<4 x %struct.foobar*>, <4 x %struct.foobar*>*, > i32, <4 x i1>)* @llvm.masked.store.v4p0struct.foobar to void (<4 x > %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32, <4 x i1>)*) > LLVM ERROR: Broken module found, compilation aborted! > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/4b246a6a/attachment.html>
On 04/18/2016 09:52 AM, Mehdi Amini via llvm-dev wrote:>> >> Initially I came across the problem with my recent change which added >> an overloaded type to the masked load/store intrinsics >> (http://reviews.llvm.org/D17270). The discrepancy between the name >> and the signature triggers auto-upgrade bit from my patch converting >> an incorrect mangling to the correct one. But later after remapping >> of isomorphic types when we return to the original type name this >> “updated" intrinsic name become invalid. > > In the same way, I'd try to avoid "autoupgrading" in this case? I'm > puzzled by the fact that round-tripping to bitcode within the same > version of LLVM triggers an "upgrade".This does seem questionable. It's doesn't avoid the root issue - which is that we're not renaming intrinsics when renaming types - but changing this would seem reasonable to me. It sounds like we might be relying on the upgrade functionality to paper over problems with type renaming. (And possibly other things...?) Philip -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/860b2227/attachment.html>
On 04/18/2016 10:52 AM, Ahmed Bougacha via llvm-dev wrote:> On Mon, Apr 18, 2016 at 9:45 AM, Artur Pilipenko via llvm-dev > <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: > > In the current mangling scheme for overloaded intrinsics we include > > overloaded type names in the intrinsic name. For example: > > > > %struct.foobar = type { i32 } > > declare <4 x %struct.foobar*> @llvm.masked.load.v4p0struct.foobar(<4 x > > %struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>) > > > > Verifier checks that an overloaded intrinsic name matches with its > > signature. > > > > When different modules are loaded in LTO configuration with the same > > LLVMContext, types with the same name from different modules are > renamed so > > their names are unique (%struct.foobar in the second module becomes > > %struct.foobar.0). After renaming intrinsic names and signatures can > become > > inconsistent. > > > > Usually it slips unnoticed because we don't verify individual > modules and > > eventually map isomorphic types to a single type. So isomorphic > types get > > their original names. Although in some cases it causes problems. > > > > Initially I came across the problem with my recent change which added an > > overloaded type to the masked load/store intrinsics > > (http://reviews.llvm.org/D17270). The discrepancy between the name > and the > > signature triggers auto-upgrade bit from my patch converting an > incorrect > > mangling to the correct one. But later after remapping of isomorphic > types > > when we return to the original type name this “updated" intrinsic name > > become invalid. > > > > Another way to trigger the problem is to have different types with > the same > > name in different modules. Corresponding test case is attached. In > this case > > types in different modules will be renamed but the intrinsics from > different > > modules will have the same name which will be caught by verifier. > > > > As a possible solution we can use AutoUpgrade to handle the > situation when > > the name of the intrinsic doesn't match with its signature. In such > cases we > > have to rename the intrinsic. Then during linking if we map some > isomorphic > > types we have to update intrinsics names. To do that we have to teach > > IRMover to update intrinsics signatures according to the types mapping. > > > > Does this sound reasonable? Are there any other alternatives? > > Would demoting pointer types to pNi8 work? > > As you say, that could potentially mask problems, but I don't think > the type of the masked load/store matters, only the types of the > pointer elements at the subsequent loads/stores. > In other words, this sounds equivalent to opaque pointer types to me. > A pointer load shouldn't care about the type.I went down this path too. It doesn't work unfortunately. The problem is that the value type of the store is also part of the signature and could be a struct type. Analogously, the same problem exists for the return type of the load. We can and do lower loads/stores of different value types differently. Memory isn't typed, but the operation is.> > -Ahmed > > > Artur > > > > To reproduce: > > $ clang -O3 -S -march=core-avx2 -emit-llvm bar.c > > $ clang -O3 -S -march=core-avx2 -emit-llvm foo.c > > $ llvm-as bar.ll > > $ llvm-as foo.ll > > $ llvm-lto foo.bc bar.bc > > Invalid user of intrinsic instruction! > > <4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>, <4 x > > %struct.foobar.0*>)* bitcast (<4 x %struct.foobar*> (<4 x > %struct.foobar*>*, > > i32, <4 x i1>, <4 x %struct.foobar*>)* > @llvm.masked.load.v4p0struct.foobar > > to <4 x %struct.foobar.0*> (<4 x %struct.foobar.0*>*, i32, <4 x i1>, > <4 x > > %struct.foobar.0*>)*) > > Invalid user of intrinsic instruction! > > void (<4 x %struct.foobar.0*>, <4 x %struct.foobar.0*>*, i32, <4 x i1>)* > > bitcast (void (<4 x %struct.foobar*>, <4 x %struct.foobar*>*, i32, <4 x > > i1>)* @llvm.masked.store.v4p0struct.foobar to void (<4 x > %struct.foobar.0*>, > > <4 x %struct.foobar.0*>*, i32, <4 x i1>)*) > > LLVM ERROR: Broken module found, compilation aborted! > > > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160418/9c1c40dc/attachment.html>
Rafael Espíndola via llvm-dev
2016-Apr-19 21:51 UTC
[llvm-dev] LTO and intrinsics mangling
On 18 April 2016 at 19:22, Philip Reames via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > > On 04/18/2016 09:45 AM, Artur Pilipenko via llvm-dev wrote: > > In the current mangling scheme for overloaded intrinsics we include > overloaded type names in the intrinsic name. For example: > > %struct.foobar = type { i32 } > declare <4 x %struct.foobar*> @llvm.masked.load.v4p0struct.foobar(<4 x > %struct.foobar*>*, i32, <4 x i1>, <4 x %struct.foobar*>) > > Verifier checks that an overloaded intrinsic name matches with its > signature. > > When different modules are loaded in LTO configuration with the same > LLVMContext, types with the same name from different modules are renamed so > their names are unique (%struct.foobar in the second module becomes > %struct.foobar.0). After renaming intrinsic names and signatures can become > inconsistent. > > This seems like a clear bug in the module loading. If we're changing type > names, we need to change the intrinsic signatures as well. > > > Usually it slips unnoticed because we don't verify individual modules and > eventually map isomorphic types to a single type. So isomorphic types get > their original names. Although in some cases it causes problems. > > Initially I came across the problem with my recent change which added an > overloaded type to the masked load/store intrinsics > (http://reviews.llvm.org/D17270). The discrepancy between the name and the > signature triggers auto-upgrade bit from my patch converting an incorrect > mangling to the correct one. But later after remapping of isomorphic types > when we return to the original type name this “updated" intrinsic name > become invalid. > > Another way to trigger the problem is to have different types with the same > name in different modules. Corresponding test case is attached. In this case > types in different modules will be renamed but the intrinsics from different > modules will have the same name which will be caught by verifier. > > As a possible solution we can use AutoUpgrade to handle the situation when > the name of the intrinsic doesn't match with its signature. In such cases we > have to rename the intrinsic. Then during linking if we map some isomorphic > types we have to update intrinsics names. To do that we have to teach > IRMover to update intrinsics signatures according to the types mapping. > > Does this sound reasonable? Are there any other alternatives? > > Given our current intrinsic naming scheme, the approach you've described > seems entirely reasonable. > > An alternate scheme would be to make the intrinsic signatures insensitive to > the struct naming. (That was probably a bad idea on my part to start with, > sorry!) I would argue that we should not block your original change on a > re-architecting effort here.I sorry I missed this when it first went in. In general the name of llvm types should not be significant. What was the motivation for having it in the name of the intrinsic? Could we change to using declare <4 x %struct.foo*> @llvm.masked.load.arbitrary_suffix1(<4 x %struct.foo*>*, i32, <4 x i1>, <4 x %struct.foo*>) declare <4 x %struct.bar*> @llvm.masked.load.arbitrary_suffix2(<4 x %struct.bar*>*, i32, <4 x i1>, <4 x %struct.bar*>) Cheers, Rafael