diff mbox series

middle-end: fix ICE when moving statements to empty BB [PR113731]

Message ID patch-18247-tamar@arm.com
State New
Headers show
Series middle-end: fix ICE when moving statements to empty BB [PR113731] | expand

Commit Message

Tamar Christina Feb. 5, 2024, 1:08 p.m. UTC
Hi All,

We use gsi_move_before (&stmt_gsi, &dest_gsi); to request that the new statement
be placed before any other statement.  Typically this then moves the current
pointer to be after the statement we just inserted.

However it looks like when the BB is empty, this does not happen and the CUR
pointer stays NULL.   There's a comment in the source of gsi_insert_before that
explains:

/* If CUR is NULL, we link at the end of the sequence (this case happens

so it adds it to the end instead of start like you asked.  This means that in
this case there's nothing to move and so we shouldn't move the pointer if we're
already at the HEAD.

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

	PR tree-optimization/113731
	* tree-vect-loop.cc (move_early_exit_stmts): Conditionally move pointer.

gcc/testsuite/ChangeLog:

	PR tree-optimization/113731
	* gcc.dg/vect/vect-early-break_111-pr113731.c: New test.

--- inline copy of patch -- 
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d6db91df97625a7f11609d034e89af0461129b2




--
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d6db91df97625a7f11609d034e89af0461129b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+char* inet_net_pton_ipv4_bits;
+char inet_net_pton_ipv4_odst;
+void __errno_location();
+void inet_net_pton_ipv4();
+void inet_net_pton() { inet_net_pton_ipv4(); }
+void inet_net_pton_ipv4(char *dst, int size) {
+  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
+    if (size-- <= 0)
+      goto emsgsize;
+    *dst++ = '\0';
+  }
+emsgsize:
+  __errno_location();
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 30b90d99925bea74caf14833d8ab1695607d0fe9..e2587315020a35a7d4ebd3e7a9842caa36bb5d3c 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -11801,7 +11801,8 @@ move_early_exit_stmts (loop_vec_info loop_vinfo)
 
       gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
       gsi_move_before (&stmt_gsi, &dest_gsi);
-      gsi_prev (&dest_gsi);
+      if (!gsi_end_p (dest_gsi))
+	gsi_prev (&dest_gsi);
     }
 
   /* Update all the stmts with their new reaching VUSES.  */

Comments

Richard Biener Feb. 5, 2024, 1:21 p.m. UTC | #1
On Mon, 5 Feb 2024, Tamar Christina wrote:

> Hi All,
> 
> We use gsi_move_before (&stmt_gsi, &dest_gsi); to request that the new statement
> be placed before any other statement.  Typically this then moves the current
> pointer to be after the statement we just inserted.
> 
> However it looks like when the BB is empty, this does not happen and the CUR
> pointer stays NULL.   There's a comment in the source of gsi_insert_before that
> explains:
> 
> /* If CUR is NULL, we link at the end of the sequence (this case happens
> 
> so it adds it to the end instead of start like you asked.  This means that in
> this case there's nothing to move and so we shouldn't move the pointer if we're
> already at the HEAD.

The issue is that a gsi_end_p () is ambiguous, it could be the start
or the end.  gsi_insert_before treats it as "end" while gsi_insert_after
treats it as "start" since you can't really insert "after" the "end".

gsi_move_before doesn't update the insertion pointer (using 
GSI_SAME_STMT), so with a gsi_end_p () you get what you ask for.

Btw,

  /* Move all stmts that need moving.  */
  basic_block dest_bb = LOOP_VINFO_EARLY_BRK_DEST_BB (loop_vinfo);
  gimple_stmt_iterator dest_gsi = gsi_start_bb (dest_bb);

should probably use gsi_after_labels (dest_bb) just in case.

It looks like LOOP_VINFO_EARLY_BRK_STORES is "reverse"?  Is that
why you are doing gsi_move_before + gsi_prev?  Why do gsi_prev
at all?

> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> 
> Ok for master?
> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
> 	PR tree-optimization/113731
> 	* tree-vect-loop.cc (move_early_exit_stmts): Conditionally move pointer.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR tree-optimization/113731
> 	* gcc.dg/vect/vect-early-break_111-pr113731.c: New test.
> 
> --- inline copy of patch -- 
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..2d6db91df97625a7f11609d034e89af0461129b2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
> +
> +char* inet_net_pton_ipv4_bits;
> +char inet_net_pton_ipv4_odst;
> +void __errno_location();
> +void inet_net_pton_ipv4();
> +void inet_net_pton() { inet_net_pton_ipv4(); }
> +void inet_net_pton_ipv4(char *dst, int size) {
> +  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
> +    if (size-- <= 0)
> +      goto emsgsize;
> +    *dst++ = '\0';
> +  }
> +emsgsize:
> +  __errno_location();
> +}
> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index 30b90d99925bea74caf14833d8ab1695607d0fe9..e2587315020a35a7d4ebd3e7a9842caa36bb5d3c 100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -11801,7 +11801,8 @@ move_early_exit_stmts (loop_vec_info loop_vinfo)
>  
>        gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
>        gsi_move_before (&stmt_gsi, &dest_gsi);
> -      gsi_prev (&dest_gsi);
> +      if (!gsi_end_p (dest_gsi))
> +	gsi_prev (&dest_gsi);
>      }
>  
>    /* Update all the stmts with their new reaching VUSES.  */
> 
> 
> 
> 
>
Tamar Christina Feb. 5, 2024, 1:25 p.m. UTC | #2
> -----Original Message-----
> From: Richard Biener <rguenther@suse.de>
> Sent: Monday, February 5, 2024 1:22 PM
> To: Tamar Christina <Tamar.Christina@arm.com>
> Cc: gcc-patches@gcc.gnu.org; nd <nd@arm.com>; jlaw@ventanamicro.com
> Subject: Re: [PATCH]middle-end: fix ICE when moving statements to empty BB
> [PR113731]
> 
> On Mon, 5 Feb 2024, Tamar Christina wrote:
> 
> > Hi All,
> >
> > We use gsi_move_before (&stmt_gsi, &dest_gsi); to request that the new
> statement
> > be placed before any other statement.  Typically this then moves the current
> > pointer to be after the statement we just inserted.
> >
> > However it looks like when the BB is empty, this does not happen and the CUR
> > pointer stays NULL.   There's a comment in the source of gsi_insert_before that
> > explains:
> >
> > /* If CUR is NULL, we link at the end of the sequence (this case happens
> >
> > so it adds it to the end instead of start like you asked.  This means that in
> > this case there's nothing to move and so we shouldn't move the pointer if we're
> > already at the HEAD.
> 
> The issue is that a gsi_end_p () is ambiguous, it could be the start
> or the end.  gsi_insert_before treats it as "end" while gsi_insert_after
> treats it as "start" since you can't really insert "after" the "end".
> 
> gsi_move_before doesn't update the insertion pointer (using
> GSI_SAME_STMT), so with a gsi_end_p () you get what you ask for.
> 
> Btw,
> 
>   /* Move all stmts that need moving.  */
>   basic_block dest_bb = LOOP_VINFO_EARLY_BRK_DEST_BB (loop_vinfo);
>   gimple_stmt_iterator dest_gsi = gsi_start_bb (dest_bb);
> 
> should probably use gsi_after_labels (dest_bb) just in case.

See next patch.

> 
> It looks like LOOP_VINFO_EARLY_BRK_STORES is "reverse"?  Is that
> why you are doing gsi_move_before + gsi_prev?  Why do gsi_prev
> at all?
> 

Yes, it stores them reverse because we record them from the latch on up.
So we either have to iterate backwards, insert them to the front or move gsi.

I guess I could remove it by removing the for-each loop and iterating in
reverse.  Is that preferred?

Tamar.

> > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> >
> > Ok for master?
> >
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> > 	PR tree-optimization/113731
> > 	* tree-vect-loop.cc (move_early_exit_stmts): Conditionally move pointer.
> >
> > gcc/testsuite/ChangeLog:
> >
> > 	PR tree-optimization/113731
> > 	* gcc.dg/vect/vect-early-break_111-pr113731.c: New test.
> >
> > --- inline copy of patch --
> > diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
> b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
> > new file mode 100644
> > index
> 0000000000000000000000000000000000000000..2d6db91df97625a7f1160
> 9d034e89af0461129b2
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
> > @@ -0,0 +1,21 @@
> > +/* { dg-do compile } */
> > +/* { dg-add-options vect_early_break } */
> > +/* { dg-require-effective-target vect_early_break } */
> > +/* { dg-require-effective-target vect_int } */
> > +
> > +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
> > +
> > +char* inet_net_pton_ipv4_bits;
> > +char inet_net_pton_ipv4_odst;
> > +void __errno_location();
> > +void inet_net_pton_ipv4();
> > +void inet_net_pton() { inet_net_pton_ipv4(); }
> > +void inet_net_pton_ipv4(char *dst, int size) {
> > +  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
> > +    if (size-- <= 0)
> > +      goto emsgsize;
> > +    *dst++ = '\0';
> > +  }
> > +emsgsize:
> > +  __errno_location();
> > +}
> > diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> > index
> 30b90d99925bea74caf14833d8ab1695607d0fe9..e2587315020a35a7d4ebd3e
> 7a9842caa36bb5d3c 100644
> > --- a/gcc/tree-vect-loop.cc
> > +++ b/gcc/tree-vect-loop.cc
> > @@ -11801,7 +11801,8 @@ move_early_exit_stmts (loop_vec_info loop_vinfo)
> >
> >        gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
> >        gsi_move_before (&stmt_gsi, &dest_gsi);
> > -      gsi_prev (&dest_gsi);
> > +      if (!gsi_end_p (dest_gsi))
> > +	gsi_prev (&dest_gsi);
> >      }
> >
> >    /* Update all the stmts with their new reaching VUSES.  */
> >
> >
> >
> >
> >
> 
> --
> Richard Biener <rguenther@suse.de>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
Tamar Christina Feb. 5, 2024, 2:04 p.m. UTC | #3
> It looks like LOOP_VINFO_EARLY_BRK_STORES is "reverse"?  Is that
> why you are doing gsi_move_before + gsi_prev?  Why do gsi_prev
> at all?
> 

As discussed on IRC, then how about this one.
Incremental building passed all tests and bootstrap is running.

Ok for master if bootstrap and regtesting clean?

Thanks,
Tamar

gcc/ChangeLog:

	PR tree-optimization/113731
	* gimple-iterator.cc (gsi_move_before): Take new parameter for update
	method.
	* gimple-iterator.h (gsi_move_before): Default new param to
	GSI_SAME_STMT.
	* tree-vect-loop.cc (move_early_exit_stmts): Call gsi_move_before with
	GSI_NEW_STMT.

gcc/testsuite/ChangeLog:

	PR tree-optimization/113731
	* gcc.dg/vect/vect-early-break_111-pr113731.c: New test.

--- inline copy of patch ---

