summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/alias.c7
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gfortran.dg/lto/20091028-1_0.f909
-rw-r--r--gcc/testsuite/gfortran.dg/lto/20091028-1_1.c11
-rw-r--r--gcc/testsuite/gfortran.dg/lto/20091028-2_0.f909
-rw-r--r--gcc/testsuite/gfortran.dg/lto/20091028-2_1.c11
-rw-r--r--gcc/tree-ssa-alias.c28
-rw-r--r--gcc/tree-ssa-structalias.c6
9 files changed, 92 insertions, 6 deletions
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 <rguenther@suse.de>
+
+ 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 <bonzini@gnu.org>
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 <rguenther@suse.de>
+
+ 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 <bonzini@gnu.org>
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);