Chris Lattner
2008-May-20 20:06 UTC
[LLVMdev] Troubling promotion of return value to Integer ...
On Mon, 19 May 2008 Alireza.Moshtaghi at microchip.com wrote:> Correction: > > The analysis I made regarding the callers knowledge of sign/zero > extension of return value is flawed. So I take it back. > > Never the less, I don't see how adding attributes would resolve this > problem either.Ok, I'm not sure what issue you mean. Can you restate? -Chris> ________________________________ > > From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] > On Behalf Of Alireza.Moshtaghi at microchip.com > Sent: Sunday, May 18, 2008 6:33 PM > To: llvmdev at cs.uiuc.edu > Subject: Re: [LLVMdev] Troubling promotion of return value to Integer > ... > > > > But they both follow the same calling convention. There are two > possibilities in the caller: > > 1) Call node returns sizeof(int) or larger: in this case there is no > truncation. > > 2) Call node returns smaller than sizeof(int): in this case callee > always has to return an int so it has to consistently either sign extend > or zero extend because int is either signed or unsigned consistently for > that port. Assuming that caller and callee follow the same calling > convention, caller always knows (hence the llvm pass knows) that, if the > return value of the called function is being truncated, it is because of > return value promotion. It also knows the calling convention, so it > knows whether it is sign or zero extended. This is regardless of > translation unit where the callee is in. > > > >> No, because the callee and caller may be in different translation > units. > >-Chris -- http://nondot.org/sabre/ http://llvm.org/
Alireza.Moshtaghi at microchip.com
2008-May-20 21:16 UTC
[LLVMdev] Troubling promotion of return value to Integer ...
>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". What I don't understand is I don't know who would be setting this attribute? 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. " define i32 @bar() { ; call %tmp = call i32 @foo() %x = trunc i32 %tmp to i8 ; return %tmp2 = sext i8 to i32 ret i32 %tmp2 } The problem with this is that we now have a trunc+sext instruction that cannot be eliminated. The loss here is that while foo returns an i32 value, we lost the fact that the top 25 bits all have the same value (i.e. that it is a sign extended 8-bit value). Because of this, we can't eliminate the trunc+sext pair in bar, pessimizing code (and in a very common case!). I am just saying that we should have some attribute (or something) on foo that indicates its result is actually sign extended, allowing the optimizer to zap the trunc+sext in bar. "
Chris Lattner
2008-May-23 22:27 UTC
[LLVMdev] Troubling promotion of return value to Integer ...
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
Seemingly Similar Threads
- [LLVMdev] Troubling promotion of return value to Integer ...
- [LLVMdev] Troubling promotion of return value to Integer ...
- [LLVMdev] promotion of return value.
- [LLVMdev] promotion of return value.
- [LLVMdev] Troubling promotion of return value to Integer ...