Andrew Haley
2009-Jan-19 15:55 UTC
[LLVMdev] Load from abs address generated bad code on LLVM 2.4
This is x86_64. I have a problem where an absolute memory load define i32 @foo() { entry: %0 = load i32* inttoptr (i64 12704196 to i32*) ; <i32> [#uses=1] ret i32 %0 } generates incorrect code on LLVM 2.4: 0x7ffff6d54010: mov 0xc1d9c4(%rip),%eax # 0x7ffff79719da 0x7ffff6d54016: retq should be 0x7ffff6d54010: mov 0xc1d9c4, %eax 0x7ffff6d54016: retq i.e. the IP-relative addressing mode is incorrect. The current LLVM trunk does not have this bug. This seems quite a nasty bug; is there any chance of a bug-fix release for LLVM 2.4, or should I just use LLVM trunk until LLVM 2.5 ? Andrew. #include <llvm/Module.h> #include <llvm/Function.h> #include <llvm/PassManager.h> #include <llvm/CallingConv.h> #include <llvm/Analysis/Verifier.h> #include <llvm/Assembly/PrintModulePass.h> #include <llvm/Support/IRBuilder.h> #include <llvm/Support/Debug.h> #include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/ModuleProvider.h> #include <llvm/Assembly/PrintModulePass.h> #include <llvm/Support/raw_ostream.h> #include <stdio.h> using namespace llvm; Module *makeLLVMModule (); Function *foo; int main (int argc, char **argv) { Module *Mod = makeLLVMModule (); verifyModule (*Mod, PrintMessageAction); PassManager PM; PM.add (new PrintModulePass ()); PM.run (*Mod); ExecutionEngine *engine = ExecutionEngine ::create(Mod); // DebugFlag = true; // CurrentDebugType = "x86-emitter"; typedef int (*pf)(); pf F = (pf)engine->getPointerToFunction(foo); int res = F(); printf ("ret = %d\n", res); delete Mod; return 0; } int32_t p = 99; Module * makeLLVMModule () { // Module Construction Module *mod = new Module ("test"); Constant *c = mod->getOrInsertFunction ("foo", IntegerType::get(32), NULL); foo = cast <Function> (c); BasicBlock *block = BasicBlock::Create ("entry", foo); IRBuilder<> builder (block); Value *tmp = ConstantInt::get(Type::Int64Ty, (long)&p); tmp = builder.CreateIntToPtr(tmp, PointerType::getUnqual(IntegerType::get(32))); tmp = builder.CreateLoad(tmp); builder.CreateRet (tmp); return mod; }
Óscar Fuentes
2009-Jan-19 16:25 UTC
[LLVMdev] Load from abs address generated bad code on LLVM 2.4
Andrew Haley <aph at redhat.com> writes:> This is x86_64. I have a problem where an absolute memory load > > define i32 @foo() { > entry: > %0 = load i32* inttoptr (i64 12704196 to i32*) ; <i32> [#uses=1] > ret i32 %0 > } > > generates incorrect code on LLVM 2.4: > > 0x7ffff6d54010: mov 0xc1d9c4(%rip),%eax # 0x7ffff79719da > 0x7ffff6d54016: retq > > should be > > 0x7ffff6d54010: mov 0xc1d9c4, %eax > 0x7ffff6d54016: retq > > i.e. the IP-relative addressing mode is incorrect.This seems the same as http://www.llvm.org/bugs/show_bug.cgi?id=2920 which was fixed by an unknown change after the 2.4 release.> The current LLVM trunk does not have this bug. This seems quite a nasty > bug; is there any chance of a bug-fix release for LLVM 2.4, or should I > just use LLVM trunk until LLVM 2.5 ?As there ar not 2.x.y releases, your only option is to use LLVM trunk. -- Oscar
Óscar Fuentes
2009-Jan-19 16:40 UTC
[LLVMdev] Load from abs address generated bad code on LLVM 2.4
Andrew Haley <aph at redhat.com> writes:> This is x86_64. I have a problem where an absolute memory load > > define i32 @foo() { > entry: > %0 = load i32* inttoptr (i64 12704196 to i32*) ; <i32> [#uses=1] > ret i32 %0 > } > > generates incorrect code on LLVM 2.4: > > 0x7ffff6d54010: mov 0xc1d9c4(%rip),%eax # 0x7ffff79719da > 0x7ffff6d54016: retqIIRC, one workaround is to use a GlobalValue instead of a IntToPtr on a Constant. -- Oscar
Óscar Fuentes
2009-Jan-19 18:18 UTC
[LLVMdev] Load from abs address generated bad code on LLVM 2.4
Andrew Haley <aph at redhat.com> writes:> Óscar Fuentes wrote: >> The following message is a courtesy copy of an article >> that has been posted to gmane.comp.compilers.llvm.devel as well. >> >> Andrew Haley <aph at redhat.com> writes: >> >>> This is x86_64. I have a problem where an absolute memory load >>> >>> define i32 @foo() { >>> entry: >>> %0 = load i32* inttoptr (i64 12704196 to i32*) ; <i32> [#uses=1] >>> ret i32 %0 >>> } >>> >>> generates incorrect code on LLVM 2.4: >>> >>> 0x7ffff6d54010: mov 0xc1d9c4(%rip),%eax # 0x7ffff79719da >>> 0x7ffff6d54016: retq >> >> IIRC, one workaround is to use a GlobalValue instead of a IntToPtr on a >> Constant. > > Err, how? I can't figure out how to do it. The only documentation for > GlobalValue describes it as a superclass of GlobalVariables and Functions.IIRC, the stuff I used was something like... GlobalVariable *gv = new GlobalVariable( /* your pointer type */, other required parameters...); AddGlobalMapping(gv, your_pointer_value); // i.e. (void*)0x938742 then, where you use Constant* thp = ConstantExpr::getCast(Instruction::IntToPtr, your_pointer_value, /* i.e. 0x938742 */ /* your pointer type */); /* Now use thp */ change it to /* Now just use gv */ GetGlobalValueAtAddress may be useful for housekeeping. If something is wrong or not as effcient as it could be, I hope someone on the mailing list will correct me. -- Oscar
Chris Lattner
2009-Jan-19 18:46 UTC
[LLVMdev] Load from abs address generated bad code on LLVM 2.4
On Jan 19, 2009, at 7:55 AM, Andrew Haley wrote:> This is x86_64. I have a problem where an absolute memory load > The current LLVM trunk does not have this bug. This seems quite a > nasty > bug; is there any chance of a bug-fix release for LLVM 2.4, or > should I > just use LLVM trunk until LLVM 2.5 ?Hi Andrew, As others have pointed out, using a global and addglobalmapping is a great workaround for the problem. We generally don't do "dot" releases, since we have a short release cycle anyway. The 2.5 release process is slated to start this week. -Chris
Andrew Haley
2009-Jan-20 10:10 UTC
[LLVMdev] Load from abs address generated bad code on LLVM 2.4
Chris Lattner wrote:> On Jan 19, 2009, at 7:55 AM, Andrew Haley wrote: > >> This is x86_64. I have a problem where an absolute memory load >> The current LLVM trunk does not have this bug. This seems quite a >> nasty >> bug; is there any chance of a bug-fix release for LLVM 2.4, or >> should I >> just use LLVM trunk until LLVM 2.5 ? > > As others have pointed out, using a global and addglobalmapping is a > great workaround for the problem.Thanks.> We generally don't do "dot" releases, since we have a short release > cycle anyway. The 2.5 release process is slated to start this week.Mmm, but the problem is that interfaces keep changing, so simply upgrading to the latest release isn't possible. Even the tiny test case I posted doesn't work with the latest version: there were changes needed to get it to compile. Also, I can no longer figure out how to turn on debugging dumps in the JIT. The simple DebugFlag = true; CurrentDebugType = "x86-emitter"; no longer works, and there seems to be no replacement for it. Andrew.
Andrew Haley
2009-Jan-21 17:13 UTC
[LLVMdev] Load from abs address generated bad code on LLVM 2.4
Óscar Fuentes wrote:> Andrew Haley <aph at redhat.com> writes: > >> Óscar Fuentes wrote: >>> The following message is a courtesy copy of an article >>> that has been posted to gmane.comp.compilers.llvm.devel as well. >>> >>> Andrew Haley <aph at redhat.com> writes: >>> >>>> This is x86_64. I have a problem where an absolute memory load >>>> >>>> define i32 @foo() { >>>> entry: >>>> %0 = load i32* inttoptr (i64 12704196 to i32*) ; <i32> [#uses=1] >>>> ret i32 %0 >>>> } >>>> >>>> generates incorrect code on LLVM 2.4: >>>> >>>> 0x7ffff6d54010: mov 0xc1d9c4(%rip),%eax # 0x7ffff79719da >>>> 0x7ffff6d54016: retq >>> IIRC, one workaround is to use a GlobalValue instead of a IntToPtr on a >>> Constant. >> Err, how? I can't figure out how to do it. The only documentation for >> GlobalValue describes it as a superclass of GlobalVariables and Functions. > > IIRC, the stuff I used was something like... > > GlobalVariable *gv = new GlobalVariable( /* your pointer type */, > other required parameters...); > AddGlobalMapping(gv, your_pointer_value); // i.e. (void*)0x938742 > > then, where you use > > Constant* thp = ConstantExpr::getCast(Instruction::IntToPtr, > your_pointer_value, /* i.e. 0x938742 */ > /* your pointer type */); > > /* Now use thp */ > > change it to > > /* Now just use gv */ > > GetGlobalValueAtAddress may be useful for housekeeping.How does one use GetGlobalValueAtAddress? It returns a const GlobalValue *, but it seems that all the LLVM operations take a Value *. Any attempt to do anything with a const GlobalValue * is rejected by the C++ compiler. Perhaps I'm supposed to cast away the const? const GlobalValue *vv = engine->getGlobalValueAtAddress(&p); if (vv) { Value *tmp = builder.CreateLoad(vv); results in tut4.cpp:55: error: invalid conversion from 'const llvm::Value*' to 'llvm::Value*' tut4.cpp:55: error: initializing argument 1 of 'llvm::LoadInst* llvm::IRBuilder<preserveNames, T>::CreateLoad(llvm::Value*, const char*) [with bool preserveNames = true, T = llvm::ConstantFolder]' Andrew.
Maybe Matching Threads
- [LLVMdev] Load from abs address generated bad code on LLVM 2.4
- [LLVMdev] Load from abs address generated bad code on LLVM 2.4
- [LLVMdev] Load from abs address generated bad code on LLVM 2.4
- [LLVMdev] Load from abs address generated bad code on LLVM 2.4
- [LLVMdev] Load from abs address generated bad code on LLVM 2.4