This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch match.pd c c++]: Ignore results of 'shorten_compare' and move missing patterns in match.pd
- From: Kai Tietz <ktietz70 at googlemail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jeff Law <law at redhat dot com>, Richard Biener <richard dot guenther at gmail dot com>
- Date: Tue, 8 Sep 2015 13:17:23 +0200
- Subject: [patch match.pd c c++]: Ignore results of 'shorten_compare' and move missing patterns in match.pd
- Authentication-results: sourceware.org; auth=none
Hi,
This patch is the first part of obsoleting 'shorten_compare' function
for folding.
It adjusts the uses of 'shorten_compare' to ignore folding returned by
it, and adds
missing pattterns to match.pd to allow full bootstrap of C/C++ without
regressions.
Due we are using 'shorten_compare' for some diagnostic we can't simply
remove it. So if this patch gets approved, the next step will be to
rename the function to something like 'check_compare', and adjust its
arguments and inner logic to reflect that we don't modify
arguments/expression anymore within that function.
Bootstrap just show 2 regressions within gcc.dg testsuite due patterns
matched are folded more early by forward-propagation. I adjusted
them, and added them to patch, too.
I did regression-testing for x86_64-unknown-linux-gnu.
ChangeLog
2015-09-08 Kai Tietz <ktietz@redhat.com>
* match.pd: Add missing patterns from shorten_compare.
* c/c-typeck.c (build_binary_op): Discard foldings of shorten_compare.
* cp/typeck.c (cp_build_binary_op): Likewise.
2015-09-08 Kai Tietz <ktietz@redhat.com>
* gcc.dg/tree-ssa/vrp23.c: Adjust testcase to reflect that
pattern is matching now already within forward-propagation pass.
* gcc.dg/tree-ssa/vrp24.c: Likewise.
Index: match.pd
===================================================================
--- match.pd (Revision 227528)
+++ match.pd (Arbeitskopie)
@@ -1786,6 +1786,45 @@ along with GCC; see the file COPYING3. If not see
(op (abs @0) zerop@1)
(op @0 @1)))
+/* Simplify '((type) X) cmp ((type) Y' to shortest possible types, of X and Y,
+ if type's precision is wider then precision of X's and Y's type.
+ Logic taken from shorten_compare function. */
+(for op (tcc_comparison)
+ (simplify
+ (op (convert@0 @1) (convert@3 @2))
+ (if ((TREE_CODE (TREE_TYPE (@1)) == REAL_TYPE)
+ == (TREE_CODE (TREE_TYPE (@2)) == REAL_TYPE)
+ && (TREE_CODE (TREE_TYPE (@1)) == REAL_TYPE)
+ == (TREE_CODE (TREE_TYPE (@0)) == REAL_TYPE)
+ && single_use (@1)
+ && single_use (@3)
+ && TYPE_UNSIGNED (TREE_TYPE (@1)) == TYPE_UNSIGNED (TREE_TYPE (@2))
+ && !((TREE_CODE (TREE_TYPE (@1)) == REAL_TYPE
+ && DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (@1))))
+ || (TREE_CODE (TREE_TYPE (@2)) == REAL_TYPE
+ && DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (@2)))))
+ && TYPE_PRECISION (TREE_TYPE (@1)) < TYPE_PRECISION (TREE_TYPE (@0))
+ && TYPE_PRECISION (TREE_TYPE (@2)) < TYPE_PRECISION (TREE_TYPE (@0))
+ )
+ (with {
+ tree comtype = TYPE_PRECISION (TREE_TYPE (@1))
+ < TYPE_PRECISION (TREE_TYPE (@2)) ? TREE_TYPE (@2)
+ : TREE_TYPE (@1);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ {
+ if (TYPE_UNSIGNED (TREE_TYPE (@1)) || TYPE_UNSIGNED
(TREE_TYPE (@0)))
+ comtype = unsigned_type_for (comtype);
+ else
+ comtype = signed_type_for (comtype);
+ }
+ }
+ (op (convert:comtype @1) (convert:comtype @2))
+ )
+ )
+ )
+)
+
+
/* From fold_sign_changed_comparison and fold_widened_comparison. */
(for cmp (simple_comparison)
(simplify
@@ -2046,7 +2085,43 @@ along with GCC; see the file COPYING3. If not see
(if (cmp == LE_EXPR)
(ge (convert:st @0) { build_zero_cst (st); })
(lt (convert:st @0) { build_zero_cst (st); }))))))))))
-
+
+/* Simplify '(type) X cmp CST' to 'X cmp (type-of-X) CST', if
+ CST fits into the type of X. */
+(for cmp (simple_comparison)
+ (simplify
+ (cmp (convert@2 @0) INTEGER_CST@1)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && TYPE_PRECISION (TREE_TYPE (@1)) > TYPE_PRECISION (TREE_TYPE (@0))
+ && single_use (@2)
+ && (TYPE_UNSIGNED (TREE_TYPE (@0))
+ || TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED
(TREE_TYPE (@1))
+ || cmp == NE_EXPR || cmp == EQ_EXPR)
+ && !POINTER_TYPE_P (TREE_TYPE (@0))
+ && int_fits_type_p (@1, TREE_TYPE (@0)))
+ (with { tree optype = TREE_TYPE (@0); }
+ (cmp @0 (convert:optype @1))
+ )
+ )
+ )
+)
+
+/* See if '(type) X ==/!= CST' represents a condition,
+ which is always true, or false due CST's value. */
+(for cmp (ne eq)
+ (simplify
+ (cmp (convert@2 @0) INTEGER_CST@1)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && TYPE_PRECISION (TREE_TYPE (@1)) >= TYPE_PRECISION (TREE_TYPE (@0))
+ && single_use (@2)
+ && !POINTER_TYPE_P (TREE_TYPE (@0))
+ && !int_fits_type_p (@1, TREE_TYPE (@0))
+ && TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@1)))
+ { constant_boolean_node (cmp == NE_EXPR, type); }
+ )
+ )
+)
+
(for cmp (unordered ordered unlt unle ungt unge uneq ltgt)
/* If the second operand is NaN, the result is constant. */
(simplify
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (Revision 227528)
+++ cp/typeck.c (Arbeitskopie)
@@ -5000,14 +5000,8 @@ cp_build_binary_op (location_t location,
pass the copies by reference, then copy them back afterward. */
tree xop0 = op0, xop1 = op1, xresult_type = result_type;
enum tree_code xresultcode = resultcode;
- tree val
- = shorten_compare (location, &xop0, &xop1, &xresult_type,
- &xresultcode);
- if (val != 0)
- return cp_convert (boolean_type_node, val, complain);
- op0 = xop0, op1 = xop1;
- converted = 1;
- resultcode = xresultcode;
+ shorten_compare (location, &xop0, &xop1, &xresult_type,
+ &xresultcode);
}
if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
Index: c/c-typeck.c
===================================================================
--- c/c-typeck.c (Revision 227528)
+++ c/c-typeck.c (Arbeitskopie)
@@ -11193,20 +11193,9 @@ build_binary_op (location_t location, enum tree_co
pass the copies by reference, then copy them back afterward. */
tree xop0 = op0, xop1 = op1, xresult_type = result_type;
enum tree_code xresultcode = resultcode;
- tree val
- = shorten_compare (location, &xop0, &xop1, &xresult_type,
- &xresultcode);
+ shorten_compare (location, &xop0, &xop1, &xresult_type,
+ &xresultcode);
- if (val != 0)
- {
- ret = val;
- goto return_build_binary_op;
- }
-
- op0 = xop0, op1 = xop1;
- converted = 1;
- resultcode = xresultcode;
-
if (c_inhibit_evaluation_warnings == 0)
{
bool op0_maybe_const = true;
Index: gcc.dg/tree-ssa/vrp23.c
===================================================================
--- gcc.dg/tree-ssa/vrp23.c (Revision 227528)
+++ gcc.dg/tree-ssa/vrp23.c (Arbeitskopie)
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details -fdump-tree-forwprop1" } */
void aa (void);
void aos (void);
@@ -44,6 +44,10 @@ L8:
/* The n_sets > 0 test can be simplified into n_sets == 1 since the
only way to reach the test is when n_sets <= 1, and the only value
- which satisfies both conditions is n_sets == 1. */
-/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
+ which satisfies both conditions is n_sets == 1.
+ We catch this pattern for this testcase already in forward-propagation
+ pass, as use of n_sets becomes single one. Therefore we expect that
+ vrp won't find this pattern anymore. */
+/* { dg-final { scan-tree-dump-times "Simplified relational" 0 "vrp1" } } */
+/* { dg-final { scan-tree-dump-times "Replaced" 3 "forwprop1" } } */
Index: gcc.dg/tree-ssa/vrp24.c
===================================================================
--- gcc.dg/tree-ssa/vrp24.c (Revision 227528)
+++ gcc.dg/tree-ssa/vrp24.c (Arbeitskopie)
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details -fdump-tree-forwprop1" } */
struct rtx_def;
@@ -90,6 +90,9 @@ L7:
The second n_sets > 0 test can also be simplified into n_sets == 1
as the only way to reach the tests is when n_sets <= 1 and the only
- value which satisfies both conditions is n_sets == 1. */
-/* { dg-final { scan-tree-dump-times "Simplified relational" 2 "vrp1" } } */
+ value which satisfies both conditions is n_sets == 1.
+ We catch one of the simplifications already in forward-propagation pass.
+ Therefore we exprect just one simplified relational detected
within vrp1. */
+/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
+/* { dg-final { scan-tree-dump-times "Replaced" 2 "forwprop1" } } */