diff --git a/gcc/gimple-iterator.cc b/gcc/gimple-iterator.cc
index 517c53376f0511af59e124f52ec7be566a6c4789..f67bcfbfdfdd7c6cb0ad0130972f5b1dc4429bcf 100644
--- a/gcc/gimple-iterator.cc
+++ b/gcc/gimple-iterator.cc
@@ -666,10 +666,11 @@ gsi_move_after (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
 
 
 /* Move the statement at FROM so it comes right before the statement
-   at TO.  */
+   at TO using method M.  */
 
 void
-gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
+gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to,
+		 gsi_iterator_update m = GSI_SAME_STMT)
 {
   gimple *stmt = gsi_stmt (*from);
   gsi_remove (from, false);
@@ -677,7 +678,7 @@ gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
   /* For consistency with gsi_move_after, it might be better to have
      GSI_NEW_STMT here; however, that breaks several places that expect
      that TO does not change.  */
-  gsi_insert_before (to, stmt, GSI_SAME_STMT);
+  gsi_insert_before (to, stmt, m);
 }
 
 
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d6db91df97625a7f11609d034e89af0461129b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+char* inet_net_pton_ipv4_bits;
+char inet_net_pton_ipv4_odst;
+void __errno_location();
+void inet_net_pton_ipv4();
+void inet_net_pton() { inet_net_pton_ipv4(); }
+void inet_net_pton_ipv4(char *dst, int size) {
+  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
+    if (size-- <= 0)
+      goto emsgsize;
+    *dst++ = '\0';
+  }
+emsgsize:
+  __errno_location();
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 30b90d99925bea74caf14833d8ab1695607d0fe9..9aba94bd6ca2061a19487ac4a2735a16d03bcbee 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -11800,8 +11800,7 @@ move_early_exit_stmts (loop_vec_info loop_vinfo)
 	dump_printf_loc (MSG_NOTE, vect_location, "moving stmt %G", stmt);
 
       gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
-      gsi_move_before (&stmt_gsi, &dest_gsi);
-      gsi_prev (&dest_gsi);
+      gsi_move_before (&stmt_gsi, &dest_gsi, GSI_NEW_STMT);
     }
 
   /* Update all the stmts with their new reaching VUSES.  */
Richard Biener Feb. 5, 2024, 2:31 p.m. UTC | #4
On Mon, 5 Feb 2024, Tamar Christina wrote:

> > It looks like LOOP_VINFO_EARLY_BRK_STORES is "reverse"?  Is that
> > why you are doing gsi_move_before + gsi_prev?  Why do gsi_prev
> > at all?
> > 
> 
> As discussed on IRC, then how about this one.
> Incremental building passed all tests and bootstrap is running.
> 
> Ok for master if bootstrap and regtesting clean?
> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
> 	PR tree-optimization/113731
> 	* gimple-iterator.cc (gsi_move_before): Take new parameter for update
> 	method.
> 	* gimple-iterator.h (gsi_move_before): Default new param to
> 	GSI_SAME_STMT.
> 	* tree-vect-loop.cc (move_early_exit_stmts): Call gsi_move_before with
> 	GSI_NEW_STMT.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR tree-optimization/113731
> 	* gcc.dg/vect/vect-early-break_111-pr113731.c: New test.
> 
> --- inline copy of patch ---
> 
> diff --git a/gcc/gimple-iterator.cc b/gcc/gimple-iterator.cc
> index 517c53376f0511af59e124f52ec7be566a6c4789..f67bcfbfdfdd7c6cb0ad0130972f5b1dc4429bcf 100644
> --- a/gcc/gimple-iterator.cc
> +++ b/gcc/gimple-iterator.cc
> @@ -666,10 +666,11 @@ gsi_move_after (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
>  
>  
>  /* Move the statement at FROM so it comes right before the statement
> -   at TO.  */
> +   at TO using method M.  */
>  
>  void
> -gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
> +gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to,
> +		 gsi_iterator_update m = GSI_SAME_STMT)

Looks like the wrong patch attached?  This should be like in the
ChangeLog.

OK with that change

Richard.

