public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix REG_EQUAL notes for doubleword POPCOUNT etc. unops (PR target/88905)
@ 2019-01-21 22:22 Jakub Jelinek
  2019-01-22  8:31 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2019-01-21 22:22 UTC (permalink / raw)
  To: Richard Biener, Eric Botcazou; +Cc: gcc-patches

Hi!

add_equal_note has special code to handle properly doubleword POPCOUNT and
similar builtins, e.g. for POPCOUNT if we don't have DImode POPCOUNT, it can
be expanded as 2 SImode POPCOUNTs added together, but for the REG_EQUAL note
we want lowpart SImode SUBREG of DImode POPCOUNT.

Unfortunately, this doesn't really work if the operand is constant and we
are unlucky enough that it hasn't been folded during GIMPLE optimizations
- we still need to use DImode POPCOUNT and take subreg of it.

The following patch fixes it by padding the op0's mode to the function too
and use it everywhere instead of GET_MODE (op0).  For op1 we don't really
need that, that is for binary operations where both arguments have the same
mode or we don't really care about the mode of the last operand (shifts).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-01-21  Jakub Jelinek  <jakub@redhat.com>

	PR target/88905
	* optabs.c (add_equal_note): Add op0_mode argument, use it instead of
	GET_MODE (op0).
	(expand_binop_directly, expand_doubleword_clz,
	expand_doubleword_popcount, expand_ctz, expand_ffs,
	expand_unop_direct, maybe_emit_unop_insn): Adjust callers.

	* gcc.dg/pr88905.c: New test.

--- gcc/optabs.c.jj	2019-01-01 12:37:17.711965861 +0100
+++ gcc/optabs.c	2019-01-21 13:56:18.263446049 +0100
@@ -55,7 +55,7 @@ void debug_optab_libfuncs (void);
 \f
 /* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
    the result of operation CODE applied to OP0 (and OP1 if it is a binary
-   operation).
+   operation).  OP0_MODE is OP0's mode.
 
    If the last insn does not set TARGET, don't do anything, but return 1.
 
@@ -64,7 +64,8 @@ void debug_optab_libfuncs (void);
    try again, ensuring that TARGET is not one of the operands.  */
 
 static int
-add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
+add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
+		rtx op1, machine_mode op0_mode)
 {
   rtx_insn *last_insn;
   rtx set;
@@ -136,16 +137,16 @@ add_equal_note (rtx_insn *insns, rtx tar
       case POPCOUNT:
       case PARITY:
       case BSWAP:
-	if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
+	if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
 	  {
-	    note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
-	    if (GET_MODE_UNIT_SIZE (GET_MODE (op0))
+	    note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
+	    if (GET_MODE_UNIT_SIZE (op0_mode)
 		> GET_MODE_UNIT_SIZE (GET_MODE (target)))
 	      note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
-					 note, GET_MODE (op0));
+					 note, op0_mode);
 	    else
 	      note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
-					 note, GET_MODE (op0));
+					 note, op0_mode);
 	    break;
 	  }
 	/* FALLTHRU */
@@ -1127,7 +1128,7 @@ expand_binop_directly (enum insn_code ic
       if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
 	  && ! add_equal_note (pat, ops[0].value,
 			       optab_to_code (binoptab),
-			       ops[1].value, ops[2].value))
+			       ops[1].value, ops[2].value, mode0))
 	{
 	  delete_insns_since (last);
 	  return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
@@ -2298,7 +2299,7 @@ expand_doubleword_clz (scalar_int_mode m
   seq = get_insns ();
   end_sequence ();
 
-  add_equal_note (seq, target, CLZ, xop0, 0);
+  add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode);
   emit_insn (seq);
   return target;
 
@@ -2340,7 +2341,7 @@ expand_doubleword_popcount (scalar_int_m
   seq = get_insns ();
   end_sequence ();
 
-  add_equal_note (seq, t, POPCOUNT, op0, 0);
+  add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
   emit_insn (seq);
   return t;
 }
@@ -2511,7 +2512,7 @@ expand_ctz (scalar_int_mode mode, rtx op
   seq = get_insns ();
   end_sequence ();
 
-  add_equal_note (seq, temp, CTZ, op0, 0);
+  add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
   emit_insn (seq);
   return temp;
 }
@@ -2589,7 +2590,7 @@ expand_ffs (scalar_int_mode mode, rtx op
   seq = get_insns ();
   end_sequence ();
 
-  add_equal_note (seq, temp, FFS, op0, 0);
+  add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
   emit_insn (seq);
   return temp;
 
@@ -2736,7 +2737,7 @@ expand_unop_direct (machine_mode mode, o
 	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
 	      && ! add_equal_note (pat, ops[0].value,
 				   optab_to_code (unoptab),
-				   ops[1].value, NULL_RTX))
+				   ops[1].value, NULL_RTX, mode))
 	    {
 	      delete_insns_since (last);
 	      return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
@@ -3588,7 +3589,8 @@ maybe_emit_unop_insn (enum insn_code ico
 
   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
       && code != UNKNOWN)
-    add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
+    add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
+		    GET_MODE (op0));
 
   emit_insn (pat);
 
