LLVM Comparing arguments of two functions - c++

Suppose I have:
foo(int a, int b){
bar(a)
}
how would I check if argument a in bar is the same as argument a in foo in the llvm IR(*.ll file) I get something this:
test.ll:
18 ; Function Attrs: nounwind uwtable
19 define i32 #foo(i32 %a, i32 %b) #0 {
20 entry:
21 %a.addr = alloca i32, align 4
22 %b.addr = alloca i32, align 4
23 %f = alloca i32, align 4
24 store i32 %a, i32* %a.addr, align 4
25 store i32 %b, i32* %b.addr, align 4
26 %0 = load i32, i32* %a.addr, align 4
27 %call = call i32 #baz(i32 %0)
28 store i32 %call, i32* %f, align 4
29 %1 = load i32, i32* %f, align 4
30 ret i32 %1
31 }
32

I am assuming that you are only asking if the same variable is passed on to bar or not.
to check that while running on function
runOnFunction(Function &F)
{
Function::ArgumentListType &sArgs = F.getArgumentList();
Function::ArgumentListType::iterator psArg = sArgs.begin();
Function::ArgumentListType::iterator psEndArg = sArgs.end();
/* this will iterate through function arguments */
for ( ;psArg != psEndArg; ++psArg)
{
/* iterate argument uses */
Argument::user_iterator psUSe = psArg->user_begin();
Argument::user_iterator psUSeEnd = psArg->user_end();
for (;psUSe != psUSeEnd ; ++psUSe)
{
/* check if it is call to bar or not */
if (CallInst* psCall = dyn_cast<CallInst>(*psUSe))
//if (const CallInst* psInst = dyn_cast<CallInst>(*psUSe))
{
if(psCall->getCalledFunction()->getName().startswith("bar")
{ // hurray found it, do something
}
}
}
}
}
above code will check if function argument is diractly passed to another function call.

Related

LLVM pointer as a function parameter

I am trying to pass a global variable to a function as a parameter and modify this variable inside of a function
i have IR code as follows
#n = common global i32 0
declare i32 #readln(i32)
declare i32 #writeln(i32)
define i32 #main() {
entry:
%n = load i32, i32* #n, align 4
%calltmp = call i32 #readln(i32 %n)
%n1 = load i32, i32* #n, align 4
%calltmp2 = call i32 #writeln(i32 %n1)
ret i32 0
}
readln defined in separate module as a C function
int readln(int * x) {
return scanf("%d", x);
}
upon running i get segmentation fault 11
What am I doing wrong ?
comment is correct. inspire by this
Builder.CreateLoad(Builder.CreateIntToPtr(Value,Type::getInt32PtrTy(TheContext)), "ptr");
Builder.CreateIntToPtr(Value,Type::getInt32PtrTy(TheContext));

LLVM IR: getting the value of an address

I'm trying to write a LLVM pass to analyse the following IR:
%d = alloca i32, align 4
store i32 0, i32* %d, align 4
%1 = load i32* %d, align 4
%2 = add nsw i32 %1, 2
store i32 %2, i32* %d, align 4
What I need to do is to figure out the final value of d.
For the store i32 0, i32* %d, align 4 I used ConstantInt casting for the operand 0 and found the assigned value for d (which is 0). But I'm struggling with how to find the value for the d in last store instruction:
store i32 %2, i32* %d, align 4
As I know, %2 is a pointer to the result of the instruction %2 = add nsw i32 %1, 2 and similar thing to the %1.
Do I need to backtrack for %2 to find the value of %2 or is there a simpler method for this?
EDIT:
Following is the code I used so far:
void analyse(BasicBlock* BB)
{
for (auto &I: *BB)
{
if (isa<StoreInst>(I))
{
Value *v = I.getOperand(0);
Instruction *i = dyn_cast<Instruction>(I.getOperand(1));
if (isa<ConstantInt>(v))
{
llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(v);
int value = CI->getZExtValue();
std::string ope = i->getName().str().c_str();
std::cout << "ope " << value << " \n";
}
}
}
}
Way to solve this is to back track. In this case:
store i32 %2, i32* %d, align 4
%2 = add nsw i32 %1, 2
%1 = load i32* %d, align 4
so it's checking the operand is an instruction, and if so, check the type of the instruction (i.e: isa(v), isa(v) or isa(v) etc), and then find the value.

how to see content of a method pointer?

