Hello! I linked two bitcode files like described below using LTO and find they are linked fine instead of making an error. ---------- 1.bc ---------- ... define i32 @main(i32 %argc, i8** %argv) #0 { entry: ... %call = call i32 @_Z1aj(i64 2) ... } declare i32 @_Z1aj(i64) #1 ... ---------- 2.bc ---------- ... define i32 @_Z1aj(i32 %b) #0 { entry: ... } ... ---------- In the first file function "_Z1aj" is declared as having i64 argument, whereas in the second file the function "_Z1aj" is described as having i32 argument! Are function signatures different? How does LLVM cast them? Could it be a bug? -- Best regards, Ksenia
Ksenia Dolgorukova wrote:> Hello! > I linked two bitcode files like described below using LTO and find > they are linked fine instead of making an error. > ---------- > 1.bc > ---------- > ... > define i32 @main(i32 %argc, i8** %argv) #0 { > entry: > ... > %call = call i32 @_Z1aj(i64 2) > ... > } > declare i32 @_Z1aj(i64) #1 > ... > > ---------- > 2.bc > ---------- > ... > define i32 @_Z1aj(i32 %b) #0 { > entry: > ... > } > ... > > ---------- > > In the first file function "_Z1aj" is declared as having i64 argument, > whereas in the second file the function "_Z1aj" is described as having > i32 argument! > > Are function signatures different?They're both 'a(unsigned int)', but perhaps you compiled one of them targeting a 32-bit platform and the other targeting a 64-bit platform? What triple is at the top of each .bc file?> How does LLVM cast them? > Could it be a bug? >
They both was compiled with clang for 64-bit target. These example bitcode files was modified by hand to check if this case will work. Actually, this feature was revealed when I compiled 'coremark' benchmark with LTO for x68-64 target. I think, different signatures was caused by preprocessor directives. But I wander how can it work. 2015-04-10 21:05 GMT+03:00 Nick Lewycky <nicholas at mxc.ca>:> Ksenia Dolgorukova wrote: >> >> Hello! >> I linked two bitcode files like described below using LTO and find >> they are linked fine instead of making an error. >> ---------- >> 1.bc >> ---------- >> ... >> define i32 @main(i32 %argc, i8** %argv) #0 { >> entry: >> ... >> %call = call i32 @_Z1aj(i64 2) >> ... >> } >> declare i32 @_Z1aj(i64) #1 >> ... >> >> ---------- >> 2.bc >> ---------- >> ... >> define i32 @_Z1aj(i32 %b) #0 { >> entry: >> ... >> } >> ... >> >> ---------- >> >> In the first file function "_Z1aj" is declared as having i64 argument, >> whereas in the second file the function "_Z1aj" is described as having >> i32 argument! >> >> Are function signatures different? > > > They're both 'a(unsigned int)', but perhaps you compiled one of them > targeting a 32-bit platform and the other targeting a 64-bit platform? What > triple is at the top of each .bc file? > > >> How does LLVM cast them? >> Could it be a bug? >> >-- Best regards, Ksenia
Hello Ksenia, Function names in the examples below are mangled names. _Z1aj means function with name 'a' which accepts one argument of 'unsigned int' type. The following declaration is correct from LLVM bitcode point of view but the function name does not match type of the function's argument. declare i32 @_Z1aj(i64) If you compile the following code by g++ you get _Z1ay name because 'unsigned long long' corresponds to 'y' in the mangled name. int a(unsigned long long); The linker does not know anything about real type of functions and uses only mangled names for lookup. That is why the linker successfully link this code. In the real case 'void a(unsigned)' converts to the _Z1aj, while 'void a(unsigned long long)' gets _Z1ay name and linker shows an error. That is interesting why the code runs without any error. I think that is because you run it on 64-bit systems and arguments passed by registers. Probably it fails if you compile it and run on 32-bit systems. On Fri, Apr 10, 2015 at 4:03 PM, Ksenia Dolgorukova <der.spiegel.sieht.mich at gmail.com> wrote:> Hello! > I linked two bitcode files like described below using LTO and find > they are linked fine instead of making an error. > ---------- > 1.bc > ---------- > ... > define i32 @main(i32 %argc, i8** %argv) #0 { > entry: > ... > %call = call i32 @_Z1aj(i64 2) > ... > } > declare i32 @_Z1aj(i64) #1 > ... > > ---------- > 2.bc > ---------- > ... > define i32 @_Z1aj(i32 %b) #0 { > entry: > ... > } > ... > > ---------- > > In the first file function "_Z1aj" is declared as having i64 argument, > whereas in the second file the function "_Z1aj" is described as having > i32 argument! > > Are function signatures different? > How does LLVM cast them? > Could it be a bug?Regards, Simon Atanasyan