<HTML><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>Hi,</P>
<P> </P>
<P>Handling of pass by val of struct size >64 bytes case is seems wrong for arm targets.</P>
<P><STRONG></STRONG> </P>
<P><STRONG>Summary:</STRONG></P>
<P>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>Stack pointer adjustment done by prologue emitter and offset used to access function params have different logics for calculaton.</P>
<P><STRONG></STRONG> </P>
<P><STRONG>Test code<BR></STRONG>---------------------------------------------------------------<BR>#include <stdio.h><BR>struct S114 {<BR>  char a[67];<BR>}a114[5];</P>
<P>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>  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>
<P> </P>
<P><STRONG>Output on arm :<BR></STRONG># ./check114.exe <BR>values 0x10861, 0x4071706f<BR>which is wrong.</P>
<P> </P>
<P>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>---------------------------------------------------------------</P>
<P> </P>
<P>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>@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>  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>Correct value is at location {[R11+4c]<STRONG>+4</STRONG>} --> 0x00010861, 4 bytes offset going wrong.<BR>------------------------------------------------------------------------------------------------------------------------------<BR></P>
<P>When i checked from the ARM Lowering part for generation of<BR>  sub sp, sp, #16</P>
<P>Emitted by,</P>
<P>  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>Stack pointer decremented to NumGPRs*4 + alignment</P>
<P>NumGPRs = 3 registers</P>
<P>VARegSaveSize  = 16 (after considering 8 byte alignment )</P>
<P><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>Due to this mimatch of alignment, If try to access any parameter after byval which results wrong value.</P>
<P> </P>
<P>Issue(or offset of 4 bytes) wont occur if even number of register used for byval spilling.<BR>ex: <BR>struct S114 check114 (int a, struct S114 arg0, struct S114* arg1) { // accessing arg1 is fine in this case<BR>.....<BR>}</P>
<P> </P>
<P>Could someone comment on below queries about fixing the problem,</P>
<P>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>2) We will leave alignment as it is but in prologue we will adjust SP once again, this is little meaningless.</P>
<P>3) While accessing arg1 we will consider alignment and add extra offset -> looks better.</P>
<P> 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>
<P> </P>
<P>Regards,<BR>Rajesh</P>
<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=24fd7bfac5a29b9fdb21ce108665882a89220c9849ece6ef4b8edb9941f8601fb846c8a3750bbecdd1479191c8e13bdda4db4f4540c3ce487d6f8b298eafad26cf878f9a26ce15a0' border=0 width=0 height=0 style='display:none'>