public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Slightly improve TARGET_STV splitters (PR target/70321)
@ 2016-03-22 21:48 Jakub Jelinek
  2016-03-23  8:35 ` Uros Bizjak
  0 siblings, 1 reply; 3+ messages in thread
From: Jakub Jelinek @ 2016-03-22 21:48 UTC (permalink / raw)
  To: Uros Bizjak, Kirill Yukhin; +Cc: gcc-patches

Hi!

As the PR mentions, DImode AND/IOR/XOR patterns often result in too ugly
code, regression from when the patterns weren't there (before STV has been
added).  This patch attempts to improve it a little bit by improving the
splitter for these, rather than always generating two SImode AND/IOR/XOR
instructions, if the last operand's subword is either 0 or -1, optimize
the corresponding instruction in the pair to nothing, or to clearing, or
negation.  More improvement can be IMHO only achieved by moving the STV
pass before combiner and split patterns we don't adjust into vector patterns
into corresponding SImode patterns, so that the combiner can handle them,
but that sounds like stage1 material.

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

2016-03-22  Jakub Jelinek  <jakub@redhat.com>

	PR target/70321
	* config/i386/i386.md (*anddi3_doubleword, *<code>di3_doubleword):
	Optimize TARGET_STV splitters, if high or low word of last argument
	is 0 or -1.

--- gcc/config/i386/i386.md.jj	2016-03-22 09:13:54.000000000 +0100
+++ gcc/config/i386/i386.md	2016-03-22 18:45:16.392316554 +0100
@@ -8141,16 +8141,31 @@
 	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
 	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
    (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (AND, DImode, operands)"
+  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+   && ix86_binary_operator_ok (AND, DImode, operands)"
   "#"
   "&& reload_completed"
-  [(parallel [(set (match_dup 0)
-		   (and:SI (match_dup 1) (match_dup 2)))
-	      (clobber (reg:CC FLAGS_REG))])
-   (parallel [(set (match_dup 3)
-		   (and:SI (match_dup 4) (match_dup 5)))
-	      (clobber (reg:CC FLAGS_REG))])]
-  "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
+  [(const_int 0)]
+{
+  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
+  if (operands[2] == const0_rtx)
+    {
+      operands[1] = const0_rtx;
+      ix86_expand_move (SImode, &operands[0]);
+    }
+  else if (operands[2] != constm1_rtx)
+    emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
+  else if (operands[5] == constm1_rtx)
+    emit_note (NOTE_INSN_DELETED);
+  if (operands[5] == const0_rtx)
+    {
+      operands[4] = const0_rtx;
+      ix86_expand_move (SImode, &operands[3]);
+    }
+  else if (operands[5] != constm1_rtx)
+    emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
+  DONE;
+})
 
 (define_insn "*andsi_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
@@ -8665,16 +8680,41 @@
 	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
 	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
    (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
+  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+   && ix86_binary_operator_ok (<CODE>, DImode, operands)"
   "#"
   "&& reload_completed"
-  [(parallel [(set (match_dup 0)
-		   (any_or:SI (match_dup 1) (match_dup 2)))
-	      (clobber (reg:CC FLAGS_REG))])
-   (parallel [(set (match_dup 3)
-		   (any_or:SI (match_dup 4) (match_dup 5)))
-	      (clobber (reg:CC FLAGS_REG))])]
-  "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
+  [(const_int 0)]
+{
+  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
+  if (operands[2] == constm1_rtx)
+    {
+      if (<CODE> == IOR)
+	{
+	  operands[1] = constm1_rtx;
+	  ix86_expand_move (SImode, &operands[0]);
+	}
+      else
+	ix86_expand_unary_operator (NOT, SImode, &operands[0]);
+    }
+  else if (operands[2] != const0_rtx)
+    ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
+  else if (operands[5] == const0_rtx)
+    emit_note (NOTE_INSN_DELETED);
+  if (operands[5] == constm1_rtx)
+    {
+      if (<CODE> == IOR)
+	{
+	  operands[4] = constm1_rtx;
+	  ix86_expand_move (SImode, &operands[3]);
+	}
+      else
+	ix86_expand_unary_operator (NOT, SImode, &operands[3]);
+    }
+  else if (operands[5] != const0_rtx)
+    ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
+  DONE;
+})
 
 (define_insn_and_split "*andndi3_doubleword"
   [(set (match_operand:DI 0 "register_operand" "=r,r")

	Jakub

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

* Re: [PATCH] Slightly improve TARGET_STV splitters (PR target/70321)
  2016-03-22 21:48 [PATCH] Slightly improve TARGET_STV splitters (PR target/70321) Jakub Jelinek
@ 2016-03-23  8:35 ` Uros Bizjak
  2016-03-24 14:59   ` Uros Bizjak
  0 siblings, 1 reply; 3+ messages in thread
From: Uros Bizjak @ 2016-03-23  8:35 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Kirill Yukhin, gcc-patches

On Tue, Mar 22, 2016 at 10:37 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> As the PR mentions, DImode AND/IOR/XOR patterns often result in too ugly
> code, regression from when the patterns weren't there (before STV has been
> added).  This patch attempts to improve it a little bit by improving the
> splitter for these, rather than always generating two SImode AND/IOR/XOR
> instructions, if the last operand's subword is either 0 or -1, optimize
> the corresponding instruction in the pair to nothing, or to clearing, or
> negation.  More improvement can be IMHO only achieved by moving the STV
> pass before combiner and split patterns we don't adjust into vector patterns
> into corresponding SImode patterns, so that the combiner can handle them,
> but that sounds like stage1 material.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2016-03-22  Jakub Jelinek  <jakub@redhat.com>
>
>         PR target/70321
>         * config/i386/i386.md (*anddi3_doubleword, *<code>di3_doubleword):
>         Optimize TARGET_STV splitters, if high or low word of last argument
>         is 0 or -1.

Looks reasonable and safe.

OK.

Thanks,
Uros.

> --- gcc/config/i386/i386.md.jj  2016-03-22 09:13:54.000000000 +0100
> +++ gcc/config/i386/i386.md     2016-03-22 18:45:16.392316554 +0100
> @@ -8141,16 +8141,31 @@
>          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
>          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
>     (clobber (reg:CC FLAGS_REG))]
> -  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (AND, DImode, operands)"
> +  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
> +   && ix86_binary_operator_ok (AND, DImode, operands)"
>    "#"
>    "&& reload_completed"
> -  [(parallel [(set (match_dup 0)
> -                  (and:SI (match_dup 1) (match_dup 2)))
> -             (clobber (reg:CC FLAGS_REG))])
> -   (parallel [(set (match_dup 3)
> -                  (and:SI (match_dup 4) (match_dup 5)))
> -             (clobber (reg:CC FLAGS_REG))])]
> -  "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
> +  [(const_int 0)]
> +{
> +  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
> +  if (operands[2] == const0_rtx)
> +    {
> +      operands[1] = const0_rtx;
> +      ix86_expand_move (SImode, &operands[0]);
> +    }
> +  else if (operands[2] != constm1_rtx)
> +    emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
> +  else if (operands[5] == constm1_rtx)
> +    emit_note (NOTE_INSN_DELETED);
> +  if (operands[5] == const0_rtx)
> +    {
> +      operands[4] = const0_rtx;
> +      ix86_expand_move (SImode, &operands[3]);
> +    }
> +  else if (operands[5] != constm1_rtx)
> +    emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
> +  DONE;
> +})
>
>  (define_insn "*andsi_1"
>    [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
> @@ -8665,16 +8680,41 @@
>          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
>          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
>     (clobber (reg:CC FLAGS_REG))]
> -  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
> +  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
> +   && ix86_binary_operator_ok (<CODE>, DImode, operands)"
>    "#"
>    "&& reload_completed"
> -  [(parallel [(set (match_dup 0)
> -                  (any_or:SI (match_dup 1) (match_dup 2)))
> -             (clobber (reg:CC FLAGS_REG))])
> -   (parallel [(set (match_dup 3)
> -                  (any_or:SI (match_dup 4) (match_dup 5)))
> -             (clobber (reg:CC FLAGS_REG))])]
> -  "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
> +  [(const_int 0)]
> +{
> +  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
> +  if (operands[2] == constm1_rtx)
> +    {
> +      if (<CODE> == IOR)
> +       {
> +         operands[1] = constm1_rtx;
> +         ix86_expand_move (SImode, &operands[0]);
> +       }
> +      else
> +       ix86_expand_unary_operator (NOT, SImode, &operands[0]);
> +    }
> +  else if (operands[2] != const0_rtx)
> +    ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
> +  else if (operands[5] == const0_rtx)
> +    emit_note (NOTE_INSN_DELETED);
> +  if (operands[5] == constm1_rtx)
> +    {
> +      if (<CODE> == IOR)
> +       {
> +         operands[4] = constm1_rtx;
> +         ix86_expand_move (SImode, &operands[3]);
> +       }
> +      else
> +       ix86_expand_unary_operator (NOT, SImode, &operands[3]);
> +    }
> +  else if (operands[5] != const0_rtx)
> +    ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
> +  DONE;
> +})
>
>  (define_insn_and_split "*andndi3_doubleword"
>    [(set (match_operand:DI 0 "register_operand" "=r,r")
>
>         Jakub

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

* Re: [PATCH] Slightly improve TARGET_STV splitters (PR target/70321)
  2016-03-23  8:35 ` Uros Bizjak
