On Thu, Dec 01, 2016 at 01:33:17PM +0100, Bernd Schmidt wrote:
> On 11/21/2016 01:36 PM, Dominik Vogt wrote:
> >diff --git a/gcc/combine.c b/gcc/combine.c
> >index b22a274..457fe8a 100644
> >--- a/gcc/combine.c
> >+++ b/gcc/combine.c
> >@@ -5575,10 +5575,23 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, 
> >int in_dest,
> >     {
> >       rtx cop1 = const0_rtx;
> >       enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1);
> >+      unsigned HOST_WIDE_INT nz;
> >
> >       if (cond_code == NE && COMPARISON_P (cond))
> >         return x;
> >
> >+      /* If the operation is an AND wrapped in a SIGN_EXTEND or ZERO_EXTEND
> >+         with either operand being just a constant single bit value, do
> >+         nothing since IF_THEN_ELSE is likely to increase the expression's
> >+         complexity.  */
> >+      if (HWI_COMPUTABLE_MODE_P (mode)
> >+          && pow2p_hwi (nz = nonzero_bits (x, mode))
> >+          && ! ((code == SIGN_EXTEND || code == ZERO_EXTEND)
> >+                && GET_CODE (XEXP (x, 0)) == AND
> >+                && CONST_INT_P (XEXP (XEXP (x, 0), 0))
> >+                && UINTVAL (XEXP (XEXP (x, 0), 0)) == nz))
> >+        return x;
> 
> It looks like this doesn't actually use cond or true/false_rtx. So
> this could be placed just above the call to if_then_else_cond to
> avoid unnecessary work. Ok if that works.

It does.  Version 3 attached, bootstrapped on s390x and regression
tested on s390x biarch and s390.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany
gcc/ChangeLog

        * combine.c (combine_simplify_rtx):  Suppress replacement of
        "(and (reg) (const_int bit))" with "if_then_else".
>From 9202cab6332ce5dcfa740bbae3bcf07f3acc8705 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <v...@linux.vnet.ibm.com>
Date: Mon, 31 Oct 2016 09:00:31 +0100
Subject: [PATCH] Do not simplify "(and (reg) (const bit)" to if_then_else.

combine_simplify_rtx() tries to replace rtx expressions with just two
possible values with an experession that uses if_then_else:

  (if_then_else (condition) (value1) (value2))

If the original expression is e.g.

  (and (reg) (const_int 2))

where the constant is the mask for a single bit, the replacement results
in a more complex expression than before:

  (if_then_else (ne (zero_extract (reg) (1) (31))) (2) (0))

Similar replacements are done for

  (signextend (and ...))
  (zeroextend (and ...))

Suppress the replacement this special case in if_then_else_cond().
---
 gcc/combine.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/gcc/combine.c b/gcc/combine.c
index a8dae89..52bde9e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5600,6 +5600,18 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int 
in_dest,
                     && OBJECT_P (SUBREG_REG (XEXP (x, 0)))))))
     {
       rtx cond, true_rtx, false_rtx;
+      unsigned HOST_WIDE_INT nz;
+
+      /* If the operation is an AND wrapped in a SIGN_EXTEND or ZERO_EXTEND 
with
+        either operand being just a constant single bit value, do nothing since
+        IF_THEN_ELSE is likely to increase the expression's complexity.  */
+      if (HWI_COMPUTABLE_MODE_P (mode)
+         && pow2p_hwi (nz = nonzero_bits (x, mode))
+         && ! ((code == SIGN_EXTEND || code == ZERO_EXTEND)
+               && GET_CODE (XEXP (x, 0)) == AND
+               && CONST_INT_P (XEXP (XEXP (x, 0), 0))
+               && UINTVAL (XEXP (XEXP (x, 0), 0)) == nz))
+             return x;
 
       cond = if_then_else_cond (x, &true_rtx, &false_rtx);
       if (cond != 0
-- 
2.3.0

Reply via email to