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:
parent
d2e0c00b8c
commit
e080863881
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue