Ragnar1349
Ragnar1349

Reputation: 61

Get pointer to first element of array in LLVM-IR

I want to implement a string type in LLVM-IR, and my plan is as follows:

When a string variable is declared, allocate memory for a i8*.

When the variable is initialized, store the string somewhere, store the pointer to the first element at the formerly allocated address, and save the length of the string in a member variable.

The problem is, that I can't get the pointer to the first element. Using the IRBuilder (C++ API), I have yet created the following code:

  %str2 = alloca i8*
  %1 = alloca [4 x i8]
  store [4 x i8] c"foo\00", [4 x i8]* %1
  %2 = getelementptr [4 x i8], [4 x i8]* %1, i32 0
  store [4 x i8]* %2, i8** %str2

But calling llc on this gives the following error:

error: stored value and pointer type do not match
  store [4 x i8]* %2, i8** %str2
        ^

When using clang to emit llvm-ir on the same (char* instead of string) code, it emits the following:

%str2 = alloca i8*, align 8
store i8* %str, i8** %1, align 8
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8** %str2, align 8

Which looks very similar imho, but is not the same.

Clang makes the string a global constant (which is hopefully not necessary), uses the offset parameter of getelementptr and gives the type i8* to the store instruction.

Unfortunately I wasn't able to find any API Methods to explicitly give a type to the store instruction, or use the offset parameter (which wouldn't even help, I guess).

So finally my question is: How can I properly get a pointer to the first array element and store it?

Thanks in advance

Upvotes: 4

Views: 4363

Answers (1)

Ragnar1349
Ragnar1349

Reputation: 61

As in the link in the comment, the solution is to bitcast the [n x i8]* to an i8*

%str2 = alloca i8*
%1 = alloca [4 x i8]
store [4 x i8] c"foo\00", [4 x i8]* %1
%2 = bitcast [4 x i8]* %1 to i8*
store i8* %2, i8** %str2

Upvotes: 2

Related Questions