Ping.
2015-09-08 13:17 GMT+02:00 Kai Tietz <[email protected]>:
> 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 <[email protected]>
>
> * 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 <[email protected]>
>
> * 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;
Make sure to split patch here. Above patch and this can't be applied together.
> 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" } } */