Commit 64ea4e15 by Richard Biener Committed by Richard Biener

re PR tree-optimization/70497 (Missed CSE of subregs on GIMPLE)

2016-05-10  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/70497
	PR tree-optimization/28367
	* tree-ssa-sccvn.c (vn_nary_build_or_lookup): New function
	split out from ...
	(visit_reference_op_load): ... here.
	(vn_reference_lookup_3): Use it to handle subreg-like accesses
	with simplified BIT_FIELD_REFs.
	* tree-ssa-pre.c (eliminate_insert): Handle inserting BIT_FIELD_REFs.
	* tree-complex.c (extract_component): Handle BIT_FIELD_REFs
	correctly.

	* gcc.dg/torture/20160404-1.c: New testcase.
	* gcc.dg/tree-ssa/ssa-fre-54.c: Likewise.
	* gcc.dg/tree-ssa/ssa-fre-55.c: Likewise.

From-SVN: r236066
parent 5a96dae3
2016-05-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/70497
PR tree-optimization/28367
* tree-ssa-sccvn.c (vn_nary_build_or_lookup): New function
split out from ...
(visit_reference_op_load): ... here.
(vn_reference_lookup_3): Use it to handle subreg-like accesses
with simplified BIT_FIELD_REFs.
* tree-ssa-pre.c (eliminate_insert): Handle inserting BIT_FIELD_REFs.
* tree-complex.c (extract_component): Handle BIT_FIELD_REFs
correctly.
2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com> 2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com>
* dwarf2out.c (add_abstract_origin_attribute): Adjust * dwarf2out.c (add_abstract_origin_attribute): Adjust
......
2016-05-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/70497
PR tree-optimization/28367
* gcc.dg/torture/20160404-1.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-54.c: Likewise.
* gcc.dg/tree-ssa/ssa-fre-55.c: Likewise.
2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com> 2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com>
* gcc.dg/debug/dwarf2/nested_fun.c: New testcase. * gcc.dg/debug/dwarf2/nested_fun.c: New testcase.
......
/* { dg-do compile } */
typedef __UINT64_TYPE__ UINT64;
typedef union {
struct {
unsigned short lo4;
unsigned short lo3;
unsigned short lo2;
unsigned short lo1;
} i;
long double f;
} BID_BINARY80LDOUBLE;
UINT64 __binary80_to_bid32 (long double x)
{
BID_BINARY80LDOUBLE x_in;
x_in.f = x;
return (x_in.i.lo4
+ ((UINT64)x_in.i.lo3 << 16)
+ ((UINT64)x_in.i.lo2 << 32)
+ ((UINT64)x_in.i.lo1 << 48));
}
/* { dg-do run } */
/* { dg-require-effective-target int32plus } */
/* { dg-options "-O -fdump-tree-fre1 -fdump-tree-dse1" } */
extern void abort (void);
union U { int i; char c[4]; short s[2]; };
char __attribute__((noinline,noclone)) foo(int i)
{
union U u;
u.i = i;
/* This should be equivalent to (char) i. */
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
return u.c[0];
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
return u.c[3];
#else
return 0x04;
#endif
}
short __attribute__((noinline,noclone)) baz(int i)
{
union U u;
u.i = i;
/* This should be equivalent to (char) i. */
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
return u.s[0];
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
return u.s[1];
#else
return 0x0304;
#endif
}
char __attribute__((noinline,noclone)) bar(int j)
{
union U u;
u.i = j;
/* This gets simplified to a BIT_FIELD_REF. */
return u.c[2];
}
int main()
{
if (foo (0x01020304) != 0x04)
abort ();
if (baz (0x01020304) != 0x0304)
abort ();
return 0;
}
/* { dg-final { scan-tree-dump "\\(char\\) i_" "fre1" } } */
/* { dg-final { scan-tree-dump "\\(short int\\) i_" "fre1" } } */
/* { dg-final { scan-tree-dump-not "u.i =" "dse1" } } */
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-optimized" } */
typedef int v4si __attribute__((vector_size(16)));
int f(v4si t)
{
union {
v4si t1;
int t2[4];
} u;
u.t1 = t;
return u.t2[1];
}
/* { dg-final { scan-tree-dump-not "u;" "optimized" } } */
/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 1 "optimized" } } */
...@@ -604,6 +604,21 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p, ...@@ -604,6 +604,21 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
case COMPLEX_EXPR: case COMPLEX_EXPR:
gcc_unreachable (); gcc_unreachable ();
case BIT_FIELD_REF:
{
tree inner_type = TREE_TYPE (TREE_TYPE (t));
t = unshare_expr (t);
TREE_TYPE (t) = inner_type;
TREE_OPERAND (t, 1) = TYPE_SIZE (inner_type);
if (imagpart_p)
TREE_OPERAND (t, 2) = size_binop (PLUS_EXPR, TREE_OPERAND (t, 2),
TYPE_SIZE (inner_type));
if (gimple_p)
t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
GSI_SAME_STMT);
return t;
}
case VAR_DECL: case VAR_DECL:
case RESULT_DECL: case RESULT_DECL:
case PARM_DECL: case PARM_DECL:
......
...@@ -3855,19 +3855,28 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val) ...@@ -3855,19 +3855,28 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val)
gimple *stmt = gimple_seq_first_stmt (VN_INFO (val)->expr); gimple *stmt = gimple_seq_first_stmt (VN_INFO (val)->expr);
if (!is_gimple_assign (stmt) if (!is_gimple_assign (stmt)
|| (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)) || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
&& gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR)) && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR
&& gimple_assign_rhs_code (stmt) != BIT_FIELD_REF))
return NULL_TREE; return NULL_TREE;
tree op = gimple_assign_rhs1 (stmt); tree op = gimple_assign_rhs1 (stmt);
if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR) if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
|| gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
op = TREE_OPERAND (op, 0); op = TREE_OPERAND (op, 0);
tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (op) : op; tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (op) : op;
if (!leader) if (!leader)
return NULL_TREE; return NULL_TREE;
gimple_seq stmts = NULL; gimple_seq stmts = NULL;
tree res = gimple_build (&stmts, gimple_assign_rhs_code (stmt), tree res;
TREE_TYPE (val), leader); if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
res = gimple_build (&stmts, BIT_FIELD_REF,
TREE_TYPE (val), leader,
TREE_OPERAND (gimple_assign_rhs1 (stmt), 1),
TREE_OPERAND (gimple_assign_rhs1 (stmt), 2));
else
res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
TREE_TYPE (val), leader);
gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
VN_INFO_GET (res)->valnum = val; VN_INFO_GET (res)->valnum = val;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment