Hi,

Could someone review the patch for open64 bug #969, #970? Thank you very much.

1. test case
#969 and #970 can be simplified to the following case:
struct I3 {
  int a, b, c;
};
extern struct I3 foo();
void bar() {
  struct I3 a;
  a = foo();
}

The struct I1 can also be replaced by:
struct F3 {
  float a, b, c;
};

2. IR dump
Open64 will allocate a temporary on stack for the return value. The IR
after MSTID lowering looks like:

 MCALL 126 <1,51,foo> # flags 0x7e {line: 1/7}
  I8I8LDID 1 <1,5,.preg_I8> T<5,.predef_I8,8> # $r1
 I8STID 0 <2,2,_temp_.Mreturn.foo0> T<5,.predef_I8,8> {line: 0/0}
  I8I8LDID 7 <1,5,.preg_I8> T<5,.predef_I8,8> # $r7
 I8STID 8 <2,2,_temp_.Mreturn.foo0> T<5,.predef_I8,8> {line: 0/0}

[2]: _temp_.Mreturn.foo0        <2,2> Variable of type I1 (#53, KIND_STRUCT)
                Address: 0(_temp_.Mreturn.foo0<2,2>)  Alignment: 8 bytes
                location: file (null), line 0
                Flags:  0x00400000 temp, XLOCAL
                Sclass: AUTO

[53]: I3            : (f: 0x1000 content_seen) size 12 M: STRUCT
             0  a               .predef_I4 (#4) align 4
                fl:0x0000
             4  b               .predef_I4 (#4) align 4
                fl:0x0000
             8  c               .predef_I4 (#4) align 4
                fl:0x0001 last_field

The size of _temp_.Mreturn.foo0 is only 12 byte. The I8STID will
overwrite some other variables on stack. For float struct F3, two
F8STID will be generated.

3. Patch
Index: osprey/be/com/wn_lower.cxx
===================================================================
--- osprey/be/com/wn_lower.cxx  (revision 3998)
+++ osprey/be/com/wn_lower.cxx  (working copy)
@@ -7299,6 +7299,7 @@
   }
   else { // return via 1 or more return registers
     TYPE_ID mtype, desc;
+    WN_OFFSET st_ofst = WN_store_offset(tree);
     for (INT32 i = 0; i < RETURN_INFO_count(return_info); i++) {
       if (i != 0)
         WN_INSERT_BlockLast (block, wn); // insert the last STID created
@@ -7334,8 +7335,9 @@
       }
 #endif
       wn = WN_CreateStid(OPR_STID, MTYPE_V, desc,
-                        WN_store_offset(tree)+i*MTYPE_byte_size(mtype),
+                        st_ofst,
                         WN_st_idx(tree), Be_Type_Tbl(desc), n_rhs);
+      st_ofst += MTYPE_byte_size(mtype);
       wn  = lower_store (block, wn, actions);
       WN_Set_Linenum(wn, current_srcpos);
     }
@@ -7394,6 +7396,7 @@
   }
   else { // return via 1 or more return registers
     WN *base_expr;
+    WN_OFFSET st_ofst = WN_store_offset(tree);
     for (INT32 i = 0; i < RETURN_INFO_count(return_info); i++) {
       if (i != 0)
         WN_INSERT_BlockLast (block, wn); // insert the last STID created
@@ -7406,8 +7409,9 @@
 // OSP-438: The type of Istore node should be a pointer to mtype.
 // (Previously, we just use Be_Type_Tbl(mtype) as the type of Istore).
       wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, mtype,
-                          WN_store_offset(tree)+i*MTYPE_byte_size(mtype),
+                          st_ofst,
                           Make_Pointer_Type(Be_Type_Tbl(mtype),
FALSE), n_rhs, base_expr);
+      st_ofst += MTYPE_byte_size(mtype);
       WN_Set_Linenum(wn, WN_Get_Linenum(tree));
       wn  = lower_store (block, wn, actions);
       WN_Set_Linenum (wn, WN_Get_Linenum(tree));
@@ -12285,6 +12289,7 @@
                ("expected RETURN_VAL kid not type M"));

        algn = TY_align(ty_idx);
+        WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
        for (i = 0; i < RETURN_INFO_count(return_info); i++) {
          mtype = RETURN_INFO_mtype(return_info, i);
          ty_idx_used = Be_Type_Tbl(mtype);
@@ -12312,15 +12317,14 @@
 #endif
 #if defined(TARG_PPC32)
            n_rhs = WN_CreateLdid (OPR_LDID, mtype, desc,
-                                  WN_load_offset(o_rhs)
-                                  + i * MTYPE_byte_size(mtype),
+                                  ld_ofst,
                                   WN_st_idx(o_rhs), ty_idx_used);
 #else
            n_rhs = WN_CreateLdid (OPR_LDID, mtype, mtype,
-                                  WN_load_offset(o_rhs)
-                                  + i * MTYPE_byte_size(mtype),
+                                  ld_ofst,
                                   WN_st_idx(o_rhs), ty_idx_used);
 #endif
+          ld_ofst += MTYPE_byte_size(mtype);
          wn = WN_CreateStid(OPR_STID, MTYPE_V, mtype, preg, preg_st,
                             Be_Type_Tbl(mtype), n_rhs);
          WN_Set_Linenum(wn, current_srcpos);  // Bug 1268
@@ -12332,6 +12336,7 @@
                ("expected RETURN_VAL kid not type M"));

        algn = TY_align(ty_idx);
+        WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
        for (i = 0; i < RETURN_INFO_count(return_info); i++) {
           mtype = RETURN_INFO_mtype(return_info, i);
          ty_idx_used = Be_Type_Tbl(mtype);
@@ -12340,10 +12345,10 @@
            n_rhs = WN_kid0(o_rhs);
          else n_rhs = WN_COPY_Tree(WN_kid0(o_rhs));
          n_rhs = WN_CreateIload(OPR_ILOAD, mtype, mtype,
-                                WN_load_offset(o_rhs)
-                                  + i * MTYPE_byte_size(mtype),
+                                ld_ofst,
                                 ty_idx_used,
                                 Make_Pointer_Type(ty_idx_used), n_rhs);
+          ld_ofst += MTYPE_byte_size(mtype);
          n_rhs = lower_expr(block, n_rhs, actions);
          preg    = RETURN_INFO_preg (return_info, i);
           preg_st = Standard_Preg_For_Mtype(mtype);
@@ -12357,6 +12362,7 @@
        Is_True(WN_operator(WN_kid1(o_rhs)) == OPR_INTCONST,
                ("expected RETURN_VAL's MLOAD kid to be of constant size"));
        algn = TY_align(TY_pointed(WN_load_addr_ty(o_rhs)));
+        WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
        for (i = 0; i < RETURN_INFO_count(return_info); i++) {
           mtype = RETURN_INFO_mtype(return_info, i);
          ty_idx_used = Be_Type_Tbl(mtype);
@@ -12365,10 +12371,10 @@
            n_rhs = WN_kid0(o_rhs);
          else n_rhs = WN_COPY_Tree(WN_kid0(o_rhs));
          n_rhs = WN_CreateIload(OPR_ILOAD, mtype, mtype,
-                                WN_load_offset(o_rhs)
-                                  + i * MTYPE_byte_size(mtype),
+                                ld_ofst,
                                 ty_idx_used,
                                 Make_Pointer_Type(ty_idx_used), n_rhs);
+          ld_ofst += MTYPE_byte_size(mtype);
          n_rhs = lower_expr(block, n_rhs, actions);
          preg    = RETURN_INFO_preg (return_info, i);
           preg_st = Standard_Preg_For_Mtype(mtype);
Index: osprey/common/com/x8664/targ_sim.cxx
===================================================================
--- osprey/common/com/x8664/targ_sim.cxx        (revision 3998)
+++ osprey/common/com/x8664/targ_sim.cxx        (working copy)
@@ -673,13 +673,13 @@
               }
               else {
                 if (classes[0] == X86_64_SSE_CLASS) {
-                 info.mtype[0] = SIM_INFO.dbl_type;
+                 info.mtype[0] = (size > 4) ? MTYPE_F8 : MTYPE_F4;
                  info.preg[0] = PR_first_reg(SIM_INFO.dbl_results);
                  next_float_return_num = PR_last_reg(SIM_INFO.dbl_results);
                  next_int_return_num = PR_first_reg(SIM_INFO.int_results);
                }
                else {
-                 info.mtype[0] = SIM_INFO.int_type;
+                 info.mtype[0] = (size > 4) ? MTYPE_I8 : MTYPE_I4;
                  info.preg[0] = PR_first_reg(SIM_INFO.int_results);
                  next_float_return_num = PR_first_reg(SIM_INFO.dbl_results);
                  next_int_return_num = PR_last_reg(SIM_INFO.int_results);
@@ -687,11 +687,11 @@

                if (n > 1) {
                  if (classes[1] == X86_64_SSE_CLASS) {
-                   info.mtype[1] = SIM_INFO.dbl_type;
+                   info.mtype[1] = (size > 12) ? MTYPE_F8 : MTYPE_F4;
                    info.preg[1] = next_float_return_num;
                  }
                  else {
-                   info.mtype[1] = SIM_INFO.int_type;
+                   info.mtype[1] = (size > 12) ? MTYPE_I8 : MTYPE_I4;
                    info.preg[1] = next_int_return_num;
                  }
                }


-- 
Regards,
Lai Jian-Xin

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to