Do not simplify "(and (reg) (const bit)" to if_then_else.
authorDominik Vogt <vogt@linux.vnet.ibm.com>
Fri, 2 Dec 2016 08:32:40 +0000 (08:32 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Fri, 2 Dec 2016 08:32:40 +0000 (08:32 +0000)
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/ChangeLog:

2016-12-02  Dominik Vogt  <vogt@linux.vnet.ibm.com>

* combine.c (combine_simplify_rtx):  Suppress replacement of
"(and (reg) (const_int bit))" with "if_then_else".

From-SVN: r243162

gcc/ChangeLog
gcc/combine.c

index e357932..a3fcd8b 100644 (file)
@@ -1,5 +1,10 @@
 2016-12-02  Dominik Vogt  <vogt@linux.vnet.ibm.com>
 
+       * combine.c (combine_simplify_rtx):  Suppress replacement of
+       "(and (reg) (const_int bit))" with "if_then_else".
+
+2016-12-02  Dominik Vogt  <vogt@linux.vnet.ibm.com>
+
        PR target/77822
        * config/s390/s390.md ("extzv")
        ("*extzv<mode><clobbercc_or_nocc>")
index b429453..7ba634a 100644 (file)
@@ -5602,6 +5602,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