typedef int (D::*fptr)(void);
fptr bfunc;
bfunc=&D::Bfunc;
cout<<(reinterpret_cast<unsigned long long>(bfunc)&0xffffffff00000000)<<endl;
complete code available at : https://ideone.com/wRVyTu
I am trying to use reinterpret_cast, but the compiler throws error
prog.cpp: In function 'int main()': prog.cpp:49:51: error: invalid cast from type 'fptr {aka int (D::*)()}' to type 'long long unsigned int' cout<<(reinterpret_cast<unsigned long long>(bfunc)&0xffffffff00000000)<<endl;
My questions are :
why is reinterpret_cast not suitable for this occasion?
Is there another way, I can see the contents of the method pointer?
Using clang++ to compile a slightly modified version of your code (removed all the cout to not get thousands of lines...), we get this for main:
define i32 #main() #0 {
entry:
%retval = alloca i32, align 4
%bfunc = alloca { i64, i64 }, align 8
%dfunc = alloca { i64, i64 }, align 8
store i32 0, i32* %retval, align 4
store { i64, i64 } { i64 1, i64 16 }, { i64, i64 }* %bfunc, align 8
store { i64, i64 } { i64 9, i64 0 }, { i64, i64 }* %dfunc, align 8
ret i32 0
}
Note that the bfunc and dfunc are two 64-bit integer values. If I compile for 32-bit x86 it is two i32 (so 32-bit integer values).
So, if we make main look like this:
int main() {
// your code goes here
typedef int (D::*fptr)(void);
fptr bfunc;
fptr dfunc;
bfunc=&D::Bfunc;
dfunc=&D::Dfunc;
D d;
(d.*bfunc)();
return 0;
}
the generated code looks like this:
; Function Attrs: norecurse uwtable
define i32 #main() #0 {
entry:
%retval = alloca i32, align 4
%bfunc = alloca { i64, i64 }, align 8
%dfunc = alloca { i64, i64 }, align 8
%d = alloca %class.D, align 8
store i32 0, i32* %retval, align 4
store { i64, i64 } { i64 1, i64 16 }, { i64, i64 }* %bfunc, align 8
store { i64, i64 } { i64 9, i64 0 }, { i64, i64 }* %dfunc, align 8
call void #_ZN1DC2Ev(%class.D* %d) #3
%0 = load { i64, i64 }, { i64, i64 }* %bfunc, align 8
%memptr.adj = extractvalue { i64, i64 } %0, 1
%1 = bitcast %class.D* %d to i8*
%2 = getelementptr inbounds i8, i8* %1, i64 %memptr.adj
%this.adjusted = bitcast i8* %2 to %class.D*
%memptr.ptr = extractvalue { i64, i64 } %0, 0
%3 = and i64 %memptr.ptr, 1
%memptr.isvirtual = icmp ne i64 %3, 0
br i1 %memptr.isvirtual, label %memptr.virtual, label %memptr.nonvirtual
memptr.virtual: ; preds = %entry
%4 = bitcast %class.D* %this.adjusted to i8**
%vtable = load i8*, i8** %4, align 8
%5 = sub i64 %memptr.ptr, 1
%6 = getelementptr i8, i8* %vtable, i64 %5
%7 = bitcast i8* %6 to i32 (%class.D*)**
%memptr.virtualfn = load i32 (%class.D*)*, i32 (%class.D*)** %7, align 8
br label %memptr.end
memptr.nonvirtual: ; preds = %entry
%memptr.nonvirtualfn = inttoptr i64 %memptr.ptr to i32 (%class.D*)*
br label %memptr.end
memptr.end: ; preds = %memptr.nonvirtual, %memptr.virtual
%8 = phi i32 (%class.D*)* [ %memptr.virtualfn, %memptr.virtual ], [ %memptr.nonvirtualfn, %memptr.nonvirtual ]
%call = call i32 %8(%class.D* %this.adjusted)
ret i32 0
}
This is not entirely trivial to follow, but in essense:
%memptr.adj = Read adjustment from bfunc[1]
%2 = %d[%memptr.adj]
cast %2 to D*
%memptr.ptr = bfunc[0]
if (%memptr.ptr & 1) goto is_virtual else goto is_non_virtual
is_virtual:
%memptr.virtual=vtable[%memptr.ptr-1]
goto common
is_non_virtual:
%memptr.non_virtual = %memptr.ptr
common:
if we came from
is_non_virtual: %8 = %memptr.non_virtual
is_virtual: %8 = %memptr.virutal
call %8
I skipped some type-casts and stuff to make it simpler.
NOTE This is NOT meant to say "this is how it is implemented always. It's one example of what the compiler MAY do. Different compilers will do this subtly differently. But if the function may or may not be virtual, the compiler first has to figure out which. [In the above example, I'm fairly sure we can turn on optimisation and get much better code, but it would presumably just figure out exactly what's going on and remove all of the code, which for understanding how it works is pointless]
There is a very simple answer to this. Pointers-to-methods are not 'normal' pointers and can not be cast to those, even through reinterpret_cast. One can cast first to void*, and than to the long long, but this is really ill-advised.
Remember, size of pointer-to-method is not neccessarily (and usually is not!) equal to the size of 'normal' pointer. The way most compilers implement pointer-to-method, it is twice the size of 'normal' pointer.
GCC is going to complain for the pointer-to-method to void* cast in pedantic mode, but will generate code still.

