[LLVM, llvm-link] Opaque types.

Is it legal to substitute non struct type instead of opaque type?

For example:
; 1.ll
declare void @F(i32*)

; 2.ll
%T1 = type opaque
declare void @F(%T1*)

Is it normal to replace T1 with i32 here?

If yes. Will the next types are isomorphic?:

%T1 = type opaque
{ i32, %T1* }
{ i32, i32* }

-Stepan.

Is it legal to substitute non struct type instead of opaque type?

For example:
; 1.ll
declare void @F(i32*)

; 2.ll
%T1 = type opaque
declare void @F(%T1*)

Is it normal to replace T1 with i32 here?

Yes, the linker will do this, because it is forced to break type safety to link up the functions.

If yes. Will the next types are isomorphic?:

%T1 = type opaque
{ i32, %T1* }
{ i32, i32* }

No. opaque types are instances of struct types and are uniqued by name. i32 is not a struct type. These two types are also not isomorphic:

%T1 = type opaque
%T2 = type opaque
{ i32, %T1* }
{ i32, %T2* }

-Chris

OK. So if we have two modules with the same function name. This functions may not be isomorphic.

For example, we can link this files, but the function types are not isomorphic:

; 1.ll
%T1 = type opaque
declare i32 @foo(%T1*)

; 2.ll
define i32 @foo(i32* %v) {...something...}

But at the same time we should not map next two functions (PR11627):

; 3.ll
declare i32 @foo(i16* %v)

; 4.ll
define i32 @foo(i32* %b) {...something...}

If I right, with that. How it is better to fix that? I propose to create some method canMapFunctions that will very similar to areTypesIsomorphic except the case I described in 1.ll and 2.ll. Is it fine?

-Stepan

The linker will force the functions together in both cases. This doesn't have anything to do with areTypesIsomorphic though: it inserts bitcasts of the functions themselves (e.g. turning direct calls into indirect calls through a cast) to make this happen.

-Chris