[llvm-dev] LTO and intrinsics mangling
Philip Reames via llvm-dev
llvm-dev at lists.llvm.org
Mon Apr 18 16:28:13 PDT 2016
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>
More information about the llvm-dev
mailing list