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

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

Related

LLVM: passing alloca as a function argument

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.

LLVM generates unefficient IR

I playing with LLVM and tried to compile simple C++ code using it
#include <stdio.h>
#include <stdlib.h>
int main()
{
int test = rand();
if (test % 2)
test += 522;
else
test *= 333;
printf("test %d\n", test);
}
Especially to test how LLVM treats code branches
Result I got is very strange, it gives valid result on execution, but looks unefficient
; Function Attrs: nounwind
define i32 #main() local_unnamed_addr #0 {
%1 = tail call i32 #rand() #3
%2 = and i32 %1, 1
%3 = icmp eq i32 %2, 0
%4 = add nsw i32 %1, 522
%5 = mul nsw i32 %1, 333
%6 = select i1 %3, i32 %5, i32 %4
%7 = tail call i32 (i8*, ...) #printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* #.str, i64 0, i64 0), i32 %6)
ret i32 0
}
It looks like it executing both ways even if only one is needen
My question is: Should not LLVM in this case generate labels and why?
Thank you
P.S. I'm using http://ellcc.org/demo/index.cgi for this test
Branches can be expensive, so generating code without branches at the cost of one unnecessary add or mul instruction, will usually work out to be faster in practice.
If you make the branches of your if longer, you'll see that it'll eventually become a proper branch instead of a select.
The compiler tends to have a good understanding of which option is faster in which case, so I'd trust it unless you have specific benchmarks that show the version with select to be slower than a version that branches.

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