Author: xiaohua_zhang
Date: 2011-06-28 10:09:38 -0400 (Tue, 28 Jun 2011)
New Revision: 3664

Modified:
   trunk/osprey/be/com/wn_lower.cxx
Log:
The small test case is:

#include <stdio.h>
int rval = 0;
typedef struct S { double i; } S;
S f(void);

typedef struct {
    int f1;
    struct S f2;
} S1;
S1 m;
struct S t =  { 0.0 };

int main(void)
{
        t.i = 12.345;
        m.f2 = f();   // return value should be in xmm0
        if (m.f2.i != t.i) {
           rval = -1;
           printf("Failed!\n");
        }
        return rval;
}

struct S f(void)
{
        return t;
}

The WHIRL tree for "m.f2 = f()" looks like:

MCALL 126 <1,53,f> # flags 0x7e {line: 1/20}
  MMLDID -1 <1,49,.preg_return_val> T<53,S,8>
MSTID 8 <1,54,m> T<55,.anonymous.1,8> <field_id:2> {line: 0/0}

After the RETURN_VAL & MLDID/MSTID lowering:

 MCALL 126 <1,53,f> # flags 0x7e {line: 1/20}
  I8I8LDID 1 <1,5,.preg_I8> T<5,.predef_I8,8> # $r1
 I8STID 8 <1,54,m> T<5,.predef_I8,8> {line: 0/0}
  F8F8LDID 17 <1,11,.preg_F8> T<11,.predef_F8,8> # $f0
 F8STID 16 <1,54,m> T<11,.predef_F8,8> {line: 0/0}

The return value (S) is returned by two register: $r1 and $f0.
By the ABI, the f()'s return value (type struct S) should be returned by one 
floating register $f0.
The problem is in lower_return_mstid(), which takes MSTID's type (S1) as return 
type, didn't 
consider the field (f2) it accessed. So it used the wrong type (S1)to get 
return info, and the 
return value for S2 is by register $r1 and $f0.

The fix is to get the accessed field type as return type.

Code Review: Jian-Xin Lai



Modified: trunk/osprey/be/com/wn_lower.cxx
===================================================================
--- trunk/osprey/be/com/wn_lower.cxx    2011-06-25 08:10:03 UTC (rev 3663)
+++ trunk/osprey/be/com/wn_lower.cxx    2011-06-28 14:09:38 UTC (rev 3664)
@@ -7239,7 +7239,12 @@
   ST *preg_st;
   WN *n_rhs;
   WN *wn = NULL;       // init to prevent upward-exposed use
-  RETURN_INFO return_info = Get_Return_Info(WN_ty(tree), Complex_Not_Simulated
+  TY_IDX ty_idx  = WN_ty(tree);
+
+  if (WN_field_id (tree) != 0)
+    ty_idx = get_field_type (ty_idx, WN_field_id (tree));
+
+  RETURN_INFO return_info = Get_Return_Info(ty_idx, Complex_Not_Simulated
 #ifdef TARG_X8664
                                            , last_call_ff2c_abi
 #endif
@@ -7260,7 +7265,7 @@
 #endif
     WN *awn = WN_CreateLda(OPR_LDA, Pointer_Mtype, MTYPE_V, 
                           WN_store_offset(tree), 
-                          Make_Pointer_Type(WN_ty(tree)), WN_st_idx(tree));
+                          Make_Pointer_Type(ty_idx), WN_st_idx(tree));
     awn = lower_expr(block, awn, actions);
     WN *n_call = add_fake_parm(call, awn, WN_ty(awn));
     WN_DELETE_FromBlock(block, call);
@@ -7277,9 +7282,9 @@
       mtype = RETURN_INFO_mtype(return_info, i);
       desc = mtype;
 #ifdef KEY
-      if (MTYPE_byte_size(mtype) > TY_size(WN_ty(tree)) && 
!MTYPE_float(mtype)){
+      if (MTYPE_byte_size(mtype) > TY_size(ty_idx) && !MTYPE_float(mtype)){
        desc = Mtype_AlignmentClass(1, MTYPE_type_class(mtype));
-       while (MTYPE_byte_size(desc) < TY_size(WN_ty(tree)))
+       while (MTYPE_byte_size(desc) < TY_size(ty_idx))
          desc = Mtype_next_alignment(desc);
       }
 #endif
@@ -7287,7 +7292,7 @@
 
 #if defined(TARG_PPC32)
       if (preg_st == Int_Preg) {
-        UINT rem = TY_size(WN_ty(tree)) - i * 4;
+        UINT rem = TY_size(ty_idx) - i * 4;
         if (1 == rem) desc = MTYPE_I1;
         if (2 == rem) desc = MTYPE_I2;
       }


------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to