>  {
>    gimple *stmt = gsi_stmt (*from);
>    gsi_remove (from, false);
> @@ -677,7 +678,7 @@ gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
>    /* For consistency with gsi_move_after, it might be better to have
>       GSI_NEW_STMT here; however, that breaks several places that expect
>       that TO does not change.  */
> -  gsi_insert_before (to, stmt, GSI_SAME_STMT);
> +  gsi_insert_before (to, stmt, m);
>  }
>  
>  
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..2d6db91df97625a7f11609d034e89af0461129b2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
> +
> +char* inet_net_pton_ipv4_bits;
> +char inet_net_pton_ipv4_odst;
> +void __errno_location();
> +void inet_net_pton_ipv4();
> +void inet_net_pton() { inet_net_pton_ipv4(); }
> +void inet_net_pton_ipv4(char *dst, int size) {
> +  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
> +    if (size-- <= 0)
> +      goto emsgsize;
> +    *dst++ = '\0';
> +  }
> +emsgsize:
> +  __errno_location();
> +}
> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index 30b90d99925bea74caf14833d8ab1695607d0fe9..9aba94bd6ca2061a19487ac4a2735a16d03bcbee 100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -11800,8 +11800,7 @@ move_early_exit_stmts (loop_vec_info loop_vinfo)
>  	dump_printf_loc (MSG_NOTE, vect_location, "moving stmt %G", stmt);
>  
>        gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
> -      gsi_move_before (&stmt_gsi, &dest_gsi);
> -      gsi_prev (&dest_gsi);
> +      gsi_move_before (&stmt_gsi, &dest_gsi, GSI_NEW_STMT);
>      }
>  
>    /* Update all the stmts with their new reaching VUSES.  */
>
Jakub Jelinek Feb. 6, 2024, 2:48 p.m. UTC | #5
On Mon, Feb 05, 2024 at 03:31:20PM +0100, Richard Biener wrote:
> On Mon, 5 Feb 2024, Tamar Christina wrote:
> > > It looks like LOOP_VINFO_EARLY_BRK_STORES is "reverse"?  Is that
> > > why you are doing gsi_move_before + gsi_prev?  Why do gsi_prev
> > > at all?
> > > 
> > 
> > As discussed on IRC, then how about this one.
> > Incremental building passed all tests and bootstrap is running.
> > 
> > Ok for master if bootstrap and regtesting clean?
> > 
> > Thanks,
> > Tamar
> > 
> > gcc/ChangeLog:
> > 
> > 	PR tree-optimization/113731
> > 	* gimple-iterator.cc (gsi_move_before): Take new parameter for update
> > 	method.
> > 	* gimple-iterator.h (gsi_move_before): Default new param to
> > 	GSI_SAME_STMT.
> > 	* tree-vect-loop.cc (move_early_exit_stmts): Call gsi_move_before with
> > 	GSI_NEW_STMT.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > 	PR tree-optimization/113731
> > 	* gcc.dg/vect/vect-early-break_111-pr113731.c: New test.

So like following (Tobias asked for it on IRC)?
Seems it FAILs for me on x86_64-linux unless using -msse4.2 (or -msse4),
dg-add-options vect_early_break adds just -msse4.1.
I believe the difference is in presence/absence of the PCMPGTQ instruction,
the loop is comparing pointers (other than equality comparison) and so needs
it, while in SSE4.1 one only has PCMPGT{B,W,D}, so it can > compare 16-byte
vectors with 8-bit, 16-bit or 32-bit elements.

Shall we add
/* { dg-additional-options "-msse4.2" { target i?86-*-* x86_64-*-* } } */
to the testcase?

--- gcc/gimple-iterator.h.jj	2024-01-03 11:51:33.090709553 +0100
+++ gcc/gimple-iterator.h	2024-02-06 15:23:40.732532207 +0100
@@ -86,7 +86,8 @@ extern gimple_stmt_iterator gsi_for_stmt
 extern gimple_stmt_iterator gsi_for_stmt (gimple *, gimple_seq *);
 extern gphi_iterator gsi_for_phi (gphi *);
 extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
-extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
+extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *,
+			     gsi_iterator_update = GSI_SAME_STMT);
 extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
 extern void gsi_insert_on_edge (edge, gimple *);
 extern void gsi_insert_seq_on_edge (edge, gimple_seq);
