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