[LLVMdev] promotion of return value.

Alireza.Moshtaghi at microchip.com
Fri, 13 Mar 2009 19:21:36 -0000

Some targets want to do the promotion in the callee and some in the
caller. Now what you are discussing in your bug is we shouldn't do in
both...
Now the tricky part is that many targets (not for the sake of promotion,
but for the sake of performance) return a smaller value in a larger
register (say if the function is to return char, they return it in 32
bit register);
So they are effectively promoting the return value on the callee side,
then the caller takes the part that it needs and again promotes it to
comply with the rules of integer promotion stuff, hence double
promotion.

What we are trying to do is to add new attributes (more maybe added
later):

>   sign_ext_from_i8, sign_ext_from_i16
>   zero_ext_from_i8, zero_ext_from_i16

to function definition so (assuming that both caller and callee are
generated in the same front-end) the caller will know if the callee has
already extended the return value or not, then it can promote only if
needed.

You may argue that this all can be done per a target-defined convention
and I think that is the theory behind the patches that are used to fix
your bug.
However, we had this discussion last year, and it was decided to make
things more transparent by adding the aforementioned attributes. Please
look at the thread:

http://www.nabble.com/Troubling-promotion-of-return-value-to-Integer-...
-to17237327.html#a17237327

Regards,
Ali

> -----Original Message-----
> From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at
cs.uiuc.edu]
On
> Behalf Of Rafael Espindola
> Sent: Friday, March 13, 2009 2:07 AM
> To: LLVM Developers Mailing List
> Subject: Re: [LLVMdev] promotion of return value.
>
> 2009/3/12  <Alireza.Moshtaghi at microchip.com>:
> > What I was planning to do is to provide a default behavior that is
> > consistent with what currently llvm does (promote to 32 bit)
> > And then there will be control in clang for targets to do things
> > differently.
> > But I also understand you concern about gcc frontend; because the
same
> > thing has to also take place there....
> > We had long discussions about this last year, and this is what has
been
> > decided. Maybe Chris is in a better position to decide what to do.
>
> Can you take a look at my last post on the bug and see if that could
work
> for all the cases you have? Since llvm-gcc and clang are the ones
doing
> the lowering, i think it would. Consider the code
>
> ----------------------
> short x;
> void g(int);
> short h(void);
> short f(void) {
>   g(h());
>   return x;
> }
> --------------------
>
> For X86, I think llvm IL for f can be
> ------------------------------------------
> define i16 @f() nounwind {
> entry:
>        %0 = tail call i16 @h() nounwind
>        %1 = sext i16 %0 to i32
>        tail call void @g(i32 %1) nounwind
>        %2 = load i16* @x, align 2
>        ret i16 %2
> }
> --------------------------------------
>
> and for arm it can be
>
> ----------------------------------------
> define i32 @f() nounwind {
> entry:
>        %0 = tail call i32 @h() nounwind
>        tail call void @g(i32 %0) nounwind
>        %2 = load i16* @x, align 2
>        %3 = sext i16 %2 to i32
>        ret i32 %3
> }
> --------------------------------------
>
> Note that for X86 only the caller does extension. For ARM only the
> callee does it.
>
> > A.
>
> Cheers,
> --
> Rafael Avila de Espindola
>
> Google | Gordon House | Barrow Street | Dublin 4 | Ireland
> Registered in Dublin, Ireland | Registration Number: 368047
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev