diff options
author | Richard Biener <rguenther@suse.de> | 2015-07-28 11:53:37 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-07-28 11:53:37 +0000 |
commit | 68aba1f6a863b0fc0fd487a737693787a49845e2 (patch) | |
tree | 5cda3b1f17652d463edfed4a0600082c83e5cd8c | |
parent | 9bc22d19f1fa7f65d5d50d3c44e8c9fbf7a8760b (diff) | |
download | gcc-68aba1f6a863b0fc0fd487a737693787a49845e2.zip gcc-68aba1f6a863b0fc0fd487a737693787a49845e2.tar.gz gcc-68aba1f6a863b0fc0fd487a737693787a49845e2.tar.bz2 |
match.pd: Add more simplification of address comparisons.
2015-07-28 Richard Biener <rguenther@suse.de>
* match.pd: Add more simplification of address comparisons.
From-SVN: r226312
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/match.pd | 40 |
2 files changed, 44 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d81551f..fadcb03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2015-07-28 Richard Biener <rguenther@suse.de> + * match.pd: Add more simplification of address comparisons. + +2015-07-28 Richard Biener <rguenther@suse.de> + * match.pd: Re-order two cases in comparison with max/min value simplification to make it apply for bools. diff --git a/gcc/match.pd b/gcc/match.pd index 5aaa8e1..b0c6d77 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1828,6 +1828,46 @@ along with GCC; see the file COPYING3. If not see (if (tree_single_nonzero_warnv_p (@0, NULL)) { constant_boolean_node (cmp == NE_EXPR, type); }))) +/* When the addresses are not directly of decls compare base and offset. + This implements some remaining parts of fold_comparison address + comparisons but still no complete part of it. Still it is good + enough to make fold_stmt not regress when not dispatching to fold_binary. */ +(for cmp (simple_comparison) + (simplify + (cmp (convert? addr@0) (convert? addr@1)) + (with + { + HOST_WIDE_INT off0, off1; + tree base0 = get_addr_base_and_unit_offset (TREE_OPERAND (@0, 0), &off0); + tree base1 = get_addr_base_and_unit_offset (TREE_OPERAND (@1, 0), &off1); + if (base0 && TREE_CODE (base0) == MEM_REF) + { + off0 += mem_ref_offset (base0).to_short_addr (); + base0 = TREE_OPERAND (base0, 0); + } + if (base1 && TREE_CODE (base1) == MEM_REF) + { + off1 += mem_ref_offset (base1).to_short_addr (); + base1 = TREE_OPERAND (base1, 0); + } + } + (if (base0 && base1 + && operand_equal_p (base0, base1, 0) + && (cmp == EQ_EXPR || cmp == NE_EXPR + || POINTER_TYPE_OVERFLOW_UNDEFINED)) + (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); })))))) /* Non-equality compare simplifications from fold_binary */ (for cmp (lt gt le ge) |