4

I'm having some problems when loading values. Here's a simple example of the IR that my compiler generates to show the problem:

define i32 @main() {

    entry:  
    %a = alloca i32          ; <i32*> [#uses=2]  
    store i32 1, i32* %a  
    %r = load i32* %a        ; <i32> [#uses=1]

    br label %Return

    Return:                  ; preds = %entry  
    ret i32 %r

}

but instead of return 1 it returns 16777216. I have tested the program with different values and it seems that it's a matter of internal binary representation of integer values.

Edited: I show you the trace of calls to llvm that my compiler makes to generate the code above. bloques.back().last is of type Value* and bloques.back().bl is BasicBlock* (the current Block)

bloques.back().last = dyn_cast<Value>(ConstantInt::get(
    Type::getInt32Ty(getGlobalContext()), $1, true)); // $1 is an int
AllocaInst *alloc = new AllocaInst(
    Type::getInt32Ty(getGlobalContext()), izq.c_str(), bloques.back().bl);
Value *derecha = bloques.back().last;
StoreInst *s = new StoreInst(derecha, alloc, false, bloques.back().bl);
bloques.back().last = alloc;
LoadInst* v1 = new LoadInst(bloques.back().last, "r", false, bloques.back().bl);
bloques.back().last = v1;
BasicBlock* blockReturn = BasicBlock::Create(getGlobalContext(), "Return", Main);
Value* last = bloques.back().last;
BranchInst::Create(blockReturn, bloques.back().bl);
ReturnInst::Create(getGlobalContext(), last, blockReturn);

The source code corresponding to the IR representation would be:

a = 1
return a

Edit2: In my main function after generate the code and before start the execution via JIT I do this:

ExecutionEngine *EE = EngineBuilder(M).create();
string str = EE->getTargetData()->getStringRepresentation();
str[0] = 'e';
M->setDataLayout(str);

if (verifyModule(*M)) {
   errs() << argv[0] << ": Error building the function!\n";
   return 1;
}

vector<GenericValue> noargs;
GenericValue GV = EE->runFunction(Main, noargs);

outs() << "Result: " << GV.IntVal << "\n";
return 0;

Solved: finally i've found the solution. To change the endianness I do the following (a little spaguetti but it works):

Module *M = new Module("pythoncode", getGlobalContext());
ExecutionEngine *EE2 = EngineBuilder(M).create();
string str = EE2->getTargetData()->getStringRepresentation();
str[0] = 'e';
cout << str << endl;
M->setDataLayout(str);
ExecutionEngine *EE = EngineBuilder(M).create();

Thanks in advance.

Santos Merino.

betabandido
  • 18,946
  • 11
  • 62
  • 76
  • I'm not sure I understand; is the above code that you've written, or code that your compiler has generated? If it's compiled, why not just show us the original source? – Oliver Charlesworth May 27 '12 at 11:17
  • Ok, but do you know where the problem could be?, because the code it's quite spaguetti and if you tell me what could be the problem I'll show you only the relevant part of my code. – Engineer 007 May 27 '12 at 11:26
  • 1
    You should construct a [minimal test-case](http://sscce.org) that demonstrates the problem (i.e. a 10-line C++ program that gives unexpected output). – Oliver Charlesworth May 27 '12 at 11:31
  • @OliCharlesworth I believe the code he posted is a minimal test-case. You can write IR directly if you feel like it. I'm not sure his test can become any more simple. I believe the problem is a scoping issue. But I only know as much as I just searched about LLVM. – Andrew T Finnell May 27 '12 at 11:56
  • @AndrewFinnell: I realise that, but it's not clear what the problem is. Is the OP saying that the above code behaves unexpectedly, or that the compiler has mistakenly generated the above code? It sounds like the latter, in which case a source-code snippet would be appropriate. – Oliver Charlesworth May 27 '12 at 11:57
  • @OliCharlesworth Ah.. Yes I do see what you are saying. – Andrew T Finnell May 27 '12 at 12:01
  • @AndrewFinnell: it can definitely be simpler: the branch is unnecessary. A simple `ret i32 1` would suffice, etc... However spotting the bug is not necessarily easy. – Matthieu M. May 27 '12 at 12:01
  • @MatthieuM. Indeed it could do `ret i32 1` but would that exhibit the unexpected behavior he is seeing? I suppose that is part of the issue here: understanding what it is that he's asking. – Andrew T Finnell May 27 '12 at 12:02
  • @AndrewFinnell: I agree, the question is quite unclear. Given the branch names (`Return`) I suspect that the OP created her own compiler (clang generates only lower-case branch names). – Matthieu M. May 27 '12 at 12:06
  • @SantosMerino: That's not a minimal test-case. A minimal test-case is a short self-contained program that we could compile, run, and observe the problem... – Oliver Charlesworth May 27 '12 at 18:02
  • I have found that the problem is the endianness of Values, when I enter a 1 it represents it as 00000001 00000000 0000000 0000000 so how can I change the endianness? – Engineer 007 May 28 '12 at 04:12
  • @SantosMerino: are you setting the data layout string properly? What's you host/target arch? – Anton Korobeynikov May 28 '12 at 07:32
  • @AntonKorobeynikov I have edited my original message with what I do to configure the data layout. – Engineer 007 May 28 '12 at 09:15
  • @SantosMerino, you code looks bogus - why are you changing the endiannes? – Anton Korobeynikov May 28 '12 at 10:32
  • @AntonKorobeynikov Because as I said, it was getting the values with the wrong endianness, that's why the 1 became a 16777216. So to avoid this problem I changed the endianness of the main module. – Engineer 007 May 28 '12 at 10:48
  • @SantosMerino, this is not the proper fix. The problem should be somewhere else given that you have to *fix* the endiannes. Are you generating the module with bogus data layout string from the beginning? – Anton Korobeynikov May 28 '12 at 12:26
  • @AntonKorobeynikov no, the first step to build the module is the one i show you in the message – Engineer 007 May 28 '12 at 13:11
  • 1
    @SantosMerino, ah, ok. Then your module does not contain data layout at all :) And "no data layout" means actually big-endian in llvm world. So, you should put the valid string (if you care about interoperability with external code, surely). – Anton Korobeynikov May 28 '12 at 13:39

0 Answers0