Peter Zotov
2013-Jan-09 15:59 UTC
[LLVMdev] Global variable initializer type does not match global variable type
Hello. I've managed to create a bitcode file (attached; also available at [1]) which produces a series of identical errors when verified: | Global variable initializer type does not match global variable type! | %i.NilClass* @nil When ran through llvm-dis and recompiled, through, it verifies successfully. If I disassemble it one more time, the result is identical to the first disassembly. The recompiled bitcode file is slightly smaller. I suspect that the problem is with aggregate type uniqueing. I use ruby-llvm bindings, LLVM 3.2 to generate the file; the following code demonstrates what I deem the incorrect behavior: # llvm_ty is an LLVM struct type with 2 elements. a, b = llvm_ty.element_types # Here, I decompose the type and verify that the types of elements # match my expectations: p a == @types[Monotype.of(VI::Class)] # true p b == emit_class_body_type(klass) # true # I attempt to reconstruct the type using the elements # and check if it's still the same. p llvm_ty == LLVM::Type.struct([ @types[Monotype.of(VI::Class)], emit_class_body_type(klass) ], false) # false. Why? Ruby-LLVM bindings compare underlying LLVM pointers when the Type objects are compared with ==. The problem manifests itself when the following code contains the initializer assignment: datum = @llvm.globals.add llvm_ty, name datum.initializer = LLVM::ConstantStruct.const([ emit_object(klass, klass_name).bitcast_to( @types[Monotype.of(VI::Class)]), LLVM::Constant.null(emit_class_body_type(klass)) ]) LLVM::ConstantStruct.const eventually calls the LLVMConstStruct method with the appropriate arguments; LLVM::Constant.null corresponds to LLVMConstNull. Any hints are greatly appreciated. -- WBR, Peter Zotov. [1]: http://fehu.whitequark.org/files/gvar-init.bc -------------- next part -------------- A non-text attachment was scrubbed... Name: test.bc Type: application/octet-stream Size: 752 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130109/7dfa89a9/attachment.obj>
Peter Zotov
2013-Jan-09 19:11 UTC
[LLVMdev] Global variable initializer type does not match global variable type
Peter Zotov писал 09.01.2013 19:59:> Hello. > > I've managed to create a bitcode file (attached; also available at > [1]) which produces > a series of identical errors when verified: > > | Global variable initializer type does not match global variable > type! > | %i.NilClass* @nil > > When ran through llvm-dis and recompiled, through, it verifies > successfully. If I > disassemble it one more time, the result is identical to the first > disassembly. The > recompiled bitcode file is slightly smaller. > > I suspect that the problem is with aggregate type uniqueing. I use > ruby-llvm bindings, > LLVM 3.2 to generate the file; the following code demonstrates what I > deem the incorrect > behavior: > > (snip)I've ran the good and bad bitcode files for a more compact example (attached) through llvm-bcanalyzer and diff: --- bad.xml 2013-01-09 22:57:58.691131492 +0400 +++ good.xml 2013-01-09 22:58:04.153133734 +0400 ... irrelevant ... <STRUCT_NAME abbrevid=7 op0=105 op1=46 op2=78 op3=105 op4=108 op5=67 op6=108 op7=97 op8=115 op9=115/> <STRUCT_NAMED abbrevid=8 op0=0 op1=0 op2=6/> <POINTER abbrevid=4 op0=7 op1=0/> - <STRUCT_ANON abbrevid=6 op0=0 op1=0 op2=6/> </TYPE_BLOCK_ID> <GLOBALVAR abbrevid=4 op0=8 op1=0 op2=2 op3=0 op4=0 op5=0/> <CONSTANTS_BLOCK NumWords=5 BlockCodeSize=4> - <SETTYPE abbrevid=4 op0=9/> + <SETTYPE abbrevid=4 op0=7/> <NULL/> </CONSTANTS_BLOCK> ... all the same ... So it pretty much seems that instantiating a constant struct with a type which is structurally identical to an existing named struct type creates a new anonymous struct which is for some reason not deemed to be identical to the named one. Any ideas why? -- WBR, Peter Zotov. -------------- next part -------------- A non-text attachment was scrubbed... Name: bad.bc Type: application/octet-stream Size: 340 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130109/aed7cffe/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: good.bc Type: application/octet-stream Size: 336 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130109/aed7cffe/attachment-0001.obj>
Peter Zotov
2013-Jan-09 20:23 UTC
[LLVMdev] Global variable initializer type does not match global variable type
Peter Zotov писал 09.01.2013 23:11:> Peter Zotov писал 09.01.2013 19:59: >> Hello. >> >> I've managed to create a bitcode file (attached; also available at >> [1]) which produces >> a series of identical errors when verified: >> >> | Global variable initializer type does not match global variable >> type! >> | %i.NilClass* @nil >> >> When ran through llvm-dis and recompiled, through, it verifies >> successfully. If I >> disassemble it one more time, the result is identical to the first >> disassembly. The >> recompiled bitcode file is slightly smaller. >> >> I suspect that the problem is with aggregate type uniqueing. I use >> ruby-llvm bindings, >> LLVM 3.2 to generate the file; the following code demonstrates what >> I >> deem the incorrect >> behavior: >> >> (snip) > > > I've ran the good and bad bitcode files for a more compact example > (attached) > through llvm-bcanalyzer and diff: > > --- bad.xml 2013-01-09 22:57:58.691131492 +0400 > +++ good.xml 2013-01-09 22:58:04.153133734 +0400 > ... irrelevant ... > <STRUCT_NAME abbrevid=7 op0=105 op1=46 op2=78 op3=105 op4=108 > op5=67 op6=108 op7=97 op8=115 op9=115/> > <STRUCT_NAMED abbrevid=8 op0=0 op1=0 op2=6/> > <POINTER abbrevid=4 op0=7 op1=0/> > - <STRUCT_ANON abbrevid=6 op0=0 op1=0 op2=6/> > </TYPE_BLOCK_ID> > <GLOBALVAR abbrevid=4 op0=8 op1=0 op2=2 op3=0 op4=0 op5=0/> > <CONSTANTS_BLOCK NumWords=5 BlockCodeSize=4> > - <SETTYPE abbrevid=4 op0=9/> > + <SETTYPE abbrevid=4 op0=7/> > <NULL/> > </CONSTANTS_BLOCK> > ... all the same ... > > So it pretty much seems that instantiating a constant struct with a > type which > is structurally identical to an existing named struct type creates a > new anonymous struct > which is for some reason not deemed to be identical to the named one. > > Any ideas why?Solved this. If someone is interested, http://pastie.org/5656833 should be self-explanatory. This is quite a non-obvious behavior, especially when LLVM is wrapped in bindings. -- WBR, Peter Zotov.
Reasonably Related Threads
- [LLVMdev] Global variable initializer type does not match global variable type
- [LLVMdev] patch to docs/BitCodeFormat.html
- [LLVMdev] instruction CE_GEP
- [LLVMdev] [PATCH / PROPOSAL] bitcode encoding that is ~15% smaller for large bitcode files...
- [LLVMdev] [PATCH / PROPOSAL] bitcode encoding that is ~15% smaller for large bitcode files...