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
[email protected]
https://lists.sourceforge.net/lists/listinfo/open64-devel