aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-03-09 13:54:28 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-03-09 13:54:28 +0000
commite0808638812e20b756052ed8a816528db69b5a08 (patch)
tree08c44e058e8dabba9e5cd87ddd2f888817f638da /gcc/fold-const.c
parentd2e0c00b8c88ccc32d121839b18963a3657512aa (diff)
downloadgcc-e0808638812e20b756052ed8a816528db69b5a08.zip
gcc-e0808638812e20b756052ed8a816528db69b5a08.tar.gz
gcc-e0808638812e20b756052ed8a816528db69b5a08.tar.bz2
re PR ipa/65270 (issues with merging memory accesses from different code paths)
2015-03-09 Richard Biener <rguenther@suse.de> 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
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0834d47..915d639 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);