--- gcc/gimple-iterator.cc.jj	2024-01-03 11:51:42.016585669 +0100
+++ gcc/gimple-iterator.cc	2024-02-06 15:23:12.274926647 +0100
@@ -666,10 +666,11 @@ gsi_move_after (gimple_stmt_iterator *fr
 
 
 /* Move the statement at FROM so it comes right before the statement
-   at TO.  */
+   at TO using method M.  */
 
 void
-gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
+gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to,
+		 gsi_iterator_update m)
 {
   gimple *stmt = gsi_stmt (*from);
   gsi_remove (from, false);
@@ -677,7 +678,7 @@ gsi_move_before (gimple_stmt_iterator *f
   /* For consistency with gsi_move_after, it might be better to have
      GSI_NEW_STMT here; however, that breaks several places that expect
      that TO does not change.  */
-  gsi_insert_before (to, stmt, GSI_SAME_STMT);
+  gsi_insert_before (to, stmt, m);
 }
 
 
--- gcc/tree-vect-loop.cc.jj	2024-01-25 09:06:34.116831262 +0100
+++ gcc/tree-vect-loop.cc	2024-02-06 15:22:49.268245536 +0100
@@ -11800,8 +11800,7 @@ move_early_exit_stmts (loop_vec_info loo
 	dump_printf_loc (MSG_NOTE, vect_location, "moving stmt %G", stmt);
 
       gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
-      gsi_move_before (&stmt_gsi, &dest_gsi);
-      gsi_prev (&dest_gsi);
+      gsi_move_before (&stmt_gsi, &dest_gsi, GSI_NEW_STMT);
     }
 
   /* Update all the stmts with their new reaching VUSES.  */
--- gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c.jj	2024-02-06 15:22:49.248245813 +0100
+++ gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c	2024-02-06 15:22:49.248245813 +0100
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+char* inet_net_pton_ipv4_bits;
+char inet_net_pton_ipv4_odst;
+void __errno_location();
+void inet_net_pton_ipv4();
+void inet_net_pton() { inet_net_pton_ipv4(); }
+void inet_net_pton_ipv4(char *dst, int size) {
+  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
+    if (size-- <= 0)
+      goto emsgsize;
+    *dst++ = '\0';
+  }
+emsgsize:
+  __errno_location();
+}


	Jakub
Richard Biener Feb. 6, 2024, 3:04 p.m. UTC | #6
On Tue, 6 Feb 2024, Jakub Jelinek wrote:

> On Mon, Feb 05, 2024 at 03:31:20PM +0100, Richard Biener wrote:
> > On Mon, 5 Feb 2024, Tamar Christina wrote:
> > > > It looks like LOOP_VINFO_EARLY_BRK_STORES is "reverse"?  Is that
> > > > why you are doing gsi_move_before + gsi_prev?  Why do gsi_prev
> > > > at all?
> > > > 
> > > 
> > > As discussed on IRC, then how about this one.
> > > Incremental building passed all tests and bootstrap is running.
> > > 
> > > Ok for master if bootstrap and regtesting clean?
> > > 
> > > Thanks,
> > > Tamar
> > > 
> > > gcc/ChangeLog:
> > > 
> > > 	PR tree-optimization/113731
> > > 	* gimple-iterator.cc (gsi_move_before): Take new parameter for update
> > > 	method.
> > > 	* gimple-iterator.h (gsi_move_before): Default new param to
> > > 	GSI_SAME_STMT.
> > > 	* tree-vect-loop.cc (move_early_exit_stmts): Call gsi_move_before with
> > > 	GSI_NEW_STMT.
> > > 
> > > gcc/testsuite/ChangeLog:
> > > 
> > > 	PR tree-optimization/113731
> > > 	* gcc.dg/vect/vect-early-break_111-pr113731.c: New test.
> 
> So like following (Tobias asked for it on IRC)?
> Seems it FAILs for me on x86_64-linux unless using -msse4.2 (or -msse4),
> dg-add-options vect_early_break adds just -msse4.1.
> I believe the difference is in presence/absence of the PCMPGTQ instruction,
> the loop is comparing pointers (other than equality comparison) and so needs
> it, while in SSE4.1 one only has PCMPGT{B,W,D}, so it can > compare 16-byte
> vectors with 8-bit, 16-bit or 32-bit elements.
> 
> Shall we add
> /* { dg-additional-options "-msse4.2" { target i?86-*-* x86_64-*-* } } */
> to the testcase?

or add vect_long and/or vect_early_break_long?

