Ray Wang via llvm-dev
2018-Jun-29 04:01 UTC
[llvm-dev] llvm-link is creating 32 and 64-bit versions of a struct
I have two bitcode files that I want to link together, using the command `llvm-link -o llvm-helpers.bc1 target/arm/op_helper.bc2 target/arm/helper.bc2` Both files define the struct `%struct.ARMCPRegInfo`. However, when I link them together, the resulting bitcode has two structs of different bitsizes, one ending with `.32`. As a result, some functions use the `.32` type as an argument, which is not intended. %struct.ARMCPRegInfo.32 = type { i8*, i8, i8, i8, i8, i8, i8, i32, i32, i32, i32, i8*, i64, i64, [2 x i64], i32 (%struct.CPUARMState*, %struct.ARMCPRegInfo.32*, i1)*, {}*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo.32*, i64)*, {}*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo.32*, i64)*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo. 32*)* } %struct.ARMCPRegInfo = type { i8*, i8, i8, i8, i8, i8, i8, i32, i32, i32, i32, i8*, i64, i64, [2 x i64], i32 (%struct.CPUARMState*, %struct.ARMCPRegInfo*, i1)*, i64 (%struct.CPUARMState*, %struct.ARMCPRegInfo*)*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo*, i64)*, i64 (%struct.CPUARMState*, %struct.ARMCPRegInfo*)*, void (%struct. CPUARMState*, %struct.ARMCPRegInfo*, i64)*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo*)* } Why are two structs being created, and how do I prevent this from happening? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180629/37f78fe4/attachment.html>
Tim Northover via llvm-dev
2018-Jun-29 06:40 UTC
[llvm-dev] llvm-link is creating 32 and 64-bit versions of a struct
Hi Ray, On Fri, 29 Jun 2018 at 05:02, Ray Wang via llvm-dev <llvm-dev at lists.llvm.org> wrote:> Both files define the struct `%struct.ARMCPRegInfo`. However, when I link them together, the resulting bitcode has two structs of different bitsizes, one ending with `.32`. As a result, some functions use the `.32` type as an argument, which is not intended.What makes you think they have different sizes? LLVM claims they're both 88 bytes for me.> %struct.ARMCPRegInfo.32 = type { i8*, i8, i8, i8, i8, i8, i8, i32, i32, i32, i32, i8*, i64, i64, [2 x i64], i32 (%struct.CPUARMState*, %struct.ARMCPRegInfo.32*, i1)*, {}*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo.32*, i64)*, {}*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo.32*, i64)*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo. 32*)* } > > %struct.ARMCPRegInfo = type { i8*, i8, i8, i8, i8, i8, i8, i32, i32, i32, i32, i8*, i64, i64, [2 x i64], i32 (%struct.CPUARMState*, %struct.ARMCPRegInfo*, i1)*, i64 (%struct.CPUARMState*, %struct.ARMCPRegInfo*)*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo*, i64)*, i64 (%struct.CPUARMState*, %struct.ARMCPRegInfo*)*, void (%struct. CPUARMState*, %struct.ARMCPRegInfo*, i64)*, void (%struct.CPUARMState*, %struct.ARMCPRegInfo*)* } > > Why are two structs being created, and how do I prevent this from happening?The critical difference is the "{}*" parameter in the middle, which is a more fleshed out function pointer type in the second struct. LLVM will only merge types that are identical (otherwise it would have to add or remove cast instructions from functions which goes well beyond linking), so if you really want to stop the rename you have to change how you generate these types. But really you should probably try to stop relying on types being unique, or the names of types at all, in LLVM IR. They're not designed to be used like that; they're really only named at all as an aid to human comprehension. Especially, Clang will not guarantee identical types in the IR it generates (for various reasons). Cheers. Tim.