Proper way to load pre-generated LLVM IR into JIT module and dedup type definitions?

What is the proper way to load a set of pre-generated LLVM IR and make it available to runtime JIT modules such that the same types aren’t given new names and inlining and const propagation can still take place?

My attempt so far:

I compile a set of C functions to LLVM IR offline via ‘clang -c -emit-llvm -S -ffast-math -msse2 -O3 -o MyLib.ll MyLib.c’

For each runtime JIT module, I load the generated LLVM IR via llvm::parseIRFile() and “paste” it into the runtime JIT module via llvm::Linker::linkModules().

This works fine for the first JIT module, but not for subsequent JIT modules created. Each time llvm::parseIRFile() is called, the resulting module’s type definitions in the IR is given new names.

For example, offline MyLib.ll looks like this:

%struct.A = type { <4 x float> }

define <4 x float> @Foo(A*)(%struct.A* nocapture readonly) { … }

The resulting module from the first call to llvm::parseIRFile() looks exactly as the offline version. The resulting module from the second call to llvm:parseIRFile() instead looks like:

%struct.A**.1** = type { <4 x float> } define <4 x float> @Foo(A*)(%struct.A.1* nocapture readonly) { … }

Note that %struct.A was renamed to %struct.A.1. The runtime JIT module continues to generate code using %struct.A thus fails to call Foo() since its parameter is %struct.A.1 instead.