For the following branch instruction
br i1 %cmp, label %if.then, label %if.end, !dbg !35
Since llvm is SSA, I can directly access the operand 0, to determine whether the comparison is true or not. The type evaluates to i1 but I am having trouble extracting the value (true or false)
BranchInst &I;
Value *val = I.getOperand(0);
Type yields to i1 type but when I tried to cast to
ConstantInt *cint = dyn_cast<ConstantInt>(val) the casting does not seem to work? how do I go about it
Answering my own question
BranchInst &I;
Module* module;
IRBuilder<> irbuilder(&I);
Value* value = irbuilder.CreateIntCast(I.getCondition(),
Type::getInt32Ty(module->getContext()), false);
This should convert i1 to i32.
You want a different kind of cast — cast<> casts within your code, while what you want is a cast within the generated code, CastInst. Boolean is a one-bit integer type, so what you want probably is a zero extension. CastInst::Create(CastInst::ZExt, I.getOperand(0), … should do.
Related
Suppose I have a pointer to some Value* val in LLVM. I want to get a pointer to Instruction that assigned value to the variable that val points to. How can I do it?
This is an example of code
%add = add nsw i32 %aa, %bb
%div = sdiv i32 %add, %cc
I have a pointer to variable add and I want to get a pointer to the Instruction that assigned to variable add, which is pointer to %add = add nsw i32 %aa, %bb instruction
So far the only thing I found was a pointer to Basicblock that the variable belongs to. This is how I did it
Instruction * tmpI = dyn_cast<Instruction>(val);
BasicBlock * b = tmpI->getParent();
The correct answer was provided in the comments by jmmartinez:
The LLVM-IR is a Static-Single-Assignment Intermediate Representation. The pointer to the instruction IS the pointer to the assignment. The add instruction and the assignment to the add register have a one-to-one matching since registers can only be assigned once, and instructions can only assign to a single register.
[...] In your code example. if the variable val points to the register %add. It happens that val points to an llvm::Instruction (which inherits from llvm::Value). And this instruction is the addition you're looking for.
To add a bit more detail, the LLVM Value type is a base class of the LLVM Instruction type. For IR values like %add in the example, the IR allocates a specific Instruction subtype, BinaryOperator in the case of an add instruction. So the pointer to a Value for %add is actually a pointer to the same object as the instruction, just using its base class.
LLVM also has a special system for casting these pointers between types in the IR type hierarchy: https://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates
Here are some example functions that take a specific llvm::Value and return the llvm::Instruction that produces that value:
#include <llvm/IR/Value.h>
#include <llvm/IR/Instruction.h>
using llvm::Value;
using llvm::Instruction;
using llvm::cast;
using llvm::dyn_cast;
using llvm::dyn_cast_or_null;
using llvm::isa;
// Either convert a `Value` to an `Instruction`
// or return null.
auto tryGetInstr(Value* value) -> Instruction* {
return dyn_cast<Instruction>(value);
}
// Just test whether a value was computed with an
// `Instruction` without converting it. Don't use
// this if you'll just end up converting it, use
// the above that combines the two.
auto isInstr(Value* value) -> Instruction* {
return isa<Instruction>(value);
}
// When you already know the value *must* be computed
// by an instruction, you can assert this and convert
// it in a way that will never produce a null.
auto getInstr(Value* value) -> Instruction* {
return cast<Instruction>(value);
}
// If `value` is non-null, try to convert it to an
// `Instruction`. Returns null if `value` is null
// or it isn't referencing an `Instruction`.
auto tryGetInstrIfNonNull(Value* value) -> Instruction* {
return dyn_cast_or_null<Instruction>(value);
}
https://cpp.compiler-explorer.com/z/f13bT4vb5
Problem
I am trying to create a vector type in LLVM (version 12) to exploit the SIMD feature associated with this type. However, the required size of the array is stored in an integer variable. The desired LLVM IR code could possibly look like,
;; Pseudo-code for the desired LLVM IR
%0 = load i64, i64* %a
%vec = alloca <%0 x double>, align 16
Generating such IR code seems to be impossible though.
It is possible to generate vector alloca with compile-time constants, e.g. a vector of size 4 could be generated as
%vec = alloca <4 x double>, align 16
using the LLVM C++ API as
llvm::Type* I = llvm::Type::getDoubleTy(TheContext);
auto arr_type = llvm::VectorType::get(I,4,false);
llvm::AllocaInst* arr_alloc = Builder.CreateAlloca(arr_type, 0 , "vec" );
however using a runtime constant obtained from a variable seems to be a problem, since the llvm::VectorType::get interface only allows the size to be specified as an unsigned int. I.e. the available interface looks like
static VectorType* llvm::VectorType::get ( Type * ElementType,
unsigned NumElements,
bool Scalable
)
However, if I load the variable value from %a and I cant create a vector type from it using,
llvm::Value *SIZE = Builder.CreateLoad(IntType,Address_Of_Variable_A,"a");
auto arr_type = llvm::VectorType::get(I,SIZE,false); // this line fails to compile (since SIZE is not an unsigned int)
I also could not typecast the Value* pointer to a llvm::ConstantInt* pointer to get the integer value back from the Value* as done in https://stackoverflow.com/a/5315581/2940917 .
This happens due to the fact that SIZE is in this case a LoadInst* as opposed to being created from a ConstantInt::get as done in the linked question.
Is there a way to achieve this? This seems like an essential operation for many cases. It would be surprising if there is no way to declare a vector size from the runtime constant.
Could someone point me to the right information source/idea?
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 have following instruction:
%ptrA = getelementptr float, float addrspace(1)* %A, i32 %id
I can get the operands %A and %id using getOperand(0) and getOperand(1). I was wondering if getOperand will work on %ptrA? If yes, would it be getOperand(3)?
------------------------------------Edit----------------------------
So I changed my code as follows:
for (Instruction &I : instructions(F)){
if (cast<Operator>(I).getOpcode() == Instruction::GetElementPtr){
Value* AddrPointer = cast<Value>(I);
I keep getting error:
error: cannot convert ‘llvm::Value’ to ‘llvm::Value*’ in initialization
Value* AddrPointer = cast<Value>(I);
^
I see that there is some problem with type mismatch.
Thank you.
Your question lacks quite a bit of context, but I will assume you're working with an llvm::Instruction * representing that particular getelementptr instruction. No, getOperand() will not allow you to access %ptrA. In general, getOperand() only allows access to the instruction's operands, or arguments, but not its return value. In IR, %ptrA is not so much an operand of the instruction like in traditional assembly, but can be thought of more like the return value of the instruction.
The syntax for what you're trying to do is actually very convenient. An llvm::Instruction object itself represents its own return value. In fact, llvm::Instruction is a derived class of llvm::Value. You can use llvm::cast, with llvm::Value as the template argument and the result will actually be an llvm::Value * which represents the return value of getelementptr.
llvm::Instruction * instruc;
//next line assumes instruc has your getelementptr instruction
llvm::Value * returnval = llvm::cast<llvm::Value>(instruc);
//returnval now contains the result of the instruction
//you could potentially create new instructions with IRBuilder using returnval as an argument, and %ptrA would actually be passed as an operand to those instructions
Furthermore, many of the functions that actually create instructions (the llvm::IRBuilder::Create* instructions, for instance) don't even return llvm::Instruction *s but rather llvm::Value *s. This is very convenient, because most of the time if you need to feed the return value of an instruction into another instruction, you can simply pass the return value of whatever Create function you called into the next Create function, without needing to do any casting.
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]).