> --- gcc/gimple-iterator.h.jj	2024-01-03 11:51:33.090709553 +0100
> +++ gcc/gimple-iterator.h	2024-02-06 15:23:40.732532207 +0100
> @@ -86,7 +86,8 @@ extern gimple_stmt_iterator gsi_for_stmt
>  extern gimple_stmt_iterator gsi_for_stmt (gimple *, gimple_seq *);
>  extern gphi_iterator gsi_for_phi (gphi *);
>  extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
> -extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
> +extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *,
> +			     gsi_iterator_update = GSI_SAME_STMT);
>  extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
>  extern void gsi_insert_on_edge (edge, gimple *);
>  extern void gsi_insert_seq_on_edge (edge, gimple_seq);
> --- gcc/gimple-iterator.cc.jj	2024-01-03 11:51:42.016585669 +0100
> +++ gcc/gimple-iterator.cc	2024-02-06 15:23:12.274926647 +0100
> @@ -666,10 +666,11 @@ gsi_move_after (gimple_stmt_iterator *fr
>  
>  
>  /* Move the statement at FROM so it comes right before the statement
> -   at TO.  */
> +   at TO using method M.  */
>  
>  void
> -gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
> +gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to,
> +		 gsi_iterator_update m)
>  {
>    gimple *stmt = gsi_stmt (*from);
>    gsi_remove (from, false);
> @@ -677,7 +678,7 @@ gsi_move_before (gimple_stmt_iterator *f
>    /* For consistency with gsi_move_after, it might be better to have
>       GSI_NEW_STMT here; however, that breaks several places that expect
>       that TO does not change.  */
> -  gsi_insert_before (to, stmt, GSI_SAME_STMT);
> +  gsi_insert_before (to, stmt, m);
>  }
>  
>  
> --- gcc/tree-vect-loop.cc.jj	2024-01-25 09:06:34.116831262 +0100
> +++ gcc/tree-vect-loop.cc	2024-02-06 15:22:49.268245536 +0100
> @@ -11800,8 +11800,7 @@ move_early_exit_stmts (loop_vec_info loo
>  	dump_printf_loc (MSG_NOTE, vect_location, "moving stmt %G", stmt);
>  
>        gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
> -      gsi_move_before (&stmt_gsi, &dest_gsi);
> -      gsi_prev (&dest_gsi);
> +      gsi_move_before (&stmt_gsi, &dest_gsi, GSI_NEW_STMT);
>      }
>  
>    /* Update all the stmts with their new reaching VUSES.  */
> --- gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c.jj	2024-02-06 15:22:49.248245813 +0100
> +++ gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c	2024-02-06 15:22:49.248245813 +0100
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
> +
> +char* inet_net_pton_ipv4_bits;
> +char inet_net_pton_ipv4_odst;
> +void __errno_location();
> +void inet_net_pton_ipv4();
> +void inet_net_pton() { inet_net_pton_ipv4(); }
> +void inet_net_pton_ipv4(char *dst, int size) {
> +  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
> +    if (size-- <= 0)
> +      goto emsgsize;
> +    *dst++ = '\0';
> +  }
> +emsgsize:
> +  __errno_location();
> +}
> 
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+char* inet_net_pton_ipv4_bits;
+char inet_net_pton_ipv4_odst;
+void __errno_location();
+void inet_net_pton_ipv4();
+void inet_net_pton() { inet_net_pton_ipv4(); }
+void inet_net_pton_ipv4(char *dst, int size) {
+  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
+    if (size-- <= 0)
+      goto emsgsize;
+    *dst++ = '\0';
+  }
+emsgsize:
+  __errno_location();
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 30b90d99925bea74caf14833d8ab1695607d0fe9..e2587315020a35a7d4ebd3e7a9842caa36bb5d3c 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -11801,7 +11801,8 @@  move_early_exit_stmts (loop_vec_info loop_vinfo)
 
       gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
       gsi_move_before (&stmt_gsi, &dest_gsi);
-      gsi_prev (&dest_gsi);
+      if (!gsi_end_p (dest_gsi))
+	gsi_prev (&dest_gsi);
     }
 
   /* Update all the stmts with their new reaching VUSES.  */