[llvm-dev] [newbie] trouble with global variables and CreateLoad/Store in JIT

Nikodemus Siivola via llvm-dev
2017-06-04T20:39:34Z

Emitting calls to these functions (written in an .ll file linked in) works
fine, and does the right thing.

%Any = type { i8*, i32 }

define dllexport void @setGlobal(%Any* %ptr, %Any %value) {
  store %Any %value, %Any* %ptr
  ret void
}

define dllexport %Any @getGlobal(%Any* %ptr) {
  %val = load %Any, %Any* %ptr
  ret %Any %val
}

Trying to replace the setGlobal call with what should be equivalent

builder.CreateStore(value, ptr)

results in what should end up in the second (i32) slot being stored in the
first (i8*).

I've added ::dump() calls where the CreateStore is, and this is what I get:

{ i8*, i32 } { i8* @FixnumClass, i32 32 } ; for value
@foo = external global { i8*, i32 } ; for ptr

Even more bizarrely trying to replace the getGlobal call with

builder.CreateLoad(val)

results in what has been stored in the first (i8*) slot being loaded
correctly, but the second (i32) getting garbage out despite the correct
value being stored in memory. Dump call there reports the @foo pointer
identically.

This is using LLVM 4.0.0

Just so I'm not leaving anything out, what follows are IR dumps of the
sample functions using either the direct store / load, or the setGlobal
getGlobal
functions. As far as I can tell they should do exactly the same thing...

; Does NOT do the right thing
define { i8*, i32 } @"__anonToplevel/2"() {
entry:
  %.unpack = load i8*, i8** getelementptr inbounds ({ i8*, i32 }, { i8*,
i32 }* @foo, i32 0, i32 0), align 4
  %0 = insertvalue { i8*, i32 } undef, i8* %.unpack, 0
  %.unpack1 = load i32, i32* getelementptr inbounds ({ i8*, i32 }, { i8*,
i32 }* @foo, i32 0, i32 1), align 4
  %1 = insertvalue { i8*, i32 } %0, i32 %.unpack1, 1
  ret { i8*, i32 } %1
}

; Does NOT do the right thing
define { i8*, i32 } @"__anonToplevel/0"() {
entry:
  store i8* @FixnumClass, i8** getelementptr inbounds ({ i8*, i32 }, { i8*,
i32 }* @foo, i32 0, i32 0), align 4
  store i32 123, i32* getelementptr inbounds ({ i8*, i32 }, { i8*, i32 }*
@foo, i32 0, i32 1), align 4
  ret { i8*, i32 } { i8* @FixnumClass, i32 123 }
}

; DOES the right thing
define { i8*, i32 } @"__anonToplevel/0"() {
entry:
  call void @setGlobal({ i8*, i32 }* nonnull @foo, { i8*, i32 } { i8*
@FixnumClass, i32 123 })
  ret { i8*, i32 } { i8* @FixnumClass, i32 123 }
}

; DOES the right thing
define { i8*, i32 } @"__anonToplevel/1"() {
entry:
  %0 = call { i8*, i32 } @getGlobal({ i8*, i32 }* nonnull @foo)
  ret { i8*, i32 } %0
}

I'm at my wit's end. Any hints as to what I might be messing up would be
much appreciated. I expect it is something ridiculously obvious...

Cheers,

 -- nikodemus
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20170604/0f211052/attachment.html>