<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div><br></div>Hi Rajesh,<div><br></div><div>The callee code looks okay to me</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;">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]</p></div></blockquote><div><div>VARegSaveSize is 16 because we store the first 16 bytes of struct byval in r0 to r3.</div><div>Align in computeRegArea is 8 since ABI says the stack pointer needs to be 8 byte aligned at function entry point.</div><div>But the second argument does not have to be 8 byte aligned, in fact it is 4 byte aligned for i32.</div><div><br></div><div>r11, #76 is equivalent to sp_at_entry + 52 since r11 = spat_entry - 16 - 8, which is 4-byte aligned after</div><div>storing the leftover (67-16=51) bytes of struct byval.</div><div><br></div><div>Can you also paste the assembly for the caller side and check whether the second argument is stored</div><div>at sp_at_entry+52?</div><div><br></div><div>As Renato suggested, please file a bug report.</div><div><br></div><div>Thanks,</div><div>Manman</div><div><br></div><div><br></div><div>On Jun 18, 2013, at 4:26 AM, Rajesh Viswabramana <<a href="mailto:rajesh.vis@samsung.com">rajesh.vis@samsung.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="line-height: 1.4; margin: 10px; font-family: Arial, arial; font-size: 9pt; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Hi,</p><div style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"> <br class="webkit-block-placeholder"></div><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Handling of pass by val of struct size >64 bytes case is seems wrong for arm targets.</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"><strong></strong> </p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"><strong>Summary:</strong></p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">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. </p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Stack pointer adjustment done by prologue emitter and offset used to access function params have different logics for calculaton.</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"><strong></strong> </p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"><strong>Test code<br></strong>---------------------------------------------------------------<br>#include <stdio.h><br>struct S114 {<br>  char a[67];<br>}a114[5];</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">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 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)); </p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">  check114 (a114[1], &a114[0]);         //=> a114[0]  is accessed 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</p><div style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"> <br class="webkit-block-placeholder"></div><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"><strong>Output on arm :<br></strong># ./check114.exe<span class="Apple-converted-space"> </span><br>values 0x10861, 0x4071706f<br>which is wrong.</p><div style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"> <br class="webkit-block-placeholder"></div><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Assembly for check114<span class="Apple-converted-space"> </span><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>---------------------------------------------------------------</p><div style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"> <br class="webkit-block-placeholder"></div><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">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</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">@if condition<br>       0x83b4 <check114+28>: ldr r1, [r11, #76] ; 0x4c         <--- 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></p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">  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<strong> 0x4071706f</strong> <strong>0x00010861</strong>                 //[R11+4c] -> [0xbefff7f0+4c] -> [0xbefff83c] -> 0x4071706f<br></p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Correct value is at location {[R11+4c]<strong>+4</strong>} --> 0x00010861, 4 bytes offset going wrong.<br>------------------------------------------------------------------------------------------------------------------------------<br></p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">When i checked from the ARM Lowering part for generation of<br>  sub sp, sp, #16</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Emitted by,</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">  if (VARegSaveSize)<br>    emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize,        // --> VARegSaveSize is calculated in computeRegArea<br>                 MachineInstr::FrameSetup)<br><br>ARMTargetLowering::computeRegArea(..) {<br>  ...<br>  VARegSize = NumGPRs * 4;<br>  VARegSaveSize = (VARegSize + Align - 1) & ~(Align - 1);                 // --> 8 byte alignment done here<br>}</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Stack pointer decremented to NumGPRs*4 + alignment</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">NumGPRs = 3 registers</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">VARegSaveSize  = 16 (after considering 8 byte alignment )</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"><br>When the offset(#76) for the instruction, "ldr r1, [r11, #76] ; 0x4c"  is calculated, 4 bytes alignment is considered.<br>In prologue stackpointer calculation 8 byte alignment is considered.</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Due to this mimatch of alignment, If try to access any parameter after byval which results wrong value.</p><div style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"> <br class="webkit-block-placeholder"></div><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Issue(or offset of 4 bytes) wont occur if even number of register used for byval spilling.<br>ex:<span class="Apple-converted-space"> </span><br>struct S114 check114 (int a, struct S114 arg0, struct S114* arg1) { // accessing arg1 is fine in this case<br>.....<br>}</p><div style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"> <br class="webkit-block-placeholder"></div><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">Could someone comment on below queries about fixing the problem,</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">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?</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">2) We will leave alignment as it is but in prologue we will adjust SP once again, this is little meaningless.</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;">3) While accessing arg1 we will consider alignment and add extra offset -> looks better.</p><p style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"> 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 ?</p><div style="margin-top: 5px; font-family: Arial, arial; margin-bottom: 5px; font-size: 9pt;"> <br class="webkit-block-placeholder"></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;"> <br class="webkit-block-placeholder"></div><table id="confidentialsignimg"><tbody><tr><td namo_lock="" 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><201306181656803_BEI0XT4N.gif></span></p></td></tr></tbody></table>_______________________________________________<br>LLVM Developers mailing list<br><a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a><span class="Apple-converted-space"> </span>        <a href="http://llvm.cs.uiuc.edu/">http://llvm.cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a></div></blockquote></div><br></div></body></html>