I'm working with LLVM and I want to recreate a piece of IR with the API:
declare void @fun(i32* inreg, i32 inreg)
But I can't seem to get it to actually do it.
My current attempt is:
Function* fun = cast<Function>(M.getOrInsertFunction("fun",type));
((fun -> getAttributes()).getParamAttributes(0)).addAttribute(c,0,Attribute::InReg);
((fun -> getAttributes()).getParamAttributes(1)).addAttribute(c,0,Attribute::InReg);
This code literally doesn't do anything after line 1, lines 2 and 3 are completely ignored and all I get in the IR output is:
declare void @fun(i32* , i32 )
How do I get it to work correctly?
There are three problems with your code snippet.
First, the index of the first parameter is 1, not 0. So you should be using indices 1 and 2, not 0 and 1.
Second,
addAttribute()
does not modify its receiver, it instead returns a new set. So the proper way to change attributes would be to do:And finally, there's a shorthand for the above, which is just to do:
Managing function attributes in LLVM is quite inconvenient as attributes are packed into immutable and global sets. Assigning an attribute to a function argument actually means replacing the set representing all function and argument attributes with a new one.
Fortunately, there are at least helper functions that makes that job a bit easier. I suggest using
llvm::Function::addAttribute()
method.Keep in mind that index 0 represents function attributes, argument attributes starts from index 1.