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
This commit is contained in:
Richard Biener 2015-03-09 13:54:28 +00:00 committed by Richard Biener
parent d2e0c00b8c
commit e080863881
6 changed files with 100 additions and 11 deletions

View File

@ -1,3 +1,12 @@
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.
2015-03-08 Jan Hubicka <hubicka@ucw.cz> 2015-03-08 Jan Hubicka <hubicka@ucw.cz>
* ipa-inline-analysis.c (check_callers): Check * ipa-inline-analysis.c (check_callers): Check

View File

@ -2860,7 +2860,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case ADDR_EXPR: case ADDR_EXPR:
return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1) TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1)
? OEP_CONSTANT_ADDRESS_OF : 0); ? OEP_CONSTANT_ADDRESS_OF | OEP_ADDRESS_OF : 0);
default: default:
break; break;
} }
@ -2922,7 +2922,11 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
switch (TREE_CODE (arg0)) switch (TREE_CODE (arg0))
{ {
case INDIRECT_REF: 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); return OP_SAME (0);
case REALPART_EXPR: case REALPART_EXPR:
@ -2930,7 +2934,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
return OP_SAME (0); return OP_SAME (0);
case TARGET_MEM_REF: 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 /* Require equal extra operands and then fall through to MEM_REF
handling of the two common operands. */ handling of the two common operands. */
if (!OP_SAME_WITH_NULL (2) if (!OP_SAME_WITH_NULL (2)
@ -2939,7 +2943,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
return 0; return 0;
/* Fallthru. */ /* Fallthru. */
case MEM_REF: case MEM_REF:
flags &= ~OEP_CONSTANT_ADDRESS_OF; flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
/* Require equal access sizes, and similar pointer types. /* Require equal access sizes, and similar pointer types.
We can have incomplete types for array references of We can have incomplete types for array references of
variable-sized arrays from the Fortran frontend 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)), && operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
TYPE_SIZE (TREE_TYPE (arg1)), flags))) TYPE_SIZE (TREE_TYPE (arg1)), flags)))
&& types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)) && types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1))
&& alias_ptr_types_compatible_p && ((flags & OEP_ADDRESS_OF)
(TREE_TYPE (TREE_OPERAND (arg0, 1)), || (alias_ptr_types_compatible_p
TREE_TYPE (TREE_OPERAND (arg1, 1))) (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)); && OP_SAME (0) && OP_SAME (1));
case ARRAY_REF: 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. */ may have different types but same value here. */
if (!OP_SAME (0)) if (!OP_SAME (0))
return 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), return ((tree_int_cst_equal (TREE_OPERAND (arg0, 1),
TREE_OPERAND (arg1, 1)) TREE_OPERAND (arg1, 1))
|| OP_SAME (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) if (!OP_SAME_WITH_NULL (0)
|| !OP_SAME (1)) || !OP_SAME (1))
return 0; return 0;
flags &= ~OEP_CONSTANT_ADDRESS_OF; flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
return OP_SAME_WITH_NULL (2); return OP_SAME_WITH_NULL (2);
case BIT_FIELD_REF: case BIT_FIELD_REF:
if (!OP_SAME (0)) if (!OP_SAME (0))
return 0; return 0;
flags &= ~OEP_CONSTANT_ADDRESS_OF; flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
return OP_SAME (1) && OP_SAME (2); return OP_SAME (1) && OP_SAME (2);
default: default:
@ -2992,6 +3003,10 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
switch (TREE_CODE (arg0)) switch (TREE_CODE (arg0))
{ {
case ADDR_EXPR: case ADDR_EXPR:
return operand_equal_p (TREE_OPERAND (arg0, 0),
TREE_OPERAND (arg1, 0),
flags | OEP_ADDRESS_OF);
case TRUTH_NOT_EXPR: case TRUTH_NOT_EXPR:
return OP_SAME (0); return OP_SAME (0);

View File

@ -1,3 +1,9 @@
2015-03-09 Richard Biener <rguenther@suse.de>
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 <thomas.preudhomme@arm.com> 2015-03-09 Thomas Preud'homme <thomas.preudhomme@arm.com>
PR tree-optimization/63743 PR tree-optimization/63743

View File

@ -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;
}

View File

@ -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;
}

View File

@ -700,7 +700,8 @@ enum size_type_kind {
enum operand_equal_flag { enum operand_equal_flag {
OEP_ONLY_CONST = 1, OEP_ONLY_CONST = 1,
OEP_PURE_SAME = 2, 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. /* Enum and arrays used for tree allocation stats.