[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