[llvm-dev] LTO and intrinsics mangling

Ahmed Bougacha via llvm-dev llvm-dev at lists.llvm.org
Mon Apr 18 10:52:57 PDT 2016


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 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.

-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>


More information about the llvm-dev mailing list