@ 2016-03-24 14:59   ` Uros Bizjak
  0 siblings, 0 replies; 3+ messages in thread
From: Uros Bizjak @ 2016-03-24 14:59 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Kirill Yukhin, gcc-patches

On Wed, Mar 23, 2016 at 8:35 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Tue, Mar 22, 2016 at 10:37 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>> Hi!
>>
>> As the PR mentions, DImode AND/IOR/XOR patterns often result in too ugly
>> code, regression from when the patterns weren't there (before STV has been
>> added).  This patch attempts to improve it a little bit by improving the
>> splitter for these, rather than always generating two SImode AND/IOR/XOR
>> instructions, if the last operand's subword is either 0 or -1, optimize
>> the corresponding instruction in the pair to nothing, or to clearing, or
>> negation.  More improvement can be IMHO only achieved by moving the STV
>> pass before combiner and split patterns we don't adjust into vector patterns
>> into corresponding SImode patterns, so that the combiner can handle them,
>> but that sounds like stage1 material.

Following patch fixes:

FAIL: gcc.c-torture/execute/bitfld-3.c   -O1  (internal compiler error)
FAIL: gcc.c-torture/execute/bitfld-3.c   -O1  (test for excess errors)

We should not expand post reload via gen_andsi3, since we can generate
movzbl with unsupported QImode register.

2016-03-24  Uros Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.md (*anddi3_doubleword): Generate AND insn
    using ix86_expand_binary_operator instead of gen_andsi3.

Bootstrap and regression test in process, will commit the patch when
regtest finish.

Uros.

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 51e9a6e..339a134 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -8154,7 +8154,7 @@
       ix86_expand_move (SImode, &operands[0]);
     }
   else if (operands[2] != constm1_rtx)
-    emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
+    ix86_expand_binary_operator (AND, SImode, &operands[0]);
   else if (operands[5] == constm1_rtx)
     emit_note (NOTE_INSN_DELETED);
   if (operands[5] == const0_rtx)
@@ -8163,7 +8163,7 @@
       ix86_expand_move (SImode, &operands[3]);
     }
   else if (operands[5] != constm1_rtx)
-    emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
+    ix86_expand_binary_operator (AND, SImode, &operands[3]);
   DONE;
 })

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

end of thread, other threads:[~2016-03-24 14:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-22 21:48 [PATCH] Slightly improve TARGET_STV splitters (PR target/70321) Jakub Jelinek
2016-03-23  8:35 ` Uros Bizjak
2016-03-24 14:59   ` Uros Bizjak

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).