LLVM: passing alloca as a function argument - llvm

I want an LLVM IR code equivalent to
double x = 4.93;
printf("hello world: %f", x);
In my LLVM IR code, I got from godbolt and after neating the code, it will become something like
%x = alloca double, align 8
store double 4.930000e+00, double* %x, align 8
%1 = load double, double* %x, align 8
%2 = call i32 (i8*, ...) #printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* #.str, i32 0, i32 0), double %1)
No error. No problem so far.
But to me, %1 look redundant. However, it looks like I cannot remove this medium. The following code
%x = alloca double, align 8
store double 4.930000e+00, double* %x, align 8
%2 = call i32 (i8*, ...) #printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* #.str, i32 0, i32 0), double %x)
leads to error
llvm-as-9: test.ll:26:113: error: '%x' defined with type 'double*' but expected 'double'
%2 = call i32 (i8*, ...) #printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* #.str, i32 0, i32 0), double %x)
^
Now I am wondering if what I'm doing to remove %1 is really possible?

The alloca instruction returns a pointer, so in your code %x is of double* type. You have to load from a double* to get a double.
In your case it should be possible to create a double constant with 4.930000e+00 value and use this value as printf argument directly.
The same effect can be achieved by running optimization passes on your first snippet.

Related

How to use CreateInBoundsGEP in cpp api of llvm to access the element of an array?

I am new to llvm programming, and I am trying to write cpp to generate llvm ir for a simple C code like this:
int a[10];
a[0] = 1;
I want to generate something like this to store 1 into a[0]
%3 = getelementptr inbounds [10 x i32], [10 x i32]* %2, i64 0, i64 0
store i32 1, i32* %3, align 16
And I tried CreateGEP: auto arrayPtr = builder.CreateInBoundsGEP(var, num); where var and
num are both of type llvm::Value*
but I only get
%1 = getelementptr inbounds [10 x i32], [10 x i32]* %0, i32 0
store i32 1, [10 x i32]* %1
I searched google for a long time and looked the llvm manual but still don't know what Cpp api to use and how to use it.
Really appreciate it if you can help!
Note that the 2nd argument to IRBuilder::CreateInBoundsGEP (1st overload) is actually ArrayRef<Value *>, which means it accepts an array of Value * values (including C-style array, std::vector<Value *> and std::array<Value *, LEN> and others).
To generate a GEP instruction with multiple (child) addresses, pass an array of Value * to the second argument:
Value *i32zero = ConstantInt::get(contexet, APInt(32, 0));
Value *indices[2] = {i32zero, i32zero};
builder.CreateInBoundsGEP(var, ArrayRef<Value *>(indices, 2));
Which will yield
%1 = getelementptr inbounds [10 x i32], [10 x i32]* %0, i32 0, i32 0
You can correctly identify that %1 is of type i32*, pointing to the first item in the array pointed to by %0.
LLVM documentation on GEP instruction: https://llvm.org/docs/GetElementPtr.html

llvm 3.9 ConstantExpr::getAsInstruction for Instruction::GetElementPtr get assertion

