This fixes a part of PR81502 where we fail to re-write a variable into SSA because we don't know how to re-write a bit insertion into a BIT_INSERT_EXPR.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2017-07-27 Richard Biener <rguent...@suse.de> PR tree-optimization/81502 * tree-ssa.c (non_rewritable_lvalue_p): Handle BIT_INSERT_EXPR with incompatible but same sized type. (execute_update_addresses_taken): Likewise. * gcc.target/i386/vect-insert-1.c: New testcase. Index: gcc/tree-ssa.c =================================================================== --- gcc/tree-ssa.c (revision 250563) +++ gcc/tree-ssa.c (working copy) @@ -1513,8 +1513,8 @@ non_rewritable_lvalue_p (tree lhs) if (DECL_P (decl) && VECTOR_TYPE_P (TREE_TYPE (decl)) && TYPE_MODE (TREE_TYPE (decl)) != BLKmode - && types_compatible_p (TREE_TYPE (lhs), - TREE_TYPE (TREE_TYPE (decl))) + && 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))) @@ -1529,8 +1529,9 @@ non_rewritable_lvalue_p (tree lhs) && DECL_P (TREE_OPERAND (lhs, 0)) && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))) && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode - && types_compatible_p (TREE_TYPE (lhs), - TREE_TYPE (TREE_TYPE (TREE_OPERAND (lhs, 0)))) + && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)), + TYPE_SIZE_UNIT + (TREE_TYPE (TREE_TYPE (TREE_OPERAND (lhs, 0)))), 0) && (tree_to_uhwi (TREE_OPERAND (lhs, 2)) % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs)))) == 0) return false; @@ -1812,14 +1813,26 @@ execute_update_addresses_taken (void) DECL_UID (TREE_OPERAND (lhs, 0))) && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))) && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode - && types_compatible_p (TREE_TYPE (lhs), - TREE_TYPE (TREE_TYPE - (TREE_OPERAND (lhs, 0)))) + && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)), + TYPE_SIZE_UNIT (TREE_TYPE + (TREE_TYPE (TREE_OPERAND (lhs, 0)))), + 0) && (tree_to_uhwi (TREE_OPERAND (lhs, 2)) % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs))) == 0)) { tree var = TREE_OPERAND (lhs, 0); tree val = gimple_assign_rhs1 (stmt); + if (! types_compatible_p (TREE_TYPE (TREE_TYPE (var)), + TREE_TYPE (val))) + { + tree tem = make_ssa_name (TREE_TYPE (TREE_TYPE (var))); + gimple *pun + = gimple_build_assign (tem, + build1 (VIEW_CONVERT_EXPR, + TREE_TYPE (tem), val)); + gsi_insert_before (&gsi, pun, GSI_SAME_STMT); + val = tem; + } tree bitpos = TREE_OPERAND (lhs, 2); gimple_assign_set_lhs (stmt, var); gimple_assign_set_rhs_with_ops @@ -1839,8 +1852,9 @@ execute_update_addresses_taken (void) && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym)) && VECTOR_TYPE_P (TREE_TYPE (sym)) && TYPE_MODE (TREE_TYPE (sym)) != BLKmode - && types_compatible_p (TREE_TYPE (lhs), - TREE_TYPE (TREE_TYPE (sym))) + && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)), + TYPE_SIZE_UNIT + (TREE_TYPE (TREE_TYPE (sym))), 0) && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1)) && tree_int_cst_lt (TREE_OPERAND (lhs, 1), TYPE_SIZE_UNIT (TREE_TYPE (sym))) @@ -1848,6 +1862,17 @@ execute_update_addresses_taken (void) % tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0) { tree val = gimple_assign_rhs1 (stmt); + if (! types_compatible_p (TREE_TYPE (val), + TREE_TYPE (TREE_TYPE (sym)))) + { + tree tem = make_ssa_name (TREE_TYPE (TREE_TYPE (sym))); + gimple *pun + = gimple_build_assign (tem, + build1 (VIEW_CONVERT_EXPR, + TREE_TYPE (tem), val)); + gsi_insert_before (&gsi, pun, GSI_SAME_STMT); + val = tem; + } tree bitpos = wide_int_to_tree (bitsizetype, mem_ref_offset (lhs) * BITS_PER_UNIT); Index: gcc/testsuite/gcc.target/i386/vect-insert-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/vect-insert-1.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/vect-insert-1.c (working copy) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -msse2 -fdump-tree-ccp1" } */ + +typedef int v4si __attribute__((vector_size(16))); + +float f; + +v4si foo (v4si a) +{ + __builtin_memcpy ((char *)&a + 4, &f, 4); + return a; +} + +/* { dg-final { scan-tree-dump "Now a gimple register: a" "ccp1" } } */ +/* { dg-final { scan-tree-dump "BIT_INSERT_EXPR <a" "ccp1" } } */