This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch tree-optimization]: Fix for PR 45397 part 2 of 2


On Thu, Mar 15, 2012 at 2:09 PM, Kai Tietz <ktietz70@googlemail.com> wrote:
> Hi,
>
> this is the second part of the patch for this problem. ?It adds some
> basic simplifications for ==/!=
> comparisons for eliminating redudant operands.
>
> It adds the following patterns:
> ?-X ==/!= Z - X -> Z ==/!= 0.
> ?~X ==/!= Z ^ X -> Z ==/!= ~0
> ?X ==/!= X - Y -> Y == 0
> ?X ==/!= X + Y -> Y == 0
> ?X ==/!= X ^ Y -> Y == 0
> ?(X - Y) ==/!= (Z - Y) -> X ==/!= Z
> ?(Y - X) ==/!= (Y - Z) -> X ==/!= Z
> ?(X + Y) ==/!= (X + Z) -> Y ==/!= Z
> ?(X + Y) ==/!= (Z + X) -> Y ==/!= Z
> ?(X ^ Y) ==/!= (Z ^ X) -> Y ==/!= Z

Can you re-base this patch to work without the previous one?  Also
please coordinate with Andrew.  Note that all of these(?) simplifications
are already done by fold_comparison which we could share if you'd split
out the EXPR_P op0/op1 cases with separated operands/code.

Richard.

