> - "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>