This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR43783 - work around PR43798
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 19 Apr 2010 15:33:58 +0200 (CEST)
- Subject: [PATCH] Fix PR43783 - work around PR43798
With 4.5 PRE and VN start to emit operands two and three for all
ARRAY_REFs (which in the end I'd like to enforce throughout all
the middle-end). Unfortunately this is not possible for arrays
of structs with bigger than required alignment due to PR43798
and so we miscompile libbid (ugh).
This patch works around this issue by not emitting those operands
when possible again.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk,
will apply to the branch pending testing.
Thanks,
Richard.
2010-04-19 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43783
* tree-ssa-pre.c (create_component_ref_by_pieces_1): Drop
constant ARRAY_REF operands two and three if possible.
* gcc.c-torture/execute/pr43783.c: New testcase.
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c (revision 158507)
--- gcc/tree-ssa-pre.c (working copy)
*************** create_component_ref_by_pieces_1 (basic_
*** 2779,2800 ****
return NULL_TREE;
if (genop2)
{
! op2expr = get_or_alloc_expr_for (genop2);
! genop2 = find_or_generate_expression (block, op2expr, stmts,
! domstmt);
! if (!genop2)
! return NULL_TREE;
}
if (genop3)
{
tree elmt_type = TREE_TYPE (TREE_TYPE (genop0));
! genop3 = size_binop (EXACT_DIV_EXPR, genop3,
! size_int (TYPE_ALIGN_UNIT (elmt_type)));
! op3expr = get_or_alloc_expr_for (genop3);
! genop3 = find_or_generate_expression (block, op3expr, stmts,
! domstmt);
! if (!genop3)
! return NULL_TREE;
}
return build4 (currop->opcode, currop->type, genop0, genop1,
genop2, genop3);
--- 2779,2815 ----
return NULL_TREE;
if (genop2)
{
! /* Drop zero minimum index. */
! if (tree_int_cst_equal (genop2, integer_zero_node))
! genop2 = NULL_TREE;
! else
! {
! op2expr = get_or_alloc_expr_for (genop2);
! genop2 = find_or_generate_expression (block, op2expr, stmts,
! domstmt);
! if (!genop2)
! return NULL_TREE;
! }
}
if (genop3)
{
tree elmt_type = TREE_TYPE (TREE_TYPE (genop0));
! /* We can't always put a size in units of the element alignment
! here as the element alignment may be not visible. See
! PR43783. Simply drop the element size for constant
! sizes. */
! if (tree_int_cst_equal (genop3, TYPE_SIZE_UNIT (elmt_type)))
! genop3 = NULL_TREE;
! else
! {
! genop3 = size_binop (EXACT_DIV_EXPR, genop3,
! size_int (TYPE_ALIGN_UNIT (elmt_type)));
! op3expr = get_or_alloc_expr_for (genop3);
! genop3 = find_or_generate_expression (block, op3expr, stmts,
! domstmt);
! if (!genop3)
! return NULL_TREE;
! }
}
return build4 (currop->opcode, currop->type, genop0, genop1,
genop2, genop3);
Index: gcc/testsuite/gcc.c-torture/execute/pr43783.c
===================================================================
*** gcc/testsuite/gcc.c-torture/execute/pr43783.c (revision 0)
--- gcc/testsuite/gcc.c-torture/execute/pr43783.c (revision 0)
***************
*** 0 ****
--- 1,21 ----
+ typedef __attribute__((aligned(16)))
+ struct {
+ unsigned long long w[3];
+ } UINT192;
+
+ UINT192 bid_Kx192[32];
+
+ extern void abort (void);
+
+ int main()
+ {
+ int i = 0;
+ unsigned long x = 0;
+ for (i = 0; i < 32; ++i)
+ bid_Kx192[i].w[1] = i == 1;
+ for (i = 0; i < 32; ++i)
+ x += bid_Kx192[1].w[1];
+ if (x != 32)
+ abort ();
+ return 0;
+ }