<HTML xmlns:mailto><HEAD><TITLE>Samsung Enterprise Portal mySingle</TITLE>
<META content="text/html; charset=windows-1252" http-equiv=Content-Type>
<STYLE id=mysingle_style type=text/css>P {
        MARGIN-TOP: 5px; FONT-FAMILY: Arial, arial; MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt
}
TD {
        MARGIN-TOP: 5px; FONT-FAMILY: Arial, arial; MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt
}
LI {
        MARGIN-TOP: 5px; FONT-FAMILY: Arial, arial; MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt
}
BODY {
        LINE-HEIGHT: 1.4; MARGIN: 10px; FONT-FAMILY: Arial, arial; FONT-SIZE: 9pt
}
</STYLE>

<META name=GENERATOR content=ActiveSquare></HEAD>
<BODY>
<P> </P>
<P>Hi All,</P>
<P> </P>
<P>I tested earlier with llvm svn 3.3 release source.</P>
<P>Today I built and tested again with svn trunk, I also got "ldr r1, [r11, #80]", which solves the failure.</P>
<P>Thanks for all comments.</P>
<P>It seems similar issue <A href="http://llvm.org/bugs/show_bug.cgi?id=15868">http://llvm.org/bugs/show_bug.cgi?id=15868</A>, fixed already. </P>
<P> </P>
<P>I have few queries, Just to get my understandings better. Could you please comment on these,</P>
<P>- "since ABI says the stack pointer needs to be 8 byte aligned at function entry point" (taken from Manman's reply)</P>
<P>    What will be considered as entry point here?</P>
<P>    Is it place of SP Adjustments "sub   sp, sp, #16"<BR>    (Or) Is it place of first user instruction(end of prologue) "ldr     r2, .LCPI0_0"</P>
<P>-  What considerations will be made from llvm side to make abi compatibile with gcc/other compilers for arm - struct byval size >64 bytes.</P>
<P> </P>
<P> </P>
<P>Regards,<BR>Rajesh</P>
<P> </P>
<P>------- <B>Original Message</B> -------</P>
<P><B>Sender</B> : Stepan Dyatkovskiy<stpworld@narod.ru></P>
<P><B>Date</B> : Jun 20, 2013 03:08 (GMT+09:00)</P>
<P><B>Title</B> : Re: [LLVMdev] ARM struct byval size > 64 triggers failure</P>
<P> </P>Hi Rajesh,<BR><BR>I'm in some stage of looking what exactly happens. As Manman mentioned <BR>r0 is reserved for function return. Though, perhaps somewhere we didn't <BR>catch that...<BR><BR>Would you tell me, please, your llvm revision number?<BR><BR>-Stepan<BR><BR>Manman Ren wrote:<BR>><BR>> I missed that the testing case is returning a struct.<BR>> You are right in VARegSaveSize.<BR>><BR>> For callee:<BR>> subsp, sp, #16<BR>> push{r11, lr}<BR>> movr11, sp<BR>> subsp, sp, #8<BR>> strr3, [r11, #20]<BR>> strr2, [r11, #16]<BR>> strr1, [r11, #12]<BR>> ldrr1, [r11, #76]<BR>><BR>> The beginning of the input struct @ sp_at_entry - 16 - 8 + 12 =<BR>> sp_at_entry -12<BR>> # of leftover bytes 67-12 = 55<BR>> r11+76 is @ sp_at_entry - 24 + 76 = sp_at_entry + 52, this is incorrect,<BR>> it should be at align(55, 4) = 56.<BR>><BR>> For caller:<BR>> movr0, sp<BR>> ldrr1, .LCPI1_0<BR>> strr1, [r0, #56]<BR>><BR>> the 2nd argument is at sp_at_entry + 56, which is correct.<BR>><BR>> On my setup (built from TOT), I got "ldr r1, [r11, #80]" instead of 76.<BR>><BR>> Thanks,<BR>> Manman<BR>><BR>> On Jun 18, 2013, at 11:31 PM, Rajesh Viswabramana wrote:<BR>><BR>>> Hi all,<BR>>><BR>>><BR>>> Thanks for all comments,<BR>>><BR>>> Filed bug report with details,<BR>>><BR>>> http://llvm.org/bugs/show_bug.cgi?id=16368<BR>>><BR>>> @Manman, please find comments, queries inline.<BR>>><BR>>><BR>>> Regards,<BR>>> Rajesh<BR>>><BR>>><BR>>> -------*Original Message*-------<BR>>><BR>>> *Sender*: Stepan Dyatkovskiy<STPWORLD@NAROD.RU <mailto:stpworld@narod.ru>><BR>>><BR>>> *Date*: Jun 19, 2013 05:15 (GMT+09:00)<BR>>><BR>>> *Title*: Re: [LLVMdev] ARM struct byval size > 64 triggers failure<BR>>><BR>>><BR>>> Hi all,<BR>>> One more interesting job :-)<BR>>> I'll look too at this case tomorrow. Today my brain is about to be<BR>>> exploded..<BR>>> -Stepan.<BR>>> 18.06.2013, 22:56, "Manman Ren" <MREN@APPLE.COM <mailto:mren@apple.com>>:<BR>>>> Hi Rajesh,<BR>>>> The callee code looks okay to me<BR>>>>><BR>>>>> Assembly for check114<BR>>>>> ---------------------------------------------------------------<BR>>>>>         sub     sp, sp, #16<BR>>>>>         push    {r11, lr}<BR>>>>>         mov     r11, sp<BR>>>>>         sub     sp, sp, #8<BR>>>>>         str     r3, [r11, #20]<BR>>>>>         str     r2, [r11, #16]<BR>>>>>         str     r1, [r11, #12]<BR>>>>>         ldr     r1, [r11, #76]<BR>>>>><BR>>>> VARegSaveSize is 16 because we store the first 16 bytes of struct<BR>>>> byval in r0 to r3.<BR>>>> For the test code/assembly I mentioned, only r1-r3 are used for<BR>>>> struct byval. r0 used for return val.<BR>>>><BR>>>> So, NumGPRs = 3, VARegSize = 12, VARegSaveSize =16(4 byte offset),<BR>>>> access of arg1 is going wrong.<BR>>>><BR>>>> For updated test code:<BR>>>><BR>>>> struct S114 check114 (*int a*, struct S114 arg0, struct S114* arg1) {<BR>>>><BR>>>> .....<BR>>>> }<BR>>>><BR>>>> Only r1, r2 used for struct byval, NumGPRs = 2, VARegSize = 8,<BR>>>> VARegSaveSize =8, this case works, able to access arg1.<BR>>>><BR>>>><BR>>>> Please correct me, if my above understanding is wrong about NumGPRs,<BR>>>> VARegSaveSize calculation.<BR>>>><BR>>>><BR>>>> Align in computeRegArea is 8 since ABI says the stack pointer needs<BR>>>> to be 8 byte aligned at function entry point.<BR>>>> But the second argument does not have to be 8 byte aligned, in fact<BR>>>> it is 4 byte aligned for i32.<BR>>>> Ok.<BR>>>> r11, #76 is equivalent to sp_at_entry + 52 since r11 = spat_entry -<BR>>>> 16 - 8, which is 4-byte aligned after<BR>>>> storing the leftover (67-16=51) bytes of struct byval.<BR>>>> For test code, 3 reg used for struct byval, left over will be (67- 12<BR>>>> = 55) copied to stack by caller, 55 sets of ldrb,strb in assembly.<BR>>>> Pasting dump again for locating arg1 from sp_at_entry,<BR>>>> @entry of check114<BR>>>>   sp             0xbefff808 0xbefff808 --> sp_at_entry<BR>>>><BR>>>>   At arg1 accessing instruction [0xbefff808 + 52] -><BR>>>> [0xbefff83c] ->*0x4071706f*<BR>>>>   0xbefff7e4: 0x4001ed08 0x40024f90 0x4071706f 0xbefff8a0<BR>>>>   0xbefff7f4: 0x0000869c 0x00000000 0x3231302f 0x36353433<BR>>>>   0xbefff804: 0x3a393837 0x3e3d3c3b 0x4241403f 0x46454443<BR>>>>   0xbefff814: 0x4a494847 0x4e4d4c4b 0x5251504f 0x56555453<BR>>>>   0xbefff824: 0x5a595857 0x5e5d5c5b 0x6261605f 0x66656463<BR>>>>   0xbefff834: 0x6a696867 0x6e6d6c6b* 0x4071706f* *0x00010861*<BR>>>><BR>>>> Can you also paste the assembly for the caller side and check whether<BR>>>> the second argument is stored<BR>>>> at sp_at_entry+52?<BR>>>> Please find the attached assembly file.<BR>>>> As Renato suggested, please file a bug report.<BR>>>> Filed bug.<BR>>>> Thanks,<BR>>>> Manman<BR>>>> On Jun 18, 2013, at 4:26 AM, Rajesh Viswabramana<BR>>>> <RAJESH.VIS@SAMSUNG.COM <mailto:rajesh.vis@samsung.com>> wrote:<BR>>>><BR>>>>> Hi,<BR>>>>><BR>>>>> Handling of pass by val of struct size >64 bytes case is seems wrong<BR>>>>> for arm targets.<BR>>>>><BR>>>>><BR>>>>> *Summary:*<BR>>>>><BR>>>>> Incase of struct pass by value for size > 64 along with other<BR>>>>> function params, failure seen in some corner cases. Access to<BR>>>>> function params result in wrong stack location access.<BR>>>>><BR>>>>> Stack pointer adjustment done by prologue emitter and offset used to<BR>>>>> access function params have different logics for calculaton.<BR>>>>><BR>>>>><BR>>>>> *Test code<BR>>>>> *---------------------------------------------------------------<BR>>>>> #include <STDIO.H><BR>>>>> struct S114 {<BR>>>>>   char a[67];<BR>>>>> }a114[5];<BR>>>>><BR>>>>> struct S114 check114 (struct S114 arg0, struct S114* arg1) {<BR>>>>>   if(&a114[0] != arg1)                         // arg1 value is wrong<BR>>>>>     printf( "values %p, %p\n", &a114[0], arg1);<BR>>>>> }<BR>>>>> int main () {<BR>>>>>   int i= 0, j = 0;<BR>>>>>   for (;j<2; j++)                                    // just filling<BR>>>>> a114 with some values for identification<BR>>>>>     for(i=0; i<SIZEOF(STRUCT S114); i++)<br>>>>>       memset(&a114[j].a[i],(0x11+i+j*30), sizeof(int));<BR>>>>><BR>>>>>   check114 (a114[1], &a114[0]);         //=> a114[0]  is accessed<BR>>>>> from wrong location inside check114 function<BR>>>>> }<BR>>>>> ---------------------------------------------------------------<BR>>>>> clang -v<BR>>>>> clang version 3.3 (tags/RELEASE_33/final)<BR>>>>> Target: i386-pc-linux-gnu<BR>>>>> Thread model: posix<BR>>>>><BR>>>>> *Output on arm :<BR>>>>> *# ./check114.exe<BR>>>>> values 0x10861, 0x4071706f<BR>>>>> which is wrong.<BR>>>>><BR>>>>> Assembly for check114<BR>>>>> ---------------------------------------------------------------<BR>>>>>         sub     sp, sp, #16<BR>>>>>         push    {r11, lr}<BR>>>>>         mov     r11, sp<BR>>>>>         sub     sp, sp, #8<BR>>>>>         str     r3, [r11, #20]<BR>>>>>         str     r2, [r11, #16]<BR>>>>>         str     r1, [r11, #12]<BR>>>>>         ldr     r1, [r11, #76]<BR>>>>>         str     r1, [sp, #4]<BR>>>>>         .loc    1 7 0 prologue_end<BR>>>>>         ldr     r2, .LCPI0_0<BR>>>>>         cmp     r2, r1<BR>>>>>         beq     .LBB0_2<BR>>>>>         b       .LBB0_1<BR>>>>> ---------------------------------------------------------------<BR>>>>><BR>>>>> From reg, stack dump:<BR>>>>> ------------------------------------------------------------------------------------------------------------------------------<BR>>>>> @entry of check114<BR>>>>>   => 0x8398 <CHECK114>: sub sp, sp, #16<BR>>>>>         0x839c <CHECK114+4>: push {r11, lr}<BR>>>>>   sp             0xbefff808 0xbefff808<BR>>>>><BR>>>>> @if condition<BR>>>>>        0x83b4 <CHECK114+28>: ldr r1, [r11, #76] ; 0x4c         <---<BR>>>>> wrong value copied to r1, offset #76 should be #80<BR>>>>>        0x83b8 <CHECK114+32>: str r1, [sp, #4]<BR>>>>>        0x83bc <CHECK114+36>: ldr r2, [pc, #44] ; 0x83f0 <CHECK114+88><BR>>>>>  => 0x83c0 <CHECK114+40>: cmp r2, r1<BR>>>>><BR>>>>>   r11            0xbefff7f0 -1090521104<BR>>>>>   sp             0xbefff7e8 0xbefff7e8<BR>>>>><BR>>>>>   Stack dump:<BR>>>>>   0xbefff7e4: 0x4001ed08 0x40024f90 0x4071706f 0xbefff8a0<BR>>>>>   0xbefff7f4: 0x0000869c 0x00000000 0x3231302f 0x36353433<BR>>>>>   0xbefff804: 0x3a393837 0x3e3d3c3b 0x4241403f 0x46454443<BR>>>>>   0xbefff814: 0x4a494847 0x4e4d4c4b 0x5251504f 0x56555453<BR>>>>>   0xbefff824: 0x5a595857 0x5e5d5c5b 0x6261605f 0x66656463<BR>>>>>   0xbefff834: 0x6a696867 0x6e6d6c6b* 0x4071706f*<BR>>>>> *0x00010861*                 //[R11+4c] -> [0xbefff7f0+4c] -><BR>>>>> [0xbefff83c] -> 0x4071706f<BR>>>>><BR>>>>> Correct value is at location {[R11+4c]*+4*} --> 0x00010861, 4 bytes<BR>>>>> offset going wrong.<BR>>>>> ------------------------------------------------------------------------------------------------------------------------------<BR>>>>><BR>>>>> When i checked from the ARM Lowering part for generation of<BR>>>>>   sub sp, sp, #16<BR>>>>><BR>>>>> Emitted by,<BR>>>>><BR>>>>>   if (VARegSaveSize)<BR>>>>>     emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize,<BR>>>>> // --> VARegSaveSize is calculated in computeRegArea<BR>>>>>                  MachineInstr::FrameSetup)<BR>>>>><BR>>>>> ARMTargetLowering::computeRegArea(..) {<BR>>>>>   ...<BR>>>>>   VARegSize = NumGPRs * 4;<BR>>>>>   VARegSaveSize = (VARegSize + Align - 1) & ~(Align -<BR>>>>> 1);                 // --> 8 byte alignment done here<BR>>>>> }<BR>>>>><BR>>>>> Stack pointer decremented to NumGPRs*4 + alignment<BR>>>>><BR>>>>> NumGPRs = 3 registers<BR>>>>><BR>>>>> VARegSaveSize  = 16 (after considering 8 byte alignment )<BR>>>>><BR>>>>><BR>>>>> When the offset(#76) for the instruction, "ldr r1, [r11, #76] ;<BR>>>>> 0x4c"  is calculated, 4 bytes alignment is considered.<BR>>>>> In prologue stackpointer calculation 8 byte alignment is considered.<BR>>>>><BR>>>>> Due to this mimatch of alignment, If try to access any parameter<BR>>>>> after byval which results wrong value.<BR>>>>><BR>>>>> Issue(or offset of 4 bytes) wont occur if even number of register<BR>>>>> used for byval spilling.<BR>>>>> ex:<BR>>>>> struct S114 check114 (int a, struct S114 arg0, struct S114* arg1) {<BR>>>>> // accessing arg1 is fine in this case<BR>>>>> .....<BR>>>>> }<BR>>>>><BR>>>>> Could someone comment on below queries about fixing the problem,<BR>>>>><BR>>>>> 1) Is this 8 byte alignment mandatory ?  Is this due to " ARM AAPCS<BR>>>>> 5.2.1.2 Stack constraints at a public interface" ? Can this be removed?<BR>>>>><BR>>>>> 2) We will leave alignment as it is but in prologue we will adjust<BR>>>>> SP once again, this is little meaningless.<BR>>>>><BR>>>>> 3) While accessing arg1 we will consider alignment and add extra<BR>>>>> offset -> looks better.<BR>>>>><BR>>>>>  Offset to access arg1 is calculated by selection DAG that will be<BR>>>>> target independent. But Alignment adjustment should be done by<BR>>>>> target lowering. Any suggestions on how to fix this ?<BR>>>>><BR>>>>> Regards,<BR>>>>> Rajesh<BR>>>>><BR>>>>> <201306181656803_BEI0XT4N.gif><BR>>>>><BR>>>>> _______________________________________________<BR>>>>> LLVM Developers mailing list<BR>>>>> LLVMdev@cs.uiuc.edu<BR>>>>> <mailto:LLVMdev@cs.uiuc.edu>http://llvm.cs.uiuc.edu<BR>>>>> <HTTP: llvm.cs.uiuc.edu /><BR>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev<BR>>>> ,<BR>>>><BR>>>> _______________________________________________<BR>>>> LLVM Developers mailing list<BR>>>> LLVMdev@cs.uiuc.edu<BR>>>> <mailto:LLVMdev@cs.uiuc.edu>http://llvm.cs.uiuc.edu<BR>>>> <HTTP: llvm.cs.uiuc.edu /><BR>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev<BR>>>><BR>>><BR>>><BR>>><BR>>><BR>>><BR>>><BR>>> <201306191201558_BEI0XT4N.gif><BR>>><BR>>> <CHECK114.S><BR>><BR><BR>
<P> </P>
<P> </P><!--SP:rajesh.vis--><!--rajesh.vis:EP-->
<P> </P></mailto:LLVMdev@cs.uiuc.edu></mailto:LLVMdev@cs.uiuc.edu></X-BODY>
<P> </P>
<P> </P><!--SP:rajesh.vis--><!--rajesh.vis:EP-->
<P> </P>
<TABLE id=confidentialsignimg>
<TBODY>
<TR>
<TD NAMO_LOCK>
<P><IMG border=0 src="cid:Z5JE7EUABGFC@namo.co.kr" width=520></P></TD></TR></TBODY></TABLE></BODY></HTML><img src='http://ext.samsung.net/mailcheck/SeenTimeChecker?do=01d40a42474ca0b3fee309329ade3b4adcd4b042b2c7ce5a4b8edb9941f8601fb846c8a3750bbecdd1479191c8e13bdda4db4f4540c3ce487d6f8b298eafad26cf878f9a26ce15a0' border=0 width=0 height=0 style='display:none'>