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

Chris Lattner sabre at nondot.org
Fri May 23 15:27:32 PDT 2008


On May 20, 2008, at 2:16 PM, <Alireza.Moshtaghi at microchip.com> <Alireza.Moshtaghi at microchip.com 
 > wrote:

>
>> Ok, I'm not sure what issue you mean.  Can you restate?
>
> I'm referring to your statement (below) where you say "there needs  
> to be
> some attribute (or something) on foo".

Ok.

> What I don't understand is I
> don't know who would be setting this attribute?

The front-end should set this.  Further, as an optimization, the  
optimizer could also infer cases where it is safe to set this.  For  
example, if the C programmer defined a function to return int, and  
always return a value whose top 24 bits are sign extended, the  
optimizer could apply the attribute if it were smart enough.

> Whatever you do, if you
> consider caller and callee are in different translation units, then  
> all
> that we can know in the caller is whether the return value has been
> extended or not. But we don't know if it is sign extended or zero
> extended.

I think this is where the confusion is.  The ABI of many (all?)  
platforms specifies that the return value is *required* to be properly  
sign/zero extended based on the C type.  For example, if you have:

extern signed char X();
int Y() { return X(); }

The ABI *guarantees* that the implementation of "X" returns a value  
properly sign extended from i8.  If there abi specifies that the  
result comes back in an i32 register, then this means that the top 25  
bits are known to match.  Capturing this information in the IR is  
important, because it otherwise unsafe to assume that this is the case.

The optimizer and code generator has logic (see  
SelectionDAG::ComputeNumSignBits) that propagates around the number of  
sign bits that a computation is known to have.  This allows it to  
eliminate redundant sign extension instructions, and this is very  
important for common RISCy systems.

Since the C ABI guarantees that "X" returns a sign extended value  
here, it is safe to assume it in callers, even if you can't see the  
implementation of the callee.

> 	"
> 	define i32 @bar() {
>  	; call
>  	%tmp = call i32 @foo()
>  	%x = trunc i32 %tmp to i8
>
>
>  	; return
>  	%tmp2 = sext i8 to i32
>  	ret i32 %tmp2
> 	}
>

What I'm getting at with this, is that if we compiled foo to include  
an attribute "sign_ext_from_i8" or something, then we could capture  
this information.  It would be ugly, but acceptable to define:

   sign_ext_from_i8, sign_ext_from_i16
   zero_ext_from_i8, zero_ext_from_i16

And have the C front-end generate these.  Given this, the optimizer  
and codegen can continue doing their optimizations, and we can  
eventually eliminate the existing sext/zext attributes.

Does this make sense?

-Chris



More information about the llvm-dev mailing list