I am trying to generate LLVM bitcode to store integer value into an integer array m.
At this point, I can generate bitcode for int global m
#m = common global <6 x i32>
Inside of function (foo) translation, I am trying to produce bitcode that reads the value stored in this vector, where the index is one from the first integer argument.
Value *m = TheModule->getGlobalVariable("m");
Value *offset = fooFunc->arg_begin();
Value *gep = Builder.CreateGEP(m,offset);
gep->dump();
Well, the output from the gep->dump() is simply #m = common global <6 x i32>. It seems that I am not using CreatGEP correctly. Can anyone advise me how to correctly produce the bitcode?
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?
If an integer is uneven (odd), I would like to get the previous number, otherwise I would like to keep the current number. E.g. if x = 3, I would like to assign 2 to x, if x = 4, then nothing happens.
At the moment, I do the following: x = (x/2)*2, but I have heard that division is computational expensive. Does -O3 optimize this expression? I am using the c++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 compiler. x is a uint32_t.
Try the following
x &= ~1;
I suppose that x is declared as having type int. Otherwise if the rank of type x is greater than the rank of type int then you should use an integer literal of the type of the variable x.
I have the following c++ code :
#include <OAIdl.h> // for VARIANT, BSTR etc
__declspec(dllexport) void __stdcall updatevar(VARIANT * x)
{
double nb = 3.0;
++nb;
}
with a function doing (almost) nothing (to avoid warnings)
and a .def file :
LIBRARY tmp0
EXPORTS
updatevar #1LIBRARY
I compile this with visual studio 2013 into a dll that I reference as follows in excel-2013's VBA :
Declare Sub updatevar Lib "C:\path\to\thedll.dll" (ByRef x As Variant)
and that I use like this :
Public Sub DoIt()
Dim r As Range
Set r = ActiveWorkbook.Sheets("Sheet1").Range("B2:C4")
Dim var As Variant
var = r.Value
Call updatevar(var)
End Sub
where the 6-cells excel range B2:C4 contains strings, dates, doubles and ints/longs.
I put a breakpoint in c++ code to inspect the variant pointed to that I receive, as remarked that the type of its 6 elements is always rightly resolved : dates go to a vt (variant type VT_DATE) equal to 7, doubles to a vt (variant type VT_R8) equal to 5, strings go to a vt (variant type VT_BSTR) of 8, except for ints/longs, that are mapped to VT_R8 and treated as doubles.
At the beginning I thought it was a c++ problem but, already inspecting the range r in the VBA code, and its Value2 field, showed to me that all ints/longs were treated in VBA as Variant/Double and not Variant/Long, and I have no idea why this is happening.
Note. I put c++ and dll tags as the people interested in these tags may also help given the context involving exchanging VARIANT's between c++ and VBA.
Remark. "Downcasting" from double to int is not an option, especially as VARIANT is supposed to know about ints/longs (VT_I4 = 2 and VT_I4 = 3 do exist.)
When building the IR from an existing AST, my AST has some string values (at compile-time they are built from std::string) and I want to set them safely as llvm::Value to use as a part of an expression.
In this case, I don't need to bind the string at run-time, because string values are only meant to resolve stuff as variables, functions or classes at compile-time (the language doesn't support a native string type).
Whats the best way to keep my string content as llvm::Value and still be able to retrieve it at later stages of compilation (when the nesting expressions are built)?
More concretely, if I set the llvm::Value with:
llvm::Value* v = llvm::ConstantArray::get(llvmContext, myString.c_str());
How do I safely retrieve the string value? Is llvm::ConstantArray the appropriate way to wrap strings?
Yes, ConstantArray is what you should use here. In order to retrieve the value later just use ConstantArray::getAsCString(). If you have assertions turned on, it will assert if something will went wrong (e.g. you will try to grab string from the array w/o zero terminator).
Running http://llvm.org/demo/ on the C code char *x = "asdf"; gives:
#.str = private unnamed_addr constant [5 x i8] c"asdf\00"
#x = global i8* getelementptr inbounds ([5 x i8]* #.str, i64 0, i64 0), align 8
Basically, to get the address of a string, you have to build a global containing it. You can switch http://llvm.org/demo/ to output C++ API calls if you have trouble figuring out how to do that.