--- gcc/testsuite/gcc.dg/pr88905.c.jj	2019-01-21 14:19:17.279746531 +0100
+++ gcc/testsuite/gcc.dg/pr88905.c	2019-01-21 14:18:56.264091537 +0100
@@ -0,0 +1,21 @@
+/* PR target/88905 */
+/* { dg-do compile } */
+/* { dg-options "-Og -fno-tree-ccp" } */
+/* { dg-additional-options "-mabm" { target { i?86-*-* x86_64-*-* } } } */
+
+int a, b, c;
+extern void baz (int);
+
+static inline int
+bar (unsigned u)
+{
+  int i = __builtin_popcountll (-(unsigned long long) u);
+  baz (i & c);
+  return a + b + c;
+}
+
+void
+foo (void)
+{
+  bar (2376498292ULL);
+}

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix REG_EQUAL notes for doubleword POPCOUNT etc. unops (PR target/88905)
  2019-01-21 22:22 [PATCH] Fix REG_EQUAL notes for doubleword POPCOUNT etc. unops (PR target/88905) Jakub Jelinek
@ 2019-01-22  8:31 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2019-01-22  8:31 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Eric Botcazou, gcc-patches

On Mon, 21 Jan 2019, Jakub Jelinek wrote:

> Hi!
> 
> add_equal_note has special code to handle properly doubleword POPCOUNT and
> similar builtins, e.g. for POPCOUNT if we don't have DImode POPCOUNT, it can
> be expanded as 2 SImode POPCOUNTs added together, but for the REG_EQUAL note
> we want lowpart SImode SUBREG of DImode POPCOUNT.
> 
> Unfortunately, this doesn't really work if the operand is constant and we
> are unlucky enough that it hasn't been folded during GIMPLE optimizations
> - we still need to use DImode POPCOUNT and take subreg of it.
> 
> The following patch fixes it by padding the op0's mode to the function too
> and use it everywhere instead of GET_MODE (op0).  For op1 we don't really
> need that, that is for binary operations where both arguments have the same
> mode or we don't really care about the mode of the last operand (shifts).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2019-01-21  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR target/88905
> 	* optabs.c (add_equal_note): Add op0_mode argument, use it instead of
> 	GET_MODE (op0).
> 	(expand_binop_directly, expand_doubleword_clz,
> 	expand_doubleword_popcount, expand_ctz, expand_ffs,
> 	expand_unop_direct, maybe_emit_unop_insn): Adjust callers.
> 
> 	* gcc.dg/pr88905.c: New test.
> 
> --- gcc/optabs.c.jj	2019-01-01 12:37:17.711965861 +0100
> +++ gcc/optabs.c	2019-01-21 13:56:18.263446049 +0100
> @@ -55,7 +55,7 @@ void debug_optab_libfuncs (void);
>  \f
>  /* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
>     the result of operation CODE applied to OP0 (and OP1 if it is a binary
> -   operation).
> +   operation).  OP0_MODE is OP0's mode.
>  
>     If the last insn does not set TARGET, don't do anything, but return 1.
>  
> @@ -64,7 +64,8 @@ void debug_optab_libfuncs (void);
>     try again, ensuring that TARGET is not one of the operands.  */
>  
>  static int
> -add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
> +add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
> +		rtx op1, machine_mode op0_mode)
>  {
>    rtx_insn *last_insn;
>    rtx set;
> @@ -136,16 +137,16 @@ add_equal_note (rtx_insn *insns, rtx tar
>        case POPCOUNT:
>        case PARITY:
>        case BSWAP:
> -	if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
> +	if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
>  	  {
> -	    note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
> -	    if (GET_MODE_UNIT_SIZE (GET_MODE (op0))
> +	    note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
> +	    if (GET_MODE_UNIT_SIZE (op0_mode)
>  		> GET_MODE_UNIT_SIZE (GET_MODE (target)))
>  	      note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
> -					 note, GET_MODE (op0));
> +					 note, op0_mode);
>  	    else
>  	      note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
> -					 note, GET_MODE (op0));
> +					 note, op0_mode);
>  	    break;
>  	  }
>  	/* FALLTHRU */
> @@ -1127,7 +1128,7 @@ expand_binop_directly (enum insn_code ic
>        if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
>  	  && ! add_equal_note (pat, ops[0].value,
>  			       optab_to_code (binoptab),
> -			       ops[1].value, ops[2].value))
> +			       ops[1].value, ops[2].value, mode0))
>  	{
>  	  delete_insns_since (last);
>  	  return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
> @@ -2298,7 +2299,7 @@ expand_doubleword_clz (scalar_int_mode m
>    seq = get_insns ();
>    end_sequence ();
>  
> -  add_equal_note (seq, target, CLZ, xop0, 0);
> +  add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode);
>    emit_insn (seq);
>    return target;
>  
> @@ -2340,7 +2341,7 @@ expand_doubleword_popcount (scalar_int_m
>    seq = get_insns ();
>    end_sequence ();
>  
> -  add_equal_note (seq, t, POPCOUNT, op0, 0);
> +  add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
>    emit_insn (seq);
>    return t;
>  }
> @@ -2511,7 +2512,7 @@ expand_ctz (scalar_int_mode mode, rtx op
>    seq = get_insns ();
>    end_sequence ();
>  
> -  add_equal_note (seq, temp, CTZ, op0, 0);
> +  add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
>    emit_insn (seq);
>    return temp;
>  }
> @@ -2589,7 +2590,7 @@ expand_ffs (scalar_int_mode mode, rtx op
>    seq = get_insns ();
>    end_sequence ();
>  
> -  add_equal_note (seq, temp, FFS, op0, 0);
> +  add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
>    emit_insn (seq);
>    return temp;
>  
> @@ -2736,7 +2737,7 @@ expand_unop_direct (machine_mode mode, o
>  	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
>  	      && ! add_equal_note (pat, ops[0].value,
>  				   optab_to_code (unoptab),
> -				   ops[1].value, NULL_RTX))
> +				   ops[1].value, NULL_RTX, mode))
>  	    {
>  	      delete_insns_since (last);
>  	      return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
> @@ -3588,7 +3589,8 @@ maybe_emit_unop_insn (enum insn_code ico
>  
>    if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
>        && code != UNKNOWN)
> -    add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
> +    add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
> +		    GET_MODE (op0));
>  
>    emit_insn (pat);
>  
> --- gcc/testsuite/gcc.dg/pr88905.c.jj	2019-01-21 14:19:17.279746531 +0100
> +++ gcc/testsuite/gcc.dg/pr88905.c	2019-01-21 14:18:56.264091537 +0100
> @@ -0,0 +1,21 @@
> +/* PR target/88905 */
> +/* { dg-do compile } */
> +/* { dg-options "-Og -fno-tree-ccp" } */
> +/* { dg-additional-options "-mabm" { target { i?86-*-* x86_64-*-* } } } */
> +
> +int a, b, c;
> +extern void baz (int);
> +
> +static inline int
> +bar (unsigned u)
> +{
> +  int i = __builtin_popcountll (-(unsigned long long) u);
> +  baz (i & c);
> +  return a + b + c;
> +}
> +
> +void
> +foo (void)
> +{
> +  bar (2376498292ULL);
> +}
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-01-22  8:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-21 22:22 [PATCH] Fix REG_EQUAL notes for doubleword POPCOUNT etc. unops (PR target/88905) Jakub Jelinek
2019-01-22  8:31 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).