diff options
author | Richard Biener <rguenther@suse.de> | 2013-11-08 12:49:10 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-11-08 12:49:10 +0000 |
commit | cb3d1e3e87f97eca6c52f7f49d2218e24c6ec39e (patch) | |
tree | b2d20453dba3fa0b4453f067ab55e56ca8bf280f /gcc/tree-predcom.c | |
parent | 05ff7470028712278048d02c87c6e7682b45e099 (diff) | |
download | gcc-cb3d1e3e87f97eca6c52f7f49d2218e24c6ec39e.zip gcc-cb3d1e3e87f97eca6c52f7f49d2218e24c6ec39e.tar.gz gcc-cb3d1e3e87f97eca6c52f7f49d2218e24c6ec39e.tar.bz2 |
re PR tree-optimization/59047 (wrong code for bitfields at -O3 on x86_64-linux-gnu)
2013-11-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/59047
* tree-predcom.c (ref_at_iteration): Handle bitfield accesses
properly.
* gcc.dg/torture/pr59047.c: New testcase.
From-SVN: r204566
Diffstat (limited to 'gcc/tree-predcom.c')
-rw-r--r-- | gcc/tree-predcom.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 3358f8b..6084cf6 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1353,10 +1353,24 @@ ref_at_iteration (data_reference_p dr, int iter, gimple_seq *stmts) tree addr = fold_build_pointer_plus (DR_BASE_ADDRESS (dr), off); addr = force_gimple_operand_1 (addr, stmts, is_gimple_mem_ref_addr, NULL_TREE); - return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)), - addr, - fold_convert (reference_alias_ptr_type (DR_REF (dr)), - coff)); + tree alias_ptr = fold_convert (reference_alias_ptr_type (DR_REF (dr)), coff); + /* While data-ref analysis punts on bit offsets it still handles + bitfield accesses at byte boundaries. Cope with that. Note that + we cannot simply re-apply the outer COMPONENT_REF because the + byte-granular portion of it is already applied via DR_INIT and + DR_OFFSET, so simply build a BIT_FIELD_REF knowing that the bits + start at offset zero. */ + if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1))) + { + tree field = TREE_OPERAND (DR_REF (dr), 1); + return build3 (BIT_FIELD_REF, TREE_TYPE (DR_REF (dr)), + build2 (MEM_REF, DECL_BIT_FIELD_TYPE (field), + addr, alias_ptr), + DECL_SIZE (field), bitsize_zero_node); + } + else + return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)), addr, alias_ptr); } /* Get the initialization expression for the INDEX-th temporary variable |