[LLVMdev] Load from abs address generated bad code on LLVM 2.4

Andrew Haley aph at redhat.com
Mon Jan 19 07:55:04 PST 2009


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;
}



More information about the llvm-dev mailing list