mirror of git://gcc.gnu.org/git/gcc.git
match.pd: Merge address comparison patterns and make them handle some more cases.
2015-07-29 Richard Biener <rguenther@suse.de> * match.pd: Merge address comparison patterns and make them handle some more cases. From-SVN: r226345
This commit is contained in:
parent
c56f494f74
commit
da571fdab9
|
|
@ -1,3 +1,8 @@
|
||||||
|
2015-07-29 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* match.pd: Merge address comparison patterns and make them
|
||||||
|
handle some more cases.
|
||||||
|
|
||||||
2015-07-29 Richard Biener <rguenther@suse.de>
|
2015-07-29 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
* genmatch.c (c_expr::gen_transform): Error on unknown captures.
|
* genmatch.c (c_expr::gen_transform): Error on unknown captures.
|
||||||
|
|
|
||||||
81
gcc/match.pd
81
gcc/match.pd
|
|
@ -1802,26 +1802,6 @@ along with GCC; see the file COPYING3. If not see
|
||||||
(cmp (convert?@3 (bit_xor @0 INTEGER_CST@1)) INTEGER_CST@2)
|
(cmp (convert?@3 (bit_xor @0 INTEGER_CST@1)) INTEGER_CST@2)
|
||||||
(if (tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0)))
|
(if (tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0)))
|
||||||
(cmp @0 (bit_xor @1 (convert @2)))))
|
(cmp @0 (bit_xor @1 (convert @2)))))
|
||||||
|
|
||||||
/* If this is an equality comparison of the address of two non-weak,
|
|
||||||
unaliased symbols neither of which are extern (since we do not
|
|
||||||
have access to attributes for externs), then we know the result. */
|
|
||||||
(simplify
|
|
||||||
(cmp (convert? addr@0) (convert? addr@1))
|
|
||||||
(if (DECL_P (TREE_OPERAND (@0, 0))
|
|
||||||
&& DECL_P (TREE_OPERAND (@1, 0)))
|
|
||||||
(if (decl_in_symtab_p (TREE_OPERAND (@0, 0))
|
|
||||||
&& decl_in_symtab_p (TREE_OPERAND (@1, 0)))
|
|
||||||
(with
|
|
||||||
{
|
|
||||||
int equal = symtab_node::get_create (TREE_OPERAND (@0, 0))
|
|
||||||
->equal_address_to (symtab_node::get_create (TREE_OPERAND (@1, 0)));
|
|
||||||
}
|
|
||||||
(if (equal != 2)
|
|
||||||
{ constant_boolean_node (equal
|
|
||||||
? cmp == EQ_EXPR : cmp != EQ_EXPR, type); }))
|
|
||||||
(if (TREE_OPERAND (@0, 0) != TREE_OPERAND (@1, 0))
|
|
||||||
{ constant_boolean_node (cmp == EQ_EXPR ? false : true, type); }))))
|
|
||||||
|
|
||||||
(simplify
|
(simplify
|
||||||
(cmp (convert? addr@0) integer_zerop)
|
(cmp (convert? addr@0) integer_zerop)
|
||||||
|
|
@ -1834,7 +1814,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
enough to make fold_stmt not regress when not dispatching to fold_binary. */
|
enough to make fold_stmt not regress when not dispatching to fold_binary. */
|
||||||
(for cmp (simple_comparison)
|
(for cmp (simple_comparison)
|
||||||
(simplify
|
(simplify
|
||||||
(cmp (convert? addr@0) (convert? addr@1))
|
(cmp (convert?@2 addr@0) (convert? addr@1))
|
||||||
(with
|
(with
|
||||||
{
|
{
|
||||||
HOST_WIDE_INT off0, off1;
|
HOST_WIDE_INT off0, off1;
|
||||||
|
|
@ -1851,23 +1831,48 @@ along with GCC; see the file COPYING3. If not see
|
||||||
base1 = TREE_OPERAND (base1, 0);
|
base1 = TREE_OPERAND (base1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(if (base0 && base1
|
(if (base0 && base1)
|
||||||
&& operand_equal_p (base0, base1, 0)
|
(with
|
||||||
&& (cmp == EQ_EXPR || cmp == NE_EXPR
|
{
|
||||||
|| POINTER_TYPE_OVERFLOW_UNDEFINED))
|
int equal;
|
||||||
(switch
|
if (decl_in_symtab_p (base0)
|
||||||
(if (cmp == EQ_EXPR)
|
&& decl_in_symtab_p (base1))
|
||||||
{ constant_boolean_node (off0 == off1, type); })
|
equal = symtab_node::get_create (base0)
|
||||||
(if (cmp == NE_EXPR)
|
->equal_address_to (symtab_node::get_create (base1));
|
||||||
{ constant_boolean_node (off0 != off1, type); })
|
else
|
||||||
(if (cmp == LT_EXPR)
|
equal = operand_equal_p (base0, base1, 0);
|
||||||
{ constant_boolean_node (off0 < off1, type); })
|
}
|
||||||
(if (cmp == LE_EXPR)
|
(if (equal == 1
|
||||||
{ constant_boolean_node (off0 <= off1, type); })
|
&& (cmp == EQ_EXPR || cmp == NE_EXPR
|
||||||
(if (cmp == GE_EXPR)
|
/* If the offsets are equal we can ignore overflow. */
|
||||||
{ constant_boolean_node (off0 >= off1, type); })
|
|| off0 == off1
|
||||||
(if (cmp == GT_EXPR)
|
|| POINTER_TYPE_OVERFLOW_UNDEFINED
|
||||||
{ constant_boolean_node (off0 > off1, type); }))))))
|
/* Or if we compare using pointers to decls. */
|
||||||
|
|| (POINTER_TYPE_P (TREE_TYPE (@2))
|
||||||
|
&& DECL_P (base0))))
|
||||||
|
(switch
|
||||||
|
(if (cmp == EQ_EXPR)
|
||||||
|
{ constant_boolean_node (off0 == off1, type); })
|
||||||
|
(if (cmp == NE_EXPR)
|
||||||
|
{ constant_boolean_node (off0 != off1, type); })
|
||||||
|
(if (cmp == LT_EXPR)
|
||||||
|
{ constant_boolean_node (off0 < off1, type); })
|
||||||
|
(if (cmp == LE_EXPR)
|
||||||
|
{ constant_boolean_node (off0 <= off1, type); })
|
||||||
|
(if (cmp == GE_EXPR)
|
||||||
|
{ constant_boolean_node (off0 >= off1, type); })
|
||||||
|
(if (cmp == GT_EXPR)
|
||||||
|
{ constant_boolean_node (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))
|
||||||
|
|| off0 == off1))
|
||||||
|
(switch
|
||||||
|
(if (cmp == EQ_EXPR)
|
||||||
|
{ constant_boolean_node (false, type); })
|
||||||
|
(if (cmp == NE_EXPR)
|
||||||
|
{ constant_boolean_node (true, type); })))))))))
|
||||||
|
|
||||||
/* Non-equality compare simplifications from fold_binary */
|
/* Non-equality compare simplifications from fold_binary */
|
||||||
(for cmp (lt gt le ge)
|
(for cmp (lt gt le ge)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue