From: Richard Biener Date: Mon, 9 Mar 2015 13:54:28 +0000 (+0000) Subject: re PR ipa/65270 (issues with merging memory accesses from different code paths) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e0808638812e20b756052ed8a816528db69b5a08;p=gcc.git re PR ipa/65270 (issues with merging memory accesses from different code paths) 2015-03-09 Richard Biener PR middle-end/65270 * tree-core.h (enum operand_equal_flag): Add OEP_ADDRESS_OF. * fold-const.c (operand_equal_p): When recursing for ADDR_EXPRs operand set OEP_ADDRESS_OF. Clear it when recursing to non-bases of that. When comparing dereferences compare alignment. When comparing MEM_REFs or TARGET_MEM_REFs compare dependence info. * gcc.dg/torture/pr65270-1.c: New testcase. * gcc.dg/torture/pr65270-2.c: Likewise. From-SVN: r221281 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 62b299f0d00..19efa1eca4e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-03-09 Richard Biener + + PR middle-end/65270 + * tree-core.h (enum operand_equal_flag): Add OEP_ADDRESS_OF. + * fold-const.c (operand_equal_p): When recursing for ADDR_EXPRs + operand set OEP_ADDRESS_OF. Clear it when recursing to non-bases + of that. When comparing dereferences compare alignment. + When comparing MEM_REFs or TARGET_MEM_REFs compare dependence info. + 2015-03-08 Jan Hubicka * ipa-inline-analysis.c (check_callers): Check diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0834d47fa03..915d6395382 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2860,7 +2860,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) case ADDR_EXPR: return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1) - ? OEP_CONSTANT_ADDRESS_OF : 0); + ? OEP_CONSTANT_ADDRESS_OF | OEP_ADDRESS_OF : 0); default: break; } @@ -2922,7 +2922,11 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) switch (TREE_CODE (arg0)) { case INDIRECT_REF: - flags &= ~OEP_CONSTANT_ADDRESS_OF; + if (!(flags & OEP_ADDRESS_OF) + && (TYPE_ALIGN (TREE_TYPE (arg0)) + != TYPE_ALIGN (TREE_TYPE (arg1)))) + return 0; + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); return OP_SAME (0); case REALPART_EXPR: @@ -2930,7 +2934,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) return OP_SAME (0); case TARGET_MEM_REF: - flags &= ~OEP_CONSTANT_ADDRESS_OF; + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); /* Require equal extra operands and then fall through to MEM_REF handling of the two common operands. */ if (!OP_SAME_WITH_NULL (2) @@ -2939,7 +2943,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) return 0; /* Fallthru. */ case MEM_REF: - flags &= ~OEP_CONSTANT_ADDRESS_OF; + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); /* Require equal access sizes, and similar pointer types. We can have incomplete types for array references of variable-sized arrays from the Fortran frontend @@ -2950,9 +2954,16 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) && operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), TYPE_SIZE (TREE_TYPE (arg1)), flags))) && types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)) - && alias_ptr_types_compatible_p - (TREE_TYPE (TREE_OPERAND (arg0, 1)), - TREE_TYPE (TREE_OPERAND (arg1, 1))) + && ((flags & OEP_ADDRESS_OF) + || (alias_ptr_types_compatible_p + (TREE_TYPE (TREE_OPERAND (arg0, 1)), + TREE_TYPE (TREE_OPERAND (arg1, 1))) + && (MR_DEPENDENCE_CLIQUE (arg0) + == MR_DEPENDENCE_CLIQUE (arg1)) + && (MR_DEPENDENCE_BASE (arg0) + == MR_DEPENDENCE_BASE (arg1)) + && (TYPE_ALIGN (TREE_TYPE (arg0)) + == TYPE_ALIGN (TREE_TYPE (arg1))))) && OP_SAME (0) && OP_SAME (1)); case ARRAY_REF: @@ -2962,7 +2973,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) may have different types but same value here. */ if (!OP_SAME (0)) return 0; - flags &= ~OEP_CONSTANT_ADDRESS_OF; + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); return ((tree_int_cst_equal (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1)) || OP_SAME (1)) @@ -2975,13 +2986,13 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) if (!OP_SAME_WITH_NULL (0) || !OP_SAME (1)) return 0; - flags &= ~OEP_CONSTANT_ADDRESS_OF; + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); return OP_SAME_WITH_NULL (2); case BIT_FIELD_REF: if (!OP_SAME (0)) return 0; - flags &= ~OEP_CONSTANT_ADDRESS_OF; + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); return OP_SAME (1) && OP_SAME (2); default: @@ -2992,6 +3003,10 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) switch (TREE_CODE (arg0)) { case ADDR_EXPR: + return operand_equal_p (TREE_OPERAND (arg0, 0), + TREE_OPERAND (arg1, 0), + flags | OEP_ADDRESS_OF); + case TRUTH_NOT_EXPR: return OP_SAME (0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8256fc3d9a6..a17c73f8f79 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-03-09 Richard Biener + + PR middle-end/65270 + * gcc.dg/torture/pr65270-1.c: New testcase. + * gcc.dg/torture/pr65270-2.c: Likewise. + 2015-03-09 Thomas Preud'homme PR tree-optimization/63743 diff --git a/gcc/testsuite/gcc.dg/torture/pr65270-1.c b/gcc/testsuite/gcc.dg/torture/pr65270-1.c new file mode 100644 index 00000000000..ae6dc3bf8ed --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr65270-1.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ + +struct a +{ + int a[100]; +}; +typedef struct a misaligned_t __attribute__ ((aligned (8))); +typedef struct a aligned_t __attribute__ ((aligned (32))); + +__attribute__ ((used)) +__attribute__ ((noinline)) +void +t(void *a, int misaligned, aligned_t *d) +{ + int i,v; + for (i=0;i<100;i++) + { + if (misaligned) + v=((misaligned_t *)a)->a[i]; + else + v=((aligned_t *)a)->a[i]; + d->a[i]+=v; + } +} +struct b {int v; misaligned_t m;aligned_t aa;} b; +aligned_t d; +int +main() +{ + t(&b.m, 1, &d); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr65270-2.c b/gcc/testsuite/gcc.dg/torture/pr65270-2.c new file mode 100644 index 00000000000..d5b8f1ce236 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr65270-2.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ + +struct a +{ + int a[100]; +}; +typedef struct a misaligned_t __attribute__ ((aligned (8))); +typedef struct a aligned_t __attribute__ ((aligned (32))); + +__attribute__ ((used)) +__attribute__ ((noinline)) +void +t(void *a, int misaligned, aligned_t *d) +{ + int i,v; + for (i=0;i<100;i++) + d->a[i]+=!misaligned? ((aligned_t *)a)->a[i] : ((misaligned_t *)a)->a[i]; +} +struct b {int v; misaligned_t m;aligned_t aa;} b; +aligned_t d; +int +main() +{ + t(&b.m, 1, &d); + return 0; +} diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 3aaf650ff73..ad1bb231ebe 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -700,7 +700,8 @@ enum size_type_kind { enum operand_equal_flag { OEP_ONLY_CONST = 1, OEP_PURE_SAME = 2, - OEP_CONSTANT_ADDRESS_OF = 4 + OEP_CONSTANT_ADDRESS_OF = 4, + OEP_ADDRESS_OF = 8 }; /* Enum and arrays used for tree allocation stats.