Alireza.Moshtaghi at microchip.com
2009-Mar-12 21:27 UTC
[LLVMdev] promotion of return value.
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. A.> -----Original Message----- > From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu]On> Behalf Of Dale Johannesen > Sent: Thursday, March 12, 2009 11:45 AM > To: LLVM Developers Mailing List > Subject: Re: [LLVMdev] promotion of return value. > > > On Mar 12, 2009, at 11:31 AMPDT, Andrew Haley wrote: > > > Rafael Espindola wrote: > >>>> 1) The return value promotion will be removed from llvm backendand> >>>> implemented in both front-ends (clang and llvm-gcc) > >>>> > >>>> 2) The promotions are only applied to the return value in thebody> >>>> of the function. > >>>> Return value of function definition and declaration will not be > >>>> promoted > >> > >> You might want to look at bughttp://llvm.org/bugs/show_bug.cgi?id=3779> >> . > >> > >> If I understand what you are proposing, it is exactly the oppositeof> >> what gcc does, which would be annoying for someone trying to linkgcc> >> and llvm compiled code. > > > > That's right. In gcc we used to do this in the front-ends but we > > stopped. This required quite a lot of discussion with the Linux ABI > > standardization people. > > Yes, I trust we're taking into account that some ABIs have > requirements about this. > For example, ARM AAPCS requires the caller promote arguments, and the > callee > promote return values. > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
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
Hi Rafael, if the nasty hack I mentioned in the PR was removed then the following code should work for both X86 and ARM: define signext i16 @f() nounwind { entry: %0 = tail call signext 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 } This is what llvm-gcc currently produces. On x86 the value would be returned in an i16 register, so no sign extension would be performed in the callee. Thus the sign extension to i32 would occur in the caller. On the other hand, consider ARM. There are no i16 registers on ARM, so the value would be returned in an i32. The signext attribute means that the callee would sign extend the i16 to an i32 before returning it. Also, due to the signext attribute the caller will know that the callee sign extended the i16 to an i32, so the DAG combiner will drop the sign extension in the caller as redundant. Try the attached patch. Ciao, Duncan. -------------- next part -------------- A non-text attachment was scrubbed... Name: call.diff Type: text/x-patch Size: 890 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090313/47661ed1/attachment.bin>
Alireza.Moshtaghi at microchip.com
2009-Mar-13 19:21 UTC
[LLVMdev] promotion of return value.
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_i16to 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 thesame> > thing has to also take place there.... > > We had long discussions about this last year, and this is what hasbeen> > 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 couldwork> for all the cases you have? Since llvm-gcc and clang are the onesdoing> 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