I'm new to llvm and I'm writing a small llvm IR Builder.
I use the IRBuilder and all these Create* functions to generate my IR.
What I'm trying to do is to create a load instruction which create a new SSA local variable with value of a previously allocated llvm::Value.
What I expected to have :
%2 = load i32* %1
With %2 results of load instruction and %1 my previously allocated Value (CreateAlloca)
Here is what I tried :
// Get Ptr from Val
Value* ptr = ConstantExpr::getIntToPtr((Constant*)loc[n],PointerType::getUnqual(builder->getInt32Ty()));
// Générate load instruction with the new Ptr
builder->CreateLoad(ptr);
And here is what I have :
%2 = load i32* null
loc is an array which contains all my llvm::Value*
Can you please tell me what I'm doing wrong ? Or maybe if I'm on a bad way ?
Thanks.
ConstantExpr::getIntToPtr() creates a constant expression. So in effect, what you're trying to generate is equivalent to this IR:
%2 = load i32* inttoptr (i32 %1 to i32*)
But this is illegal since a constant expression, as hinted by its name, only supports constants, and %1 isn't a constant. ConstantExpr::getIntToPtr() requires a Constant as a first argument to verify it, but you passed it a non-constant value which was forcefully cast to a constant.
The correct way to convert a non-constant integer to a pointer is with IRBuilder::createIntToPtr. However, since you say the previous value (loc[n]) was created via an alloca then it's already a pointer, and you don't need to perform any conversion: just do builder->CreateLoad(loc[n]).
By the way, the proper way to cast a Value to a Constant in LLVM is not via a c-style cast but via cast<>, like so: cast<Constant>(loc[n]).
Related
Starting with the caleidoscope tutorial and a stack exchange question (question) I tried to output some array-creation and access code with LLVM. The idea is to have an "alloca" stack variable "a" which holds a double* pointing to an array allocated with malloc.
The generated code fails, and I believe that the main problem is my Call to "CreateInBoundsGEP" in C++.
So my main question in one sentence is "How to Call CreateInBoundsGEP so that it outputs the right IR code?"
What i tried is the following:
My allocation code is created as output of the llvm c++ interface's "CreateMalloc" call from the question referenced above.
%a = alloca double*, align 8
%malloccall = tail call i8* #malloc(i32 48)
%0 = bitcast i8* %malloccall to double*
store double* %0, double** %a, align 8
This code looks good to me, but it already leads to an error/warning when checked with verifyFunction().
Call parameter type does not match function signature!
i32 48
Sadly it does not tell me, what the right parameter type would be (i64?). The IR reference does not refer to the "malloc"-function call at all but mentions a "malloc" IR-operation instead (reference)!
My main problem (also leading to memory errors if not caught before) occurs with write access to the array.
My first try was copying (more or less) directly from the referenced stack exchange question 1:
//ret is the base adress of the pointer, ie "a"
//rhs is the Value* to the right hand side that is assigned
//index is the Value* to the array index
auto element_ptr = Builder->CreateInBoundsGEP(ret, index, "acc_tmp");
Builder->CreateStore(rhs, element_ptr);
Which outputs (for a[1]=5 as input code)
%acc_tmp = getelementptr inbounds double*, double** %a, i32 1
store double 5.000000e+00, double** %acc_tmp, align 8
This creates a "verifyFunction" error and I can see that "double**" should probably be "double*".
Since I also got a deprecation warning, I decided to try the CreateInBoundsGEP with a type parameter.
Since the documentation does not tell me whether "Type" should be the element or pointer type, I tried both
auto element_ptr = Builder->CreateInBoundsGEP(rhs->getType()->getPointerTo(), ret, index, "acc_tmp");
Or
auto element_ptr = Builder->CreateInBoundsGEP(rhs->getType(), ret, index, "acc_tmp");
Both do not work, the first version outputs the same code as without passing a type, the second version leads to
static llvm::GetElementPtrInst *llvm::GetElementPtrInst::Create(llvm::Type *, llvm::Value *, ArrayRef<llvm::Value *>, const llvm::Twine &, llvm::Instruction *): Assertion `cast<PointerType>(Ptr->getType()->getScalarType()) ->isOpaqueOrPointeeTypeMatches(PointeeType)' failed.
As I noticed in my original question, there is one pointer* too much in my instruction. Initially I did not understand why this is the case, but then I found the answer to my problem in a seemingly unrelated question 1:
If you directly use the return value of "CreateMalloc" as argument for a "CreateInBoundsGEP", the Code that I originally copied from 2 will work.
However in my case there is one more step involved: I store the "CreateMalloc" return value in a local variable, which in turn is referenced by a pointer allocated with "alloca". Because of this, I need one additional dereferencing step compared to the original Code Snippet to access my array elements.
As mentioned in 1 a dereference in LLVM-IR is just a "load". So a correct array access code looks like
//ret is the pointer to(!) the base adress of the array, ie "a"
//rhs is the Value* to the right hand side that is assigned
//index is the Value* holding the array index
llvm::Value* index = visit(ctx->index).as<llvm::Value*>();
llvm::Value* ret_deref = Builder->CreateLoad(llvm::Type::getDoubleTy(*TheContext)->getPointerTo(),ret,"deref_tmp");
auto element_ptr = Builder->CreateInBoundsGEP(rhs->getType(), ret_deref, index, "acc_tmp");
Builder->CreateStore(rhs, element_ptr);
I have a function that takes an array as argument and I need to get the size of the array first thing in the function. I need to do this in LLVM IR. Is this possible? I can access the array but I don't know the size.
void test(int[] a) {
}
is right now translating to
define void #test(i32* %__p__a) {
entry:
%a = alloca i32*, align 4
store i32* %__p__a , i32** %a, align 4
ret void
}
I need to get the size of the array first thing in the function. I need to do this in LLVM IR. Is this possible?
If all you have is an i32* with no additional information about what it points to, then no, it's not possible. In order to get an array's size, you'll need to store that information somewhere where the test function can access it.
Since this is your own language and you control what the generated LLVM IR looks like, you could for example represent arrays as structs that contain the array's size and a pointer to the data.
When using the store instruction in LLVM IR code, I found this in the document:
There are two arguments to the store instruction: a value to store and
an address at which to store it. The type of the operand
must be a pointer to the first class type of the operand.
But the truth is that if I pass a llvm value which type is not a pointer to the functionbuilder.CreateStore(constInt0, v1); (v1 is a 32bits integer type, not a pointer type), the builder didn't assert error, but generate the IR code:
store i32 0, i32 %1
while normally code for storage is more like:
store i32 0, i32* %1
But if I pass a not pointer type value to builder.CreateLoad(v1);, the builder will assert an error:
typename cast_retty<X, Y *>::ret_type llvm::cast(Y *) [X = llvm::PointerType, Y = llvm::Type]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
So why builder allowed me to pass a non-pointer value? And what will happen if the store i32 0, i32 %1 runs?
I'm trying to store the value of a global variable into a local variable in a function in my custom LLVM Pass.
the global variable is defined as
GlobalVariable* gvar_int32_test = new GlobalVariable(
/*Module=*/ M,
/*Type=*/ IntegerType::get(M.getContext(), 32),
/*isConstant=*/ false,
/*Linkage=*/ GlobalValue::CommonLinkage,
/*Initializer=*/0, // has initializer, specified below
/*Name=*/"global_test_var");
gvar_int32_test->setAlignment(4);
The local variable I intend to store into is originally being used as the store location for a call instruction. I attempt to get this value using
Value* localVar = ci->getOperand(0) //ci is the call instruction
using an IR builder, I attempt to write a store instruction as:
StoreInst* strLocIns = builder.CreateStore(gvar_int32_test, localVar, false);
//my intent is to create an instruction that means localvar = globalvar;
Similarly, earlier in the code I attempt to store the value in the return instruction of a called function to the global variable
Value* value = ri->getReturnValue(); //ri is the return instruction
// Some more code, including setting the IR builder insertion point
StoreInst* strIns = builder.CreateStore(value, gvar_int32_test, false);
//here the intention is globalvar = localvar
when I try to compile my with my pass included, I get the error:
Store operand must be a pointer.
store i32* #global_test_var, i32 %5
I'm not sure what I am doing wrong. Both of the arguments for the variables that I pass to the IR builder are pointers, but the IR is somehow broken. I think that i32 %5 should be i32* %5 to indicate that %5 points to an i32, but I don't know how to fix my code to make that happen. How do I fix this error?
Swap the operands of store: first is what and second - where.
I want to store data about each stack memory that is being allocated and changed.
To do so, I thought I'd need a data structure of some sort in which I can store the related data, such as the value of the local variable, and any change of it, e.g. before a store instruction.
Moreover, I should be able to check the value with the one saved in the data structure before any read of the local variable (e.g. load instruction).
If we assume that the IR looks like this
%1 = alloca i32,
[...]
%20 = store i32 0, %1
I need to change the above code to look like the below
%18 = call __Checking
%19 = <storing the return value from __Checking into a data structure>
%20 = store i32 0, %1
My problem is I cannot figure out how to store the returned value from the library called __Checking into a StructType I defined at the beginning.
My relevant code
if (StoreInst *SI = dyn_cast<StoreInst>(&I)){
Value* newValue = IRB.CreateCall(....);
Type* strTy[] = { Type::getInt64Ty(m.getContext()),
Type::getInt64Ty(m.getContext()) };
Type* t = StructType::create(strTy);
}
You didn't provide any specific information on the type returned by __Checking (or even where does __Checking come from) and the internals of the StructType, so I'm going to suggest to abstract that behaviour away in a runtime library (most likely in C).
This will allow you to setup function calls in those parts of the IR that you require to store (or compare, etc.) a value. The function(s) would take as arguments the value and the StructType (and anything else required) and perform the desired action in plain C (e.g. store the value).
For example, using part of your posted IR (names prefixed with myruntime_ should be defined in your runtime library):
%0 = alloca %myruntime_struct
[...]
%18 = call #__Checking
%19 = call #myruntime_storevalue(%2, %18, /* other arguments? */)
%20 = store i32 0, %1