The following adds some more checks to the MEM_REF -> vector BIT_FIELD_REF rewriting and adjusts another copy with the poly-int variant.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2018-02-16 Richard Biener <rguent...@suse.de> PR tree-optimization/84417 * tree-ssa.c (non_rewritable_mem_ref_base): Properly constrain the MEM_REF offset when conversion to BIT_FIELD_REF is desired. (non_rewritable_lvalue_p): Likewise, use poly-ints. * gcc.dg/torture/pr84417.c: New testcase. Index: gcc/tree-ssa.c =================================================================== --- gcc/tree-ssa.c (revision 257724) +++ gcc/tree-ssa.c (working copy) @@ -1434,6 +1434,7 @@ non_rewritable_mem_ref_base (tree ref) || TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE) && useless_type_conversion_p (TREE_TYPE (base), TREE_TYPE (TREE_TYPE (decl))) + && known_ge (mem_ref_offset (base), 0) && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))), mem_ref_offset (base)) && multiple_of_p (sizetype, TREE_OPERAND (base, 1), @@ -1516,11 +1517,11 @@ non_rewritable_lvalue_p (tree lhs) && TYPE_MODE (TREE_TYPE (decl)) != BLKmode && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)), TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))), 0) - && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1)) - && tree_int_cst_lt (TREE_OPERAND (lhs, 1), - TYPE_SIZE_UNIT (TREE_TYPE (decl))) - && (tree_to_uhwi (TREE_OPERAND (lhs, 1)) - % tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0) + && known_ge (mem_ref_offset (lhs), 0) + && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))), + mem_ref_offset (lhs)) + && multiple_of_p (sizetype, TREE_OPERAND (lhs, 1), + TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) return false; } Index: gcc/testsuite/gcc.dg/torture/pr84417.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr84417.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr84417.c (working copy) @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target int32plus } */ + +void fn1() +{ + __attribute__((__vector_size__(sizeof(double)))) double x; + double *a = (double *)&x; + *a + *(a + 8446744073709551615LL); +}