   LLVM and the getelementptr instruction
  I'm writing a compiler for a small C-like language using LLVM as a backend. I just started implementing structs and pointers to them, but I've run into a problem.I have the following program:struct Node {  list next;  int val;  double d;};typedef struct Node *list;int main() {  list l = new Node;  l->next = l;  printPtr l->next;  printPtr l->next->next;  return 0;}Nothing fancy going on; I'm just assigning the list's next member and then printing the addresses of l->next and l->next->next.Since the list is infinite after the assignment, they should be the same, and they are, as long as the next member is the first member of the struct. Otherwise, they aren't; in fact, they cause segfaults and other random memory fun, so I'm apparently dereferencing a garbage pointer somewhere.It generates the following LLVM code. I think you can disregard the cNode function; it's just a constructor, and the problem doesn't go away if I replace it with a malloc and nothing more. I'm mallocing quite a bit of memory, since all pointer and integer types are assumed to be 64-bits.declare void @_printInt(i32)declare void @_printDouble(double)declare void @_printString(i8*)declare i32 @_readInt()declare double @_readDouble()declare i8* @malloc(i32)declare void @free(i8*)%Node = type {%list,i32,double}%list = type %Node*define %Node* @cNode() {  br label %lbl0_0lbl0_0:  %r0 = call i8* @malloc(i32 8)  %r1 = bitcast i8* %r0 to %Node*  %r2 = getelementptr %Node* %r1, i32 0, i32 0  store %list null, %list* %r2  %r3 = getelementptr %Node* %r1, i32 0, i32 1  store i32 0, i32* %r3  %r4 = getelementptr %Node* %r1, i32 0, i32 2  store double 0.0, double* %r4  ret %Node* %r1  unreachable}define i32 @_main() {  br label %lbl0_0lbl0_0:  %r0 = call %Node* @cNode()  %r1 = alloca %Node*  store %Node* %r0, %Node** %r1  br label %lbl0_1  lbl0_1:  %r2 = load %Node** %r1  %r3 = load %Node** %r1  %r4 = getelementptr %Node* %r3, i32 0, i32 0  store %Node* %r2, %Node** %r4  br label %lbl0_2lbl0_2:  %r5 = load %Node** %r1  %r6 = getelementptr %Node* %r5, i32 0, i32 0  %r7 = load %Node** %r6  %r8 = ptrtoint %Node* %r7 to i32  call void @_printInt(i32 %r8)  br label %lbl0_3lbl0_3:  %r10 = load %Node** %r1  %r11 = getelementptr %Node* %r10, i32 0, i32 0  %r12 = load %Node** %r11  %r13 = getelementptr %Node* %r12, i32 0, i32 0  %r14 = load %Node** %r13  %r15 = ptrtoint %Node* %r14 to i32  call void @_printInt(i32 %r15)  br label %lbl0_4lbl0_4:  %r17 = alloca i32  store i32 0, i32* %r17  %r18 = load i32* %r17  ret i32 %r18  br label %lbl0_5lbl0_5:  unreachable}define i32 @main() {  br label %lbl0_0lbl0_0:  %r0 = call i32 @_main()  ret i32 %r0  unreachable}This is the diff of the LLVM code produced by changing the bad version into the good version; note that in the good version, the only difference, sans the constructor, is the last index of the getelementptr instructions; since next is first in the good version, the last index is 0, and in the bad version, its index is 2 since it's the third member of the struct.--- test3.ll.bad2010-05-18 02:43:54.150878813 +0200+++ test3.ll2010-05-18 03:00:33.370843683 +0200@@ -6,7 +6,7 @@ declare i8* @malloc(i32) declare void @free(i8*) -%Node = type {i32,double,%list}+%Node = type {%list,i32,double} %list = type %Node* define %Node* @cNode() { br label %lbl0_0@@ -14,11 +14,11 @@ %r0 = call i8* @malloc(i32 8) %r1 = bitcast i8* %r0 to %Node* %r2 = getelementptr %Node* %r1, i32 0, i32 0-store i32 0, i32* %r2+store %list null, %list* %r2 %r3 = getelementptr %Node* %r1, i32 0, i32 1-store double 0.0, double* %r3+store i32 0, i32* %r3 %r4 = getelementptr %Node* %r1, i32 0, i32 2-store %list null, %list* %r4+store double 0.0, double* %r4 ret %Node* %r1 unreachable }@@ -32,21 +32,21 @@ lbl0_1: %r2 = load %Node** %r1 %r3 = load %Node** %r1-%r4 = getelementptr %Node* %r3, i32 0, i32 2+%r4 = getelementptr %Node* %r3, i32 0, i32 0 store %Node* %r2, %Node** %r4 br label %lbl0_2 lbl0_2: %r5 = load %Node** %r1-%r6 = getelementptr %Node* %r5, i32 0, i32 2+%r6 = getelementptr %Node* %r5, i32 0, i32 0 %r7 = load %Node** %r6 %r8 = ptrtoint %Node* %r7 to i32 call void @_printInt(i32 %r8) br label %lbl0_3 lbl0_3: %r10 = load %Node** %r1-%r11 = getelementptr %Node* %r10, i32 0, i32 2+%r11 = getelementptr %Node* %r10, i32 0, i32 0 %r12 = load %Node** %r11-%r13 = getelementptr %Node* %r12, i32 0, i32 2+%r13 = getelementptr %Node* %r12, i32 0, i32 0 %r14 = load %Node** %r13 %r15 = ptrtoint %Node* %r14 to i32 call void @_printInt(i32 %r15)I think I'm misunderstanding something about the getelementptr instruction, but I'm completely at a loss for how. I've asked in the LLVM IRC channel, read the docs 10-15 times, including the FAQ about getelementptr and googled it, but the solution still escapes me.Is anyone here familiar enough with LLVM to tell me what I'm doing wrong? :(   
  For starters, you are not posting the "good" code version, nor explaining what getelementptr instructions you were expecting.   ;Quote:Original post by LorenzoGattiFor starters, you are not posting the "good" code version, nor explaining what getelementptr instructions you were expecting.The expected result is that the two pointers l->next and l->next->next get printed. Since l->next = l, they should be the same. The generated instructions are exactly what was expected, which is why I suspected that I was using it improperly.I did find out however, that I'm using getelementptr correctly, and that instead LLVM is doing something funny with data layout on my system. For some reason, getelementptr treated both i32 and pointers like 64 bit values, not 32 bit as it should have (on my 32 bit system.) This was solved by putting the following declaration at the top of the generated code:target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"However, I'm interested to know if there is a less "dumping random unreadable strings into your code"-ish way to solve this; if it's possible to tell LLVM that pointers and i32 are indeed 32 bits by, say, telling it something like "use the normal i386 data layout." I've tried setting both the target architecture and target triple, but it doesn't alleviate the problem. Any other way to do this, or could this be a problem with Debian's (which is what I'm using) LLVM packaging?The good code is what's posted. The bad code looks as follows. As you can see, the generated code is identical except for the getelementptr indices and ordering of initializations in the constructor.Source language:struct Node {  int val;  double d;  list next;};typedef struct Node *list;int main() {  list l = new Node;  l->next = l;  printPtr l->next;  printPtr l->next->next;  return 0;}Target language:declare void @_printInt(i32)declare void @_printDouble(double)declare void @_printString(i8*)declare i32 @_readInt()declare double @_readDouble()declare i8* @malloc(i32)declare void @free(i8*)%Node = type {i32,double,%list}%list = type %Node*define %Node* @cNode() {  br label %lbl0_0lbl0_0:  %r0 = call i8* @malloc(i32 8)  %r1 = bitcast i8* %r0 to %Node*  %r2 = getelementptr %Node* %r1, i32 0, i32 0  store i32 0, i32* %r2  %r3 = getelementptr %Node* %r1, i32 0, i32 1  store double 0.0, double* %r3  %r4 = getelementptr %Node* %r1, i32 0, i32 2  store %list null, %list* %r4  ret %Node* %r1  unreachable}define i32 @_main() {br label %lbl0_0lbl0_0:  %r0 = call %Node* @cNode()  %r1 = alloca %Node*  store %Node* %r0, %Node** %r1  br label %lbl0_1lbl0_1:  %r2 = load %Node** %r1  %r3 = load %Node** %r1  %r4 = getelementptr %Node* %r3, i32 0, i32 2  store %Node* %r2, %Node** %r4  br label %lbl0_2lbl0_2:  %r5 = load %Node** %r1  %r6 = getelementptr %Node* %r5, i32 0, i32 2  %r7 = load %Node** %r6  %r8 = ptrtoint %Node* %r7 to i32  call void @_printInt(i32 %r8)  br label %lbl0_3lbl0_3:  %r10 = load %Node** %r1  %r11 = getelementptr %Node* %r10, i32 0, i32 2  %r12 = load %Node** %r11  %r13 = getelementptr %Node* %r12, i32 0, i32 2  %r14 = load %Node** %r13  %r15 = ptrtoint %Node* %r14 to i32  call void @_printInt(i32 %r15)  br label %lbl0_4lbl0_4:  %r17 = alloca i32  store i32 0, i32* %r17  %r18 = load i32* %r17  ret i32 %r18  br label %lbl0_5lbl0_5:  unreachable}define i32 @main() {  br label %lbl0_0lbl0_0:  %r0 = call i32 @_main()  ret i32 %r0  unreachable};  I don't see anything wrong with your IR. I would suspect a bug or misconfiguration somewhere if the machine code generated from that is wrong. Are you generating code or interpreting it? If one you might try the other.   