diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57a0bd7d533..9a7155fbd99 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2009-10-28 Richard Guenther + + PR middle-end/41855 + * tree-ssa-alias.c (refs_may_alias_p_1): Deal with CONST_DECLs + (ref_maybe_used_by_call_p_1): Fix bcopy handling. + (call_may_clobber_ref_p_1): Likewise. + * tree-ssa-structalias.c (find_func_aliases): Likewise. + * alias.c (nonoverlapping_memrefs_p): Deal with CONST_DECLs. + 2009-10-28 Paolo Bonzini PR rtl-optimization/41812 diff --git a/gcc/alias.c b/gcc/alias.c index 40226f26b17..1d4290f7848 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -2200,6 +2200,13 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y) if (! DECL_P (exprx) || ! DECL_P (expry)) return 0; + /* With invalid code we can end up storing into the constant pool. + Bail out to avoid ICEing when creating RTL for this. + See gfortran.dg/lto/20091028-2_0.f90. */ + if (TREE_CODE (exprx) == CONST_DECL + || TREE_CODE (expry) == CONST_DECL) + return 1; + rtlx = DECL_RTL (exprx); rtly = DECL_RTL (expry); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1d59b71e4eb..9311bac87b7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2009-10-28 Richard Guenther + + PR middle-end/41855 + * gfortran.dg/lto/20091028-1_0.f90: New testcase. + * gfortran.dg/lto/20091028-1_1.c: Likewise. + * gfortran.dg/lto/20091028-2_0.f90: Likewise. + * gfortran.dg/lto/20091028-2_1.c: Likewise. + 2009-10-28 Paolo Bonzini PR rtl-optimization/39715 diff --git a/gcc/testsuite/gfortran.dg/lto/20091028-1_0.f90 b/gcc/testsuite/gfortran.dg/lto/20091028-1_0.f90 new file mode 100644 index 00000000000..57c1b1f6028 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20091028-1_0.f90 @@ -0,0 +1,9 @@ +! { dg-lto-do link } +! { dg-extra-ld-options "-r -nostdlib -finline-functions" } + +SUBROUTINE int_gen_ti_header_char( hdrbuf, hdrbufsize, itypesize, & + DataHandle, Element, VarName, Data, code ) + CALL int_gen_ti_header_c ( hdrbuf, hdrbufsize, itypesize, 1, & + DataHandle, DummyData, DummyCount, code ) +END SUBROUTINE int_gen_ti_header_char + diff --git a/gcc/testsuite/gfortran.dg/lto/20091028-1_1.c b/gcc/testsuite/gfortran.dg/lto/20091028-1_1.c new file mode 100644 index 00000000000..b3afc23fb8e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20091028-1_1.c @@ -0,0 +1,11 @@ +extern void bcopy(const void *, void *, __SIZE_TYPE__ n); +char *p; +int int_gen_ti_header_c_ (char * hdrbuf, int * hdrbufsize, + int * itypesize, int * typesize, + int * DataHandle, char * Data, + int * Count, int * code) +{ + bcopy (typesize, p, sizeof(int)) ; + bcopy (Data, p, *Count * *typesize) ; +} + diff --git a/gcc/testsuite/gfortran.dg/lto/20091028-2_0.f90 b/gcc/testsuite/gfortran.dg/lto/20091028-2_0.f90 new file mode 100644 index 00000000000..57c1b1f6028 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20091028-2_0.f90 @@ -0,0 +1,9 @@ +! { dg-lto-do link } +! { dg-extra-ld-options "-r -nostdlib -finline-functions" } + +SUBROUTINE int_gen_ti_header_char( hdrbuf, hdrbufsize, itypesize, & + DataHandle, Element, VarName, Data, code ) + CALL int_gen_ti_header_c ( hdrbuf, hdrbufsize, itypesize, 1, & + DataHandle, DummyData, DummyCount, code ) +END SUBROUTINE int_gen_ti_header_char + diff --git a/gcc/testsuite/gfortran.dg/lto/20091028-2_1.c b/gcc/testsuite/gfortran.dg/lto/20091028-2_1.c new file mode 100644 index 00000000000..496aaf11220 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20091028-2_1.c @@ -0,0 +1,11 @@ +extern void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n); +char *p; +int int_gen_ti_header_c_ (char * hdrbuf, int * hdrbufsize, + int * itypesize, int * typesize, + int * DataHandle, char * Data, + int * Count, int * code) +{ + memcpy (typesize, p, sizeof(int)) ; + memcpy (Data, p, *Count * *typesize) ; +} + diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index fbd047085da..4c052be418f 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -776,12 +776,14 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) || SSA_VAR_P (ref1->ref) || handled_component_p (ref1->ref) || INDIRECT_REF_P (ref1->ref) - || TREE_CODE (ref1->ref) == TARGET_MEM_REF) + || TREE_CODE (ref1->ref) == TARGET_MEM_REF + || TREE_CODE (ref1->ref) == CONST_DECL) && (!ref2->ref || SSA_VAR_P (ref2->ref) || handled_component_p (ref2->ref) || INDIRECT_REF_P (ref2->ref) - || TREE_CODE (ref2->ref) == TARGET_MEM_REF)); + || TREE_CODE (ref2->ref) == TARGET_MEM_REF + || TREE_CODE (ref2->ref) == CONST_DECL)); /* Decompose the references into their base objects and the access. */ base1 = ao_ref_base (ref1); @@ -798,6 +800,8 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) which is seen as a struct copy. */ if (TREE_CODE (base1) == SSA_NAME || TREE_CODE (base2) == SSA_NAME + || TREE_CODE (base1) == CONST_DECL + || TREE_CODE (base2) == CONST_DECL || is_gimple_min_invariant (base1) || is_gimple_min_invariant (base2)) return false; @@ -934,7 +938,6 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref) their first argument. */ case BUILT_IN_STRCPY: case BUILT_IN_STRNCPY: - case BUILT_IN_BCOPY: case BUILT_IN_MEMCPY: case BUILT_IN_MEMMOVE: case BUILT_IN_MEMPCPY: @@ -952,6 +955,15 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref) size); return refs_may_alias_p_1 (&dref, ref, false); } + case BUILT_IN_BCOPY: + { + ao_ref dref; + tree size = gimple_call_arg (call, 2); + ao_ref_init_from_ptr_and_size (&dref, + gimple_call_arg (call, 0), + size); + return refs_may_alias_p_1 (&dref, ref, false); + } /* The following builtins do not read from memory. */ case BUILT_IN_FREE: case BUILT_IN_MEMSET: @@ -1151,7 +1163,6 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref) their first argument. */ case BUILT_IN_STRCPY: case BUILT_IN_STRNCPY: - case BUILT_IN_BCOPY: case BUILT_IN_MEMCPY: case BUILT_IN_MEMMOVE: case BUILT_IN_MEMPCPY: @@ -1170,6 +1181,15 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref) size); return refs_may_alias_p_1 (&dref, ref, false); } + case BUILT_IN_BCOPY: + { + ao_ref dref; + tree size = gimple_call_arg (call, 2); + ao_ref_init_from_ptr_and_size (&dref, + gimple_call_arg (call, 1), + size); + return refs_may_alias_p_1 (&dref, ref, false); + } /* Freeing memory kills the pointed-to memory. More importantly the call has to serve as a barrier for moving loads and stores across it. */ diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 7b33936dfd7..74dc6d2c1ba 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -3687,8 +3687,10 @@ find_func_aliases (gimple origt) case BUILT_IN_STRNCAT: { tree res = gimple_call_lhs (t); - tree dest = gimple_call_arg (t, 0); - tree src = gimple_call_arg (t, 1); + tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl) + == BUILT_IN_BCOPY ? 1 : 0)); + tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl) + == BUILT_IN_BCOPY ? 0 : 1)); if (res != NULL_TREE) { get_constraint_for (res, &lhsc);