I migrated from LLVM 3.6.1 to LLVM 3.9.0. In LLVMv3.6 this code execute fine, but in LLVMv3.9 I have assertion failure:
... include/llvm/IR/Instructions.h:866: static llvm::GetElementPtrInst* llvm::GetElementPtrInst::Create(llvm::Type*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, const llvm::Twine&, llvm::Instruction*): Assertion `PointeeType == cast<PointerType>(Ptr->getType()->getScalarType())->getElementType()' failed.
My Code is:
pOperand = pStore->getValueOperand();
if(!pOperand)
return;
pConstExpr = dyn_cast<ConstantExpr>(pOperand);
if(!pConstExpr)
return;
if(pConstExpr->getOpcode() == Instruction::GetElementPtr)
{
pGEPInst = dyn_cast<GetElementPtrInst>(pConstExpr->getAsInstruction()); // Assertion !!!
if(!pGEPInst)
return;
... other code ...
}
EDIT:
This problem appears only when the build type of LLVM-3.9.0 is DEBUG. The RELEASE-build hasn't this problem!
I found where I had a problem. It is my own mistake. In instruction GetElementPtrInst of LLVM-3.9.0 appeared argument "Type *PointeeType", but LLVM-3.6.1 it argument wasn't, and that was the my error.
When in LLVM-3.6.1 I generate LLVM IR from source file, I got IR-line:
store i8* getelementptr inbounds ([14 x i8]* #.str1, i32 0, i32 0), i8** %2
in LLVM-3.9.0 this line:
store i8* getelementptr inbounds ([14 x i8], [14 x i8]* #.str1, i32 0, i32 0), i8** %2
After this in both versions I change global variable #.str1 to #globstr1, and replace it everywhere in module. In LLVM-3.6.1 this line transform to:
store i8* getelementptr inbounds ([17 x i8]* #globstr1, i32 0, i32 0), i8** %2
and worked fine, but in LLVM-3.9.0 this line transform to:
store i8* getelementptr inbounds ([14 x i8], [17 x i8]* #globstr1, i32 0, i32 0), i8** %2
the Type [14 x i8] not changed and in this place occurred assertion failure.
EDIT:
This problem appears only when the build with ASSERTS (parameter -DLLVM_ENABLE_ASSERTIONS=1 for CMAKE. This parametr default is ON for DEBUG build). In RELEASE-build it doesn't appear because parametr DLLVM_ENABLE_ASSERTIONS default is off (default for RELEASE build)!

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

How can you print instruction in llvm

From an llvm pass, I need to print an llvm instruction (Type llvm::Instruction) on the screen, just like as it appears in the llvm bitcode file. Actually my compilation is crashing, and does not reach the point where bitcode file is generated. So for debugging I want to print some instructions to know what is going wrong.
Assuming I is your instruction
I.print(errs());
By simply using the print method.
For a simple Hello World program, using C++'s range-based loops, you can do something like this:
for(auto& B: F){
for(auto& I: B){
errs() << I << "\n";
}
}
This gives the output:
%3 = alloca i32, align 4
%4 = alloca i8**, align 8
store i32 %0, i32* %3, align 4
store i8** %1, i8*** %4, align 8
%5 = call i32 (i8*, ...) #printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* #.str, i64 0, i64 0))
ret i32 0

Does ampersand of reference data type return the address of the reference itself or the value it is referencing?

I wish I could have tested it myself, but unfortunately it's impossible to do so in the current situation I'm in. Could anyone care to shed some light on this?
It returns the address of the value it is referencing.
Unlike a pointer, a reference isn't actually an object. It doesn't have an address itself, it's easier to think of it as an alias to an object that the compiler will then interpret.
Anyway, you can always test code online with IdeOne
#include <stdio.h>
void func(int &z)
{
printf("&z: %p", &z);
}
int main(int argc, char **argv)
{
int x = 0;
int &y = x;
printf("&x: %p\n", &x);
printf("&y: %p\n", &y);
func(x);
return 0;
}
Executed online, with results.
Address of the value.
(There is no such thing as address of reference)
You can always check on codepad : http://codepad.org/I1aBfWAQ
A further experiment: there are online compilers that allow inspection of intermediate results!
Taking Mahmoud's example on the Try out LLVM and Clang page, we get the following LLVM IR (truncated).
define i32 #main() nounwind uwtable {
%x = alloca i32, align 4
store i32 0, i32* %x, align 4, !tbaa !0
%1 = call i32 (i8*, ...)* #printf(i8* getelementptr inbounds ([8 x i8]* #.str, i64 0, i64 0), i32* %x)
%2 = call i32 (i8*, ...)* #printf(i8* getelementptr inbounds ([8 x i8]* #.str1, i64 0, i64 0), i32* %x)
%3 = call i32 (i8*, ...)* #printf(i8* getelementptr inbounds ([7 x i8]* #.str2, i64 0, i64 0), i32* %x) nounwind
ret i32 0
}
... the syntax is not too important, what is important is to note that a single variable has been declared: %x (whose name is suspiciously similar to that of the C function).
This means that the compiler has elided the y and z variable, no storage is ever allocated for them.
I will spare you the assembly listing ;)