aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-predcom.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-11-08 12:49:10 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-11-08 12:49:10 +0000
commitcb3d1e3e87f97eca6c52f7f49d2218e24c6ec39e (patch)
treeb2d20453dba3fa0b4453f067ab55e56ca8bf280f /gcc/tree-predcom.c
parent05ff7470028712278048d02c87c6e7682b45e099 (diff)
downloadgcc-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.c22
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