[LLVMdev] Troubling promotion of return value to Integer ...

Chris Lattner sabre at nondot.org
Tue May 27 22:11:02 PDT 2008


On May 27, 2008, at 3:33 PM, <Alireza.Moshtaghi at microchip.com> <Alireza.Moshtaghi at microchip.com 
 > wrote:
> Chris,
> I see, so in deed the front-end sets the attributes on the declaration
> of the called function; which in theory is also available to the  
> caller
> through the CALL node.

Right.

> Now here is what I think:
> I agree that 4 attributes are a bit ugly. I think we can only get away
> with 2 attributes to signify sign extension or zero extension.
> Currently the front end does not promote the function declaration; I
> hope we don't change this...
> The length of extension can be inferred from the CALL SDNode by
> following the links all the way to the definition of callee in  
> Function
> class.

In many cases that is true, but for indirect calls (calls through a  
function pointer) it isn't.

> All that is needed is to add some kind of sign attribute to the
> definition of callee function which will be set by the front-end and
> eventually saved in Function class.

Sure.  Adding an attribute is what we need to do.  To handle the  
indirect call case, llvm puts attributes both on the function  
definitions and on the calls to those functions.

> Two llvm methods (probably in
> SelectionDAG class) would be responsible for retrieving this
> information. We pass to them the SDNode of CALL to callee. Knowing the
> ABI/ calling convention, these two methods can infer the size and sign
> extension information from function definition information.
> So:
>
> signed char g(...);
> void foo(){
> 	x = g(...);
> }
>
> Would translate to:
>
> define void @foo(){
> Entry:
> 	%call = call i32 @g(...)
> 	...
> }
> declare signed i8 @g(...)

Ok.  We already have this, with the 'signext' attribute.  This code:

signed char g();
signed char foo(){
	return g();
}

compiles into:

define i8 @foo() signext nounwind  {
entry:
	%tmp1 = tail call i8 (...)* @g( ) signext nounwind 		; <i8> [#uses=1]
	ret i8 %tmp1
}

declare i8 @g(...) signext

Note that the 'signext' attribute is on all of foo, the call to G, and  
the G declaration itself.

> In both cases DAG.getReturnValueRegisterSizeInBits(...) returns 32  
> (on a
> 32 bit architecture)
>
> The caveat here is when we don't have a prototype for callee in which
> case "int ()" is considered, hence known values are returned and no
> optimization will take effect.

The IR is already capturing this much information.  If you want to go  
this route, it seems simple to parameterize (in target data?) the size  
of int, and have the code generator extend to that size, instead of  
forcing extension to i32.

-Chris



More information about the llvm-dev mailing list