> - "since ABI says the stack pointer needs to be 8 byte aligned at function entry point" (taken from Manman's reply) > What will be considered as entry point here? > Is it place of SP Adjustments "sub sp, sp, #16" > (Or) Is it place of first user instruction(end of prologue) "ldr r2, .LCPI0_0"Eight byte stack alignment is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS]. This specifies that functions must maintain an eight-byte aligned stack address (for example: 0x00, 0x08, 0x10, 0x18, 0x20) on all external interfaces. In practice this requirement is met if: At each external interface, the current stack pointer (SP) is a multiple of eight bytes. Your OS maintains eight-byte stack alignment on its external interfaces, for example, on task switches <-- from web Manman On Jun 20, 2013, at 5:35 AM, Rajesh Viswabramana <rajesh.vis at samsung.com> wrote:> > Hi All, > > I tested earlier with llvm svn 3.3 release source. > Today I built and tested again with svn trunk, I also got "ldr r1, [r11, #80]", which solves the failure. > Thanks for all comments. > It seems similar issue http://llvm.org/bugs/show_bug.cgi?id=15868, fixed already. > > I have few queries, Just to get my understandings better. Could you please comment on these, > - "since ABI says the stack pointer needs to be 8 byte aligned at function entry point" (taken from Manman's reply) > What will be considered as entry point here? > Is it place of SP Adjustments "sub sp, sp, #16" > (Or) Is it place of first user instruction(end of prologue) "ldr r2, .LCPI0_0" > - What considerations will be made from llvm side to make abi compatibile with gcc/other compilers for arm - struct byval size >64 bytes. > > > Regards, > Rajesh > > ------- Original Message ------- > Sender : Stepan Dyatkovskiy<stpworld at narod.ru> > Date : Jun 20, 2013 03:08 (GMT+09:00) > Title : Re: [LLVMdev] ARM struct byval size > 64 triggers failure > > Hi Rajesh, > > I'm in some stage of looking what exactly happens. As Manman mentioned > r0 is reserved for function return. Though, perhaps somewhere we didn't > catch that... > > Would you tell me, please, your llvm revision number? > > -Stepan > > Manman Ren wrote: > > > > I missed that the testing case is returning a struct. > > You are right in VARegSaveSize. > > > > For callee: > > subsp, sp, #16 > > push{r11, lr} > > movr11, sp > > subsp, sp, #8 > > strr3, [r11, #20] > > strr2, [r11, #16] > > strr1, [r11, #12] > > ldrr1, [r11, #76] > > > > The beginning of the input struct @ sp_at_entry - 16 - 8 + 12 > > sp_at_entry -12 > > # of leftover bytes 67-12 = 55 > > r11+76 is @ sp_at_entry - 24 + 76 = sp_at_entry + 52, this is incorrect, > > it should be at align(55, 4) = 56. > > > > For caller: > > movr0, sp > > ldrr1, .LCPI1_0 > > strr1, [r0, #56] > > > > the 2nd argument is at sp_at_entry + 56, which is correct. > > > > On my setup (built from TOT), I got "ldr r1, [r11, #80]" instead of 76. > > > > Thanks, > > Manman > > > > On Jun 18, 2013, at 11:31 PM, Rajesh Viswabramana wrote: > > > >> Hi all, > >> > >> > >> Thanks for all comments, > >> > >> Filed bug report with details, > >> > >> http://llvm.org/bugs/show_bug.cgi?id=16368 > >> > >> @Manman, please find comments, queries inline. > >> > >> > >> Regards, > >> Rajesh > >> > >> > >> -------*Original Message*------- > >> > >> *Sender*: Stepan Dyatkovskiy> > >> > >> *Date*: Jun 19, 2013 05:15 (GMT+09:00) > >> > >> *Title*: Re: [LLVMdev] ARM struct byval size > 64 triggers failure > >> > >> > >> Hi all, > >> One more interesting job :-) > >> I'll look too at this case tomorrow. Today my brain is about to be > >> exploded.. > >> -Stepan. > >> 18.06.2013, 22:56, "Manman Ren" >: > >>> Hi Rajesh, > >>> The callee code looks okay to me > >>>> > >>>> Assembly for check114 > >>>> --------------------------------------------------------------- > >>>> sub sp, sp, #16 > >>>> push {r11, lr} > >>>> mov r11, sp > >>>> sub sp, sp, #8 > >>>> str r3, [r11, #20] > >>>> str r2, [r11, #16] > >>>> str r1, [r11, #12] > >>>> ldr r1, [r11, #76] > >>>> > >>> VARegSaveSize is 16 because we store the first 16 bytes of struct > >>> byval in r0 to r3. > >>> For the test code/assembly I mentioned, only r1-r3 are used for > >>> struct byval. r0 used for return val. > >>> > >>> So, NumGPRs = 3, VARegSize = 12, VARegSaveSize =16(4 byte offset), > >>> access of arg1 is going wrong. > >>> > >>> For updated test code: > >>> > >>> struct S114 check114 (*int a*, struct S114 arg0, struct S114* arg1) { > >>> > >>> ..... > >>> } > >>> > >>> Only r1, r2 used for struct byval, NumGPRs = 2, VARegSize = 8, > >>> VARegSaveSize =8, this case works, able to access arg1. > >>> > >>> > >>> Please correct me, if my above understanding is wrong about NumGPRs, > >>> VARegSaveSize calculation. > >>> > >>> > >>> Align in computeRegArea is 8 since ABI says the stack pointer needs > >>> to be 8 byte aligned at function entry point. > >>> But the second argument does not have to be 8 byte aligned, in fact > >>> it is 4 byte aligned for i32. > >>> Ok. > >>> r11, #76 is equivalent to sp_at_entry + 52 since r11 = spat_entry - > >>> 16 - 8, which is 4-byte aligned after > >>> storing the leftover (67-16=51) bytes of struct byval. > >>> For test code, 3 reg used for struct byval, left over will be (67- 12 > >>> = 55) copied to stack by caller, 55 sets of ldrb,strb in assembly. > >>> Pasting dump again for locating arg1 from sp_at_entry, > >>> @entry of check114 > >>> sp 0xbefff808 0xbefff808 --> sp_at_entry > >>> > >>> At arg1 accessing instruction [0xbefff808 + 52] -> > >>> [0xbefff83c] ->*0x4071706f* > >>> 0xbefff7e4: 0x4001ed08 0x40024f90 0x4071706f 0xbefff8a0 > >>> 0xbefff7f4: 0x0000869c 0x00000000 0x3231302f 0x36353433 > >>> 0xbefff804: 0x3a393837 0x3e3d3c3b 0x4241403f 0x46454443 > >>> 0xbefff814: 0x4a494847 0x4e4d4c4b 0x5251504f 0x56555453 > >>> 0xbefff824: 0x5a595857 0x5e5d5c5b 0x6261605f 0x66656463 > >>> 0xbefff834: 0x6a696867 0x6e6d6c6b* 0x4071706f* *0x00010861* > >>> > >>> Can you also paste the assembly for the caller side and check whether > >>> the second argument is stored > >>> at sp_at_entry+52? > >>> Please find the attached assembly file. > >>> As Renato suggested, please file a bug report. > >>> Filed bug. > >>> Thanks, > >>> Manman > >>> On Jun 18, 2013, at 4:26 AM, Rajesh Viswabramana > >>> > wrote: > >>> > >>>> Hi, > >>>> > >>>> Handling of pass by val of struct size >64 bytes case is seems wrong > >>>> for arm targets. > >>>> > >>>> > >>>> *Summary:* > >>>> > >>>> Incase of struct pass by value for size > 64 along with other > >>>> function params, failure seen in some corner cases. Access to > >>>> function params result in wrong stack location access. > >>>> > >>>> Stack pointer adjustment done by prologue emitter and offset used to > >>>> access function params have different logics for calculaton. > >>>> > >>>> > >>>> *Test code > >>>> *--------------------------------------------------------------- > >>>> #include > >>>> struct S114 { > >>>> char a[67]; > >>>> }a114[5]; > >>>> > >>>> struct S114 check114 (struct S114 arg0, struct S114* arg1) { > >>>> if(&a114[0] != arg1) // arg1 value is wrong > >>>> printf( "values %p, %p\n", &a114[0], arg1); > >>>> } > >>>> int main () { > >>>> int i= 0, j = 0; > >>>> for (;j<2; j++) // just filling > >>>> a114 with some values for identification > >>>> for(i=0; i>>>> memset(&a114[j].a[i],(0x11+i+j*30), sizeof(int)); > >>>> > >>>> check114 (a114[1], &a114[0]); //=> a114[0] is accessed > >>>> from wrong location inside check114 function > >>>> } > >>>> --------------------------------------------------------------- > >>>> clang -v > >>>> clang version 3.3 (tags/RELEASE_33/final) > >>>> Target: i386-pc-linux-gnu > >>>> Thread model: posix > >>>> > >>>> *Output on arm : > >>>> *# ./check114.exe > >>>> values 0x10861, 0x4071706f > >>>> which is wrong. > >>>> > >>>> Assembly for check114 > >>>> --------------------------------------------------------------- > >>>> sub sp, sp, #16 > >>>> push {r11, lr} > >>>> mov r11, sp > >>>> sub sp, sp, #8 > >>>> str r3, [r11, #20] > >>>> str r2, [r11, #16] > >>>> str r1, [r11, #12] > >>>> ldr r1, [r11, #76] > >>>> str r1, [sp, #4] > >>>> .loc 1 7 0 prologue_end > >>>> ldr r2, .LCPI0_0 > >>>> cmp r2, r1 > >>>> beq .LBB0_2 > >>>> b .LBB0_1 > >>>> --------------------------------------------------------------- > >>>> > >>>> From reg, stack dump: > >>>> ------------------------------------------------------------------------------------------------------------------------------ > >>>> @entry of check114 > >>>> => 0x8398 : sub sp, sp, #16 > >>>> 0x839c : push {r11, lr} > >>>> sp 0xbefff808 0xbefff808 > >>>> > >>>> @if condition > >>>> 0x83b4 : ldr r1, [r11, #76] ; 0x4c <--- > >>>> wrong value copied to r1, offset #76 should be #80 > >>>> 0x83b8 : str r1, [sp, #4] > >>>> 0x83bc : ldr r2, [pc, #44] ; 0x83f0 > >>>> => 0x83c0 : cmp r2, r1 > >>>> > >>>> r11 0xbefff7f0 -1090521104 > >>>> sp 0xbefff7e8 0xbefff7e8 > >>>> > >>>> Stack dump: > >>>> 0xbefff7e4: 0x4001ed08 0x40024f90 0x4071706f 0xbefff8a0 > >>>> 0xbefff7f4: 0x0000869c 0x00000000 0x3231302f 0x36353433 > >>>> 0xbefff804: 0x3a393837 0x3e3d3c3b 0x4241403f 0x46454443 > >>>> 0xbefff814: 0x4a494847 0x4e4d4c4b 0x5251504f 0x56555453 > >>>> 0xbefff824: 0x5a595857 0x5e5d5c5b 0x6261605f 0x66656463 > >>>> 0xbefff834: 0x6a696867 0x6e6d6c6b* 0x4071706f* > >>>> *0x00010861* //[R11+4c] -> [0xbefff7f0+4c] -> > >>>> [0xbefff83c] -> 0x4071706f > >>>> > >>>> Correct value is at location {[R11+4c]*+4*} --> 0x00010861, 4 bytes > >>>> offset going wrong. > >>>> ------------------------------------------------------------------------------------------------------------------------------ > >>>> > >>>> When i checked from the ARM Lowering part for generation of > >>>> sub sp, sp, #16 > >>>> > >>>> Emitted by, > >>>> > >>>> if (VARegSaveSize) > >>>> emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize, > >>>> // --> VARegSaveSize is calculated in computeRegArea > >>>> MachineInstr::FrameSetup) > >>>> > >>>> ARMTargetLowering::computeRegArea(..) { > >>>> ... > >>>> VARegSize = NumGPRs * 4; > >>>> VARegSaveSize = (VARegSize + Align - 1) & ~(Align - > >>>> 1); // --> 8 byte alignment done here > >>>> } > >>>> > >>>> Stack pointer decremented to NumGPRs*4 + alignment > >>>> > >>>> NumGPRs = 3 registers > >>>> > >>>> VARegSaveSize = 16 (after considering 8 byte alignment ) > >>>> > >>>> > >>>> When the offset(#76) for the instruction, "ldr r1, [r11, #76] ; > >>>> 0x4c" is calculated, 4 bytes alignment is considered. > >>>> In prologue stackpointer calculation 8 byte alignment is considered. > >>>> > >>>> Due to this mimatch of alignment, If try to access any parameter > >>>> after byval which results wrong value. > >>>> > >>>> Issue(or offset of 4 bytes) wont occur if even number of register > >>>> used for byval spilling. > >>>> ex: > >>>> struct S114 check114 (int a, struct S114 arg0, struct S114* arg1) { > >>>> // accessing arg1 is fine in this case > >>>> ..... > >>>> } > >>>> > >>>> Could someone comment on below queries about fixing the problem, > >>>> > >>>> 1) Is this 8 byte alignment mandatory ? Is this due to " ARM AAPCS > >>>> 5.2.1.2 Stack constraints at a public interface" ? Can this be removed? > >>>> > >>>> 2) We will leave alignment as it is but in prologue we will adjust > >>>> SP once again, this is little meaningless. > >>>> > >>>> 3) While accessing arg1 we will consider alignment and add extra > >>>> offset -> looks better. > >>>> > >>>> Offset to access arg1 is calculated by selection DAG that will be > >>>> target independent. But Alignment adjustment should be done by > >>>> target lowering. Any suggestions on how to fix this ? > >>>> > >>>> Regards, > >>>> Rajesh > >>>> > >>>> <201306181656803_BEI0XT4N.gif> > >>>> > >>>> _______________________________________________ > >>>> LLVM Developers mailing list > >>>> LLVMdev at cs.uiuc.edu > >>>> http://llvm.cs.uiuc.edu > >>>> > >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >>> , > >>> > >>> _______________________________________________ > >>> LLVM Developers mailing list > >>> LLVMdev at cs.uiuc.edu > >>> http://llvm.cs.uiuc.edu > >>> > >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >>> > >> > >> > >> > >> > >> > >> > >> <201306191201558_BEI0XT4N.gif> > >> > >> > > > > > > > > > > <201306201804240_BEI0XT4N.gif>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130620/cf3f17de/attachment.html>
Stepan Dyatkovskiy
2013-Jun-21 09:49 UTC
[LLVMdev] ARM struct byval size > 64 triggers failure
<div>I'd want to add few words too :-)</div><div>This is also means, that at very beginning of function SP should be multiple of 8. And straight before "bl" instruction - the same.</div><div>If I'm got right, theoretically, inside your function (in all other cases) there are no any restrictions on SP, so you can use it even as a loop counter :-)</div><div>š</div><div>-Stepan.</div><div>š</div><div>20.06.2013, 21:53, "Manman Ren" <mren@apple.com>:</div><blockquote type="cite"><div>š</div><div><blockquote type="cite"><div style="line-height:1.4;margin:10px;font-family:Arial,arial;font-size:9pt;"><p style="margin-top:5px;margin-bottom:5px;font-size:9pt;">-š"since ABI says the stack pointer needs to be 8 byte aligned at function entry point" (taken from Manman's reply)</p><p style="margin-top:5px;margin-bottom:5px;font-size:9pt;">ššš What will be considered as entry point here?</p><p style="margin-top:5px;margin-bottom:5px;font-size:9pt;">ššš 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></div></blockquote></div><div style="margin-top:0.8em;margin-bottom:0.2em;font-family:Verdana,Tahoma,Arial,Helvetica,sans-serif;font-size:small;background-color:#ffffff;">Eight byte stack alignment is a requirement of theš<a style="color:#4f0f8e;text-decoration:none;" href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/index.html">Procedure Call Standard for the ARM Architecture [AAPCS]</a>. This specifies that functions must maintain an eight-byte aligned stack address (for example:š<code style="color:#333399;font-family:"Lucida Sans Typewriter","Courier New",Courier,monospace;font-size:0.9em;">0x00</code>,š<code style="color:#333399;font-family:"Lucida Sans Typewriter","Courier New",Courier,monospace;font-size:0.9em;">0x08</code>,š<code style="color:#333399;font-family:"Lucida Sans Typewriter","Courier New",Courier,monospace;font-size:0.9em;">0x10</code>,š<code style="color:#333399;font-family:"Lucida Sans Typewriter","Courier New",Courier,monospace;font-size:0.9em;">0x18</code>,š<code style="color:#333399;font-family:"Lucida Sans Typewriter","Courier New",Courier,monospace;font-size:0.9em;">0x20</code>) on all external interfaces. In practice this requirement is met if:</div><ul style="margin-top:0.8em;margin-bottom:0.2em;font-family:Verdana,Tahoma,Arial,Helvetica,sans-serif;font-size:small;background-color:#ffffff;"><li style="margin-top:0.6em;margin-bottom:0.2em;">At each external interface, the current stack pointer (SP) is a multiple of eight bytes.</li><li style="margin-top:0.6em;margin-bottom:0.2em;">Your OS maintains eight-byte stack alignment on its external interfaces, for example, on task switches</li></ul><div>š</div><div><div><-- from web</div><div>š</div><div>Manman</div><div><br /><div><div>On Jun 20, 2013, at 5:35 AM, Rajesh Viswabramana <<a href="mailto:rajesh.vis@samsung.com">rajesh.vis@samsung.com</a>> wrote:</div><br /><blockquote type="cite"><div style="line-height:1.4;margin:10px;font-family:Arial,arial;font-size:9pt;text-align:start;text-transform:none;"><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">Hi All,</p><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">I tested earlier with llvm svn 3.3 release source.</p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">Today I built and tested again with svn trunk, I also gotš"ldr r1, [r11, #80]", whichšsolves the failure.</p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">Thanks for all comments.</p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">It seems similar issue<span>š</span><a href="http://llvm.org/bugs/show_bug.cgi?id=15868">http://llvm.org/bugs/show_bug.cgi?id=15868</a>, fixed already.š</p><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">I have few queries, Just to get my understandings better. Could you please comment on these,</p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">-š"since ABI says the stack pointer needs to be 8 byte aligned at function entry point" (taken from Manman's reply)</p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">ššš What will be considered as entry point here?</p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">ššš 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 style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">-š What considerations will be made from llvm sidešto make abi compatibile with gcc/other compilers for arm - struct byval size >64 bytes.</p><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">Regards,<br />Rajesh</p><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">-------<span>š</span><strong>Original Message</strong><span>š</span>-------</p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;"><strong>Sender</strong><span>š</span>: Stepan Dyatkovskiy<<a href="mailto:stpworld@narod.ru">stpworld@narod.ru</a>></p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;"><strong>Date</strong><span>š</span>: Jun 20, 2013 03:08 (GMT+09:00)</p><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;"><strong>Title</strong><span>š</span>: Re: [LLVMdev] ARM struct byval size > 64 triggers failure</p><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div>Hi Rajesh,<br /><br />I'm in some stage of looking what exactly happens. As Manman mentioned<span>š</span><br />r0 is reserved for function return. Though, perhaps somewhere we didn't<span>š</span><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 />>> <a href="http://llvm.org/bugs/show_bug.cgi?id=16368">http://llvm.org/bugs/show_bug.cgi?id=16368</a><br />>><br />>> @Manman, please find comments, queries inline.<br />>><br />>><br />>> Regards,<br />>> Rajesh<br />>><br />>><br />>> -------*Original Message*-------<br />>><br />>> *Sender*: Stepan Dyatkovskiy<<a href="mailto:stpworld@narod.ru">stpworld@narod.ru</a>>><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"<span>š</span><<a href="mailto:mren@apple.com">mren@apple.com</a>><mailto:<a href="mailto:mren@apple.com=">mren@apple.com=</a>"">>:<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] ->*0x<span>4071706</span>f*<br />>>>šš 0xbefff7e4: 0x4001ed08 0x40024f90 0x<span>4071706</span>f 0xbefff8a0<br />>>>šš 0xbefff7f4: 0x<span>0000869</span>c 0x<span>00000000 0</span>x<span>3231302</span>f 0x<span>36353433</span><br />>>>šš 0xbefff804: 0x3a<span>393837 0</span>x3e3d3c3b 0x<span>4241403</span>f 0x<span>46454443</span><br />>>>šš 0xbefff814: 0x4a<span>494847 0</span>x4e4d4c4b 0x<span>5251504</span>f 0x<span>56555453</span><br />>>>šš 0xbefff824: 0x5a<span>595857 0</span>x5e5d5c5b 0x<span>6261605</span>f 0x<span>66656463</span><br />>>>šš 0xbefff834: 0x6a<span>696867 0</span>x6e6d6c6b* 0x<span>4071706</span>f* *0x<span>00010861</span>*<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 />>>><span>š</span><<a href="mailto:rajesh.vis@samsung.com">rajesh.vis@samsung.com</a>><mailto:<a href="mailto:rajesh.vis@samsung.com=">rajesh.vis@samsung.com=</a>"">> 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<span>š</span><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, 0x<span>4071706</span>f<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<span>š</span>: sub sp, sp, #16<br />>>>>šššššššš 0x839c<span>š</span><check114+4>: push {r11, lr}<br />>>>>šš spšššššššššššš 0xbefff808 0xbefff808<br />>>>><br />>>>> @if condition<br />>>>>šššššššš0x83b4<span>š</span><check114+28>: ldr r1, [r11, #76] ; 0x4cšššššššš <---<br />>>>> wrong value copied to r1, offset #76 should be #80<br />>>>>šššššššš0x83b8<span>š</span><check114+32>: str r1, [sp, #4]<br />>>>>šššššššš0x83bc<span>š</span><check114+36>: ldr r2, [pc, #44] ; 0x83f0<span>š</span><check114+88><br />>>>>šš=> 0x83c0<span>š</span><check114+40>: cmp r2, r1<br />>>>><br />>>>>šš r11šššššššššššš0xbefff7f<span>0 -1090521104</span><br />>>>>šš spšššššššššššš 0xbefff7e8 0xbefff7e8<br />>>>><br />>>>>šš Stack dump:<br />>>>>šš 0xbefff7e4: 0x4001ed08 0x40024f90 0x<span>4071706</span>f 0xbefff8a0<br />>>>>šš 0xbefff7f4: 0x<span>0000869</span>c 0x<span>00000000 0</span>x<span>3231302</span>f 0x<span>36353433</span><br />>>>>šš 0xbefff804: 0x3a<span>393837 0</span>x3e3d3c3b 0x<span>4241403</span>f 0x<span>46454443</span><br />>>>>šš 0xbefff814: 0x4a<span>494847 0</span>x4e4d4c4b 0x<span>5251504</span>f 0x<span>56555453</span><br />>>>>šš 0xbefff824: 0x5a<span>595857 0</span>x5e5d5c5b 0x<span>6261605</span>f 0x<span>66656463</span><br />>>>>šš 0xbefff834: 0x6a<span>696867 0</span>x6e6d6c6b* 0x<span>4071706</span>f*<br />>>>> *0x<span>00010861</span>*šššššššššššššššš //[R11+4c] -> [0xbefff7f0+4c] -><br />>>>> [0xbefff83c] -> 0x<span>4071706</span>f<br />>>>><br />>>>> Correct value is at location {[R11+4c]*+4*} --> 0x<span>00010861</span>, 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 />>>>> <<span>201306181656803</span>_BEI0XT4N.gif><br />>>>><br />>>>> _______________________________________________<br />>>>> LLVM Developers mailing list<br />>>>> <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a><br />>>>><span>š</span><mailto:<a href="mailto:llvmdev@cs.uiuc.edu">llvmdev@cs.uiuc.edu</a>><a href="http://llvm.cs.uiuc.edu/">http://llvm.cs.uiuc.edu</a><br />>>>><span>š</span><http: llvm.cs.uiuc.edu=""><br />>>>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br />>>> ,<br />>>><br />>>> _______________________________________________<br />>>> LLVM Developers mailing list<br />>>><span>š</span><a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a><br />>>><span>š</span><mailto:<a href="mailto:llvmdev@cs.uiuc.edu">llvmdev@cs.uiuc.edu</a>><a href="http://llvm.cs.uiuc.edu/">http://llvm.cs.uiuc.edu</a><br />>>><span>š</span><http: llvm.cs.uiuc.edu=""><br />>>><span>š</span><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br />>>><br />>><br />>><br />>><br />>><br />>><br />>><br />>> <<span>201306191201558</span>_BEI0XT4N.gif><br />>><br />>><span>š</span><check114.s><br />><br /><br /><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><div style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;">š</div><table><tbody><tr><td style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;"><p style="margin-top:5px;font-family:Arial,arial;margin-bottom:5px;font-size:9pt;"><span><<span>201306201804240</span>_BEI0XT4N.gif></span></p></td></tr></tbody></table></div></blockquote></div></div></div></blockquote>