Create a LLVM function with a reference argument (e.g. double &x)

I want to create, from scratch, a new function in LLVM IR. The LLVM code should correspond to a C++ function with a reference argument, say
void foo(double &x){
x=0;
}
The tutorial such as http://llvm.org/releases/2.6/docs/tutorial/JITTutorial1.html is too old (llvm 2.6) and does not consider pass-by-reference function.
Any hint on how to do this? Thanks.
In LLVM, Reference types are typically implemented with pointer types. For the following C++ source code,
int foo(int & i) {
return i;
}
int bar(int *i) {
return *i;
}
void baz(int i) {
foo(i);
bar(&i);
}
The corresponding IR is:
; Function Attrs: nounwind
define i32 #_Z3fooRi(i32* dereferenceable(4) %i) #0 {
entry:
%i.addr = alloca i32*, align 8
store i32* %i, i32** %i.addr, align 8
%0 = load i32*, i32** %i.addr, align 8
%1 = load i32, i32* %0, align 4
ret i32 %1
}
; Function Attrs: nounwind
define i32 #_Z3barPi(i32* %i) #0 {
entry:
%i.addr = alloca i32*, align 8
store i32* %i, i32** %i.addr, align 8
%0 = load i32*, i32** %i.addr, align 8
%1 = load i32, i32* %0, align 4
ret i32 %1
}
; Function Attrs: nounwind
define void #_Z3bazi(i32 %i) #0 {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
%call = call i32 #_Z3fooRi(i32* dereferenceable(4) %i.addr)
%call1 = call i32 #_Z3barPi(i32* %i.addr)
ret void
}
You can find that there is no essential difference for i between functions foo and bar: dereferenceable is just a parameter attribute that you can add yourself during the code generation from the frontend.

How the pre and post increment work in c++? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
i want to know if increment/decrement operator results vary from compiler to compiler or it is independent of the compiler. as I am getting different results in different compilers of c/c++ (tested in G++, TDM, gcc) for the same expression.
Let's look at the internal llvm assembly. Which isn't hard to do.
C++ code:
void preincrement() __attribute__((noinline));
void preincrement() {
volatile int x = 10;
volatile int y = ++x;
}
void postincrement() __attribute__((noinline));
void postincrement() {
volatile int x = 10;
volatile int y = x++;
}
int main()
{
preincrement();
postincrement();
}
Resultant LLVM Assembly (minus some leading and trailing text that isn't interesting):
; Function Attrs: noinline nounwind uwtable
define void #_Z12preincrementv() #0 {
%x = alloca i32, align 4
%y = alloca i32, align 4
store volatile i32 10, i32* %x, align 4
%1 = load volatile i32* %x, align 4
%2 = add nsw i32 %1, 1
store volatile i32 %2, i32* %x, align 4
store volatile i32 %2, i32* %y, align 4
ret void
}
; Function Attrs: noinline nounwind uwtable
define void #_Z13postincrementv() #0 {
%x = alloca i32, align 4
%y = alloca i32, align 4
store volatile i32 10, i32* %x, align 4
%1 = load volatile i32* %x, align 4
%2 = add nsw i32 %1, 1
store volatile i32 %2, i32* %x, align 4
store volatile i32 %1, i32* %y, align 4
ret void
}
; Function Attrs: nounwind uwtable
define i32 #main() #1 {
tail call void #_Z12preincrementv()
tail call void #_Z13postincrementv()
ret i32 0
}
We can see here pretty clearly the only difference: In the post increment version, we use the original value, instead of the upgraded value.
In both cases, we just use a traditional add opcode to do the real work.