> ChangeLog
>
> 2012-03-15 ?Kai Tietz ?<ktietz@redhat.com>
>
> ? ? ? ?PR tree-optimization/45397
> ? ? ? ?* tree-ssa-forwprop.c (compare_equal_optimized_1): Add
> ? ? ? ?simplification patterns for ==/!= comparison.
>
> 2012-03-15 ?Kai Tietz ?<ktietz@redhat.com>
>
> ? ? ? ?* gcc.dg/tree-ssa/pr45397-2.c: New test.
>
> Regression tested for all languages (including Ada and Obj-C) on
> x86_64-unknown-linux-gnu. ?Ok for apply?
>
> Regards,
> Kai
>
> Index: gcc-trunk/gcc/tree-ssa-forwprop.c
> ===================================================================
> --- gcc-trunk.orig/gcc/tree-ssa-forwprop.c
> +++ gcc-trunk/gcc/tree-ssa-forwprop.c
> @@ -381,6 +381,99 @@ compare_equal_optimize_1 (gimple stmt, e
> ? ? ? || !INTEGRAL_TYPE_P (type_outer))
> ? ? return NULL_TREE;
>
> + ?/* Simplify -X ==/!= Z - X -> Z ==/!= 0. ?*/
> + ?if (TREE_CODE (op0) == NEGATE_EXPR
> + ? ? ?&& !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 0))
> + ? ? ?&& TREE_CODE (op1) == MINUS_EXPR
> + ? ? ?&& TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 1))
> + ? ? ? return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op1, 0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? build_zero_cst (TREE_TYPE (op1)));
> +
> + ?/* Simplify X - Z ==/!= -X -> Z ==/!= 0. ?*/
> + ?if (TREE_CODE (op1) == NEGATE_EXPR
> + ? ? ?&& !TREE_SIDE_EFFECTS (TREE_OPERAND (op1, 0))
> + ? ? ?&& TREE_CODE (op0) == MINUS_EXPR
> + ? ? ?&& TREE_OPERAND (op1, 0) == TREE_OPERAND (op0, 1))
> + ? ? ? return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op0, 0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? build_zero_cst (TREE_TYPE (op0)));
> +
> + ?/* Simplify ~X ==/!= X ^ Y to Y ==/!= ~0. ?*/
> + ?if (TREE_CODE (op0) == BIT_NOT_EXPR
> + ? ? ?&& !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 0))
> + ? ? ?&& TREE_CODE (op1) == BIT_XOR_EXPR)
> + ? ?{
> + ? ? ?if (TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 1))
> + ? ? ? return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op1, 0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fold_build1 (BIT_NOT_EXPR,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TREE_TYPE (op1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?build_zero_cst (TREE_TYPE (op1))));
> + ? ? ?if (TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 0))
> + ? ? ? return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op1, 1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fold_build1 (BIT_NOT_EXPR,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TREE_TYPE (op1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?build_zero_cst (TREE_TYPE (op1))));
> + ? ?}
> +
> + ?/* Simplify X ^ Y ==/!= ~X to Y ==/!= ~0. ?*/
> + ?if (TREE_CODE (op1) == BIT_NOT_EXPR
> + ? ? ?&& !TREE_SIDE_EFFECTS (TREE_OPERAND (op1, 0))
> + ? ? ?&& TREE_CODE (op0) == BIT_XOR_EXPR)
> + ? ?{
> + ? ? ?if (TREE_OPERAND (op1, 0) == TREE_OPERAND (op0, 1))
> + ? ? ? return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op0, 0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fold_build1 (BIT_NOT_EXPR,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TREE_TYPE (op0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?build_zero_cst (TREE_TYPE (op0))));
> + ? ? ?if (TREE_OPERAND (op1, 0) == TREE_OPERAND (op0, 0))
> + ? ? ? return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op0, 1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fold_build1 (BIT_NOT_EXPR,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TREE_TYPE (op0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?build_zero_cst (TREE_TYPE (op0))));
> + ? ?}
> +
> + ?/* For code being +, -, or ^-expression simplify (X code Y) ==/!= (Z code Y)
> + ? ? to (X ==/!= Z), and (X code Y) ==/!= (X code Z) to (Y ==/!= Z). ?*/
> + ?if (TREE_CODE (op0) == TREE_CODE (op1)
> + ? ? ?&& (TREE_CODE (op0) == PLUS_EXPR
> + ? ? ? ? ?|| TREE_CODE (op0) == MINUS_EXPR
> + ? ? ? ? ?|| TREE_CODE (op0) == BIT_XOR_EXPR))
> + ? ?{
> + ? ? ?/* Simplify (X code Y) ==/!= (X code Z) to Y ==/!= Z. ?*/
> + ? ? ?if (TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 0)
> + ? ? ? ? ?&& !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 0)))
> + ? ? ? return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op0, 1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op1, 1));
> + ? ? ?/* Simplify (X code Y) ==/!= (Z code X) to Y ==/!= Z, if code isn't
> + ? ? ? ?minus operation. ?*/
> + ? ? ?if (TREE_CODE (op0) != MINUS_EXPR
> + ? ? ? ? ?&& TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 1)
> + ? ? ? ? ?&& !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 0)))
> + ? ? ? ?return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op0, 1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op1, 0));
> + ? ? ?/* Simplify (Y code X) ==/!= (X code Z) to Y ==/!= Z, if code isn't
> + ? ? ? ?minus operation. ?*/
> + ? ? ?if (TREE_CODE (op0) != MINUS_EXPR
> + ? ? ? ? ?&& TREE_OPERAND (op0, 1) == TREE_OPERAND (op1, 0)
> + ? ? ? ? ?&& !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 1)))
> + ? ? ? ?return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op0, 0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op1, 1));
> + ? ? ?/* Simplify (Y code X) ==/!= (Z code X) to Y ==/!= Z. ?*/
> + ? ? ?if (TREE_OPERAND (op0, 1) == TREE_OPERAND (op1, 1)
> + ? ? ? ? ?&& !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 1)))
> + ? ? ? ?return fold_build2_loc (gimple_location (stmt), code, type,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op0, 0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TREE_OPERAND (op1, 0));
> + ? ?}
> +
> ? /* If OP0 isn't a conversion, then check if OP1 might be one. ?If so
> ? ? ?swap arguments, otherwise return NULL_TREE. ?*/
> ? if (!CONVERT_EXPR_P (op0))
> Index: gcc-trunk/gcc/testsuite/gcc.dg/tree-ssa/pr45397-2.c
> ===================================================================
> --- /dev/null
> +++ gcc-trunk/gcc/testsuite/gcc.dg/tree-ssa/pr45397-2.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +int
> +foo (const unsigned char *a, int b, int c)
> +{
> + ?int x = (unsigned char) (a[b] + c);
> + ?int y = a[b] + c;
> + ?int z = (unsigned char) y;
> + ?return x == z;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "return 1" 1 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> +


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]