re PR tree-optimization/88775 (Optimize std::string assignment)
PR tree-optimization/88775 * match.pd (cmp (convert1?@2 addr@0) (convert2? addr@1)): Optimize equal == 0 equality pointer comparisons some more if compared in integral types and either one points to an automatic var and the other to a global, or we can prove at least one points to the middle or both point to start or both point to end. * gcc.dg/tree-ssa/pr88775-1.c: New test. * gcc.dg/tree-ssa/pr88775-2.c: New test. From-SVN: r267931
This commit is contained in:
parent
6facd01f98
commit
93aa3c4aca
5 changed files with 183 additions and 10 deletions
|
@ -1,3 +1,12 @@
|
|||
2019-01-15 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/88775
|
||||
* match.pd (cmp (convert1?@2 addr@0) (convert2? addr@1)): Optimize
|
||||
equal == 0 equality pointer comparisons some more if compared in
|
||||
integral types and either one points to an automatic var and the
|
||||
other to a global, or we can prove at least one points to the middle
|
||||
or both point to start or both point to end.
|
||||
|
||||
2019-01-14 Andi Kleen <ak@linux.intel.com>
|
||||
|
||||
* Makefile.in: Lower autofdo sampling rate by 10x.
|
||||
|
|
62
gcc/match.pd
62
gcc/match.pd
|
@ -3896,6 +3896,52 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
|||
|| TREE_CODE (base1) == SSA_NAME
|
||||
|| TREE_CODE (base1) == STRING_CST))
|
||||
equal = (base0 == base1);
|
||||
if (equal == 0)
|
||||
{
|
||||
if (!DECL_P (base0) || !DECL_P (base1))
|
||||
equal = 2;
|
||||
else if (cmp != EQ_EXPR && cmp != NE_EXPR)
|
||||
equal = 2;
|
||||
/* If this is a pointer comparison, ignore for now even
|
||||
valid equalities where one pointer is the offset zero
|
||||
of one object and the other to one past end of another one. */
|
||||
else if (!INTEGRAL_TYPE_P (TREE_TYPE (@2)))
|
||||
;
|
||||
/* Assume that automatic variables can't be adjacent to global
|
||||
variables. */
|
||||
else if (is_global_var (base0) != is_global_var (base1))
|
||||
;
|
||||
else
|
||||
{
|
||||
tree sz0 = DECL_SIZE_UNIT (base0);
|
||||
tree sz1 = DECL_SIZE_UNIT (base1);
|
||||
/* If sizes are unknown, e.g. VLA or not representable,
|
||||
punt. */
|
||||
if (!tree_fits_poly_int64_p (sz0)
|
||||
|| !tree_fits_poly_int64_p (sz1))
|
||||
equal = 2;
|
||||
else
|
||||
{
|
||||
poly_int64 size0 = tree_to_poly_int64 (sz0);
|
||||
poly_int64 size1 = tree_to_poly_int64 (sz1);
|
||||
/* If one offset is pointing (or could be) to the beginning
|
||||
of one object and the other is pointing to one past the
|
||||
last byte of the other object, punt. */
|
||||
if (maybe_eq (off0, 0) && maybe_eq (off1, size1))
|
||||
equal = 2;
|
||||
else if (maybe_eq (off1, 0) && maybe_eq (off0, size0))
|
||||
equal = 2;
|
||||
/* If both offsets are the same, there are some cases
|
||||
we know that are ok. Either if we know they aren't
|
||||
zero, or if we know both sizes are no zero. */
|
||||
if (equal == 2
|
||||
&& known_eq (off0, off1)
|
||||
&& (known_ne (off0, 0)
|
||||
|| (known_ne (size0, 0) && known_ne (size1, 0))))
|
||||
equal = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(if (equal == 1
|
||||
&& (cmp == EQ_EXPR || cmp == NE_EXPR
|
||||
|
@ -3918,16 +3964,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
|||
{ constant_boolean_node (known_ge (off0, off1), type); })
|
||||
(if (cmp == GT_EXPR && (known_gt (off0, off1) || known_le (off0, off1)))
|
||||
{ constant_boolean_node (known_gt (off0, off1), type); }))
|
||||
(if (equal == 0
|
||||
&& DECL_P (base0) && DECL_P (base1)
|
||||
/* If we compare this as integers require equal offset. */
|
||||
&& (!INTEGRAL_TYPE_P (TREE_TYPE (@2))
|
||||
|| known_eq (off0, off1)))
|
||||
(switch
|
||||
(if (cmp == EQ_EXPR)
|
||||
{ constant_boolean_node (false, type); })
|
||||
(if (cmp == NE_EXPR)
|
||||
{ constant_boolean_node (true, type); })))))))))
|
||||
(if (equal == 0)
|
||||
(switch
|
||||
(if (cmp == EQ_EXPR)
|
||||
{ constant_boolean_node (false, type); })
|
||||
(if (cmp == NE_EXPR)
|
||||
{ constant_boolean_node (true, type); })))))))))
|
||||
|
||||
/* Simplify pointer equality compares using PTA. */
|
||||
(for neeq (ne eq)
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2019-01-15 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/88775
|
||||
* gcc.dg/tree-ssa/pr88775-1.c: New test.
|
||||
* gcc.dg/tree-ssa/pr88775-2.c: New test.
|
||||
|
||||
2019-01-14 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/88825 - ICE with bogus function return type deduction.
|
||||
|
|
73
gcc/testsuite/gcc.dg/tree-ssa/pr88775-1.c
Normal file
73
gcc/testsuite/gcc.dg/tree-ssa/pr88775-1.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* PR tree-optimization/88775 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
/* { dg-final { scan-tree-dump-times "return 1;" 10 "optimized" } } */
|
||||
|
||||
int a[64] = {};
|
||||
int b[64] = {};
|
||||
|
||||
int
|
||||
f1 (void)
|
||||
{
|
||||
return (__UINTPTR_TYPE__) &a[2] != (__UINTPTR_TYPE__) &b[2];
|
||||
}
|
||||
|
||||
int
|
||||
f2 (void)
|
||||
{
|
||||
return (__UINTPTR_TYPE__) &a[2] != (__UINTPTR_TYPE__) &b[10];
|
||||
}
|
||||
|
||||
int
|
||||
f3 (void)
|
||||
{
|
||||
return (__UINTPTR_TYPE__) &a[0] != (__UINTPTR_TYPE__) &b[0];
|
||||
}
|
||||
|
||||
int
|
||||
f4 (void)
|
||||
{
|
||||
return (__UINTPTR_TYPE__) &a[64] != (__UINTPTR_TYPE__) &b[64];
|
||||
}
|
||||
|
||||
int
|
||||
f5 (void)
|
||||
{
|
||||
int c[64] = {};
|
||||
return (__UINTPTR_TYPE__) &a[0] != (__UINTPTR_TYPE__) &c[64];
|
||||
}
|
||||
|
||||
int
|
||||
f6 (void)
|
||||
{
|
||||
int c[64] = {};
|
||||
return (__UINTPTR_TYPE__) &b[64] != (__UINTPTR_TYPE__) &c[0];
|
||||
}
|
||||
|
||||
int
|
||||
f7 (void)
|
||||
{
|
||||
int c[64] = {}, d[64] = {};
|
||||
return (__UINTPTR_TYPE__) &c[2] != (__UINTPTR_TYPE__) &d[2];
|
||||
}
|
||||
|
||||
int
|
||||
f8 (void)
|
||||
{
|
||||
int c[64] = {}, d[64] = {};
|
||||
return (__UINTPTR_TYPE__) &c[2] != (__UINTPTR_TYPE__) &d[10];
|
||||
}
|
||||
|
||||
int
|
||||
f9 (void)
|
||||
{
|
||||
int c[64] = {}, d[64] = {};
|
||||
return (__UINTPTR_TYPE__) &c[0] != (__UINTPTR_TYPE__) &d[0];
|
||||
}
|
||||
|
||||
int
|
||||
f10 (void)
|
||||
{
|
||||
int c[64] = {}, d[64] = {};
|
||||
return (__UINTPTR_TYPE__) &c[64] != (__UINTPTR_TYPE__) &d[64];
|
||||
}
|
43
gcc/testsuite/gcc.dg/tree-ssa/pr88775-2.c
Normal file
43
gcc/testsuite/gcc.dg/tree-ssa/pr88775-2.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* PR tree-optimization/88775 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
/* These can't be decided until we know how the variables will
|
||||
be laid out in memory. */
|
||||
/* { dg-final { scan-tree-dump-not "return 1;" "optimized" } } */
|
||||
|
||||
int a[64] = {};
|
||||
int b[64] = {};
|
||||
int e[0] = {};
|
||||
int f[0] = {};
|
||||
|
||||
int
|
||||
f1 (void)
|
||||
{
|
||||
return (__UINTPTR_TYPE__) &a[0] != (__UINTPTR_TYPE__) &b[64];
|
||||
}
|
||||
|
||||
int
|
||||
f2 (void)
|
||||
{
|
||||
return (__UINTPTR_TYPE__) &a[64] != (__UINTPTR_TYPE__) &b[0];
|
||||
}
|
||||
|
||||
int
|
||||
f3 (void)
|
||||
{
|
||||
return (__UINTPTR_TYPE__) &e[0] != (__UINTPTR_TYPE__) &f[0];
|
||||
}
|
||||
|
||||
int
|
||||
f4 (void)
|
||||
{
|
||||
int c[64] = {}, d[64] = {};
|
||||
return (__UINTPTR_TYPE__) &c[0] != (__UINTPTR_TYPE__) &d[64];
|
||||
}
|
||||
|
||||
int
|
||||
f5 (void)
|
||||
{
|
||||
int c[64] = {}, d[64] = {};
|
||||
return (__UINTPTR_TYPE__) &c[64] != (__UINTPTR_TYPE__) &d[0];
|
||||
}
|
Loading…
Add table
Reference in a new issue