public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/loop-unswitch-support-switches] Avoid ICE when removing a case sharing the edge with the default case
@ 2022-05-18 12:23 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2022-05-18 12:23 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ef6f1e135618a39ea456416093575b68ea5fc28e

commit ef6f1e135618a39ea456416093575b68ea5fc28e
Author: Richard Biener <rguenther@suse.de>
Date:   Wed May 18 09:18:24 2022 +0200

    Avoid ICE when removing a case sharing the edge with the default case

Diff:
---
 gcc/testsuite/gcc.dg/torture/20220518-1.c | 39 +++++++++++++++++++++++++++++++
 gcc/tree-ssa-loop-unswitch.cc             | 15 +++++++++---
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/20220518-1.c b/gcc/testsuite/gcc.dg/torture/20220518-1.c
new file mode 100644
index 00000000000..1822aee6151
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/20220518-1.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-funswitch-loops" } */
+
+enum {
+  MOD_WVG_MASK_TEX_USE_INT,
+  MOD_WVG_MASK_TEX_USE_RED,
+  MOD_WVG_MASK_TEX_USE_BLUE,
+  MOD_WVG_MASK_TEX_USE_SAT,
+  MOD_WVG_MASK_TEX_USE_VAL,
+  MOD_WVG_MASK_TEX_USE_ALPHA
+} foo_num;
+float *foo_org_w;
+int *foo_new_w;
+float foo_fact;
+int foo_tex_use_channel, foo_i, foo_texres_0;
+void foo()
+{
+  for (; foo_num;)
+    switch (foo_tex_use_channel) {
+    case MOD_WVG_MASK_TEX_USE_INT:
+      foo_org_w[foo_i] = foo_new_w[foo_i] * foo_texres_0;
+      break;
+    case MOD_WVG_MASK_TEX_USE_RED:
+      foo_org_w[foo_i] = 0;
+    case MOD_WVG_MASK_TEX_USE_BLUE:
+      foo_org_w[foo_i] = foo_fact + foo_org_w[foo_i];
+      break;
+    case MOD_WVG_MASK_TEX_USE_SAT:
+      foo_org_w[foo_i] = foo_fact;
+      break;
+    case MOD_WVG_MASK_TEX_USE_VAL:
+      foo_org_w[foo_i] = 0;
+    case MOD_WVG_MASK_TEX_USE_ALPHA:
+      foo_org_w[foo_i] = foo_fact + foo_org_w[foo_i];
+      break;
+    default:
+      foo_org_w[foo_i] = foo_new_w[foo_i] * foo_texres_0;
+    }
+}
diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
index b245885d91d..0e8baded8b9 100644
--- a/gcc/tree-ssa-loop-unswitch.cc
+++ b/gcc/tree-ssa-loop-unswitch.cc
@@ -1523,11 +1523,14 @@ clean_up_after_unswitching (int ignored_edge_flag)
 
   FOR_EACH_BB_FN (bb, cfun)
     {
-      gimple *last = last_stmt (bb);
-      if (gswitch *stmt = safe_dyn_cast <gswitch *> (last))
+      gswitch *stmt= safe_dyn_cast <gswitch *> (last_stmt (bb));
+      if (stmt && !CONSTANT_CLASS_P (gimple_switch_index (stmt)))
 	{
 	  unsigned nlabels = gimple_switch_num_labels (stmt);
 	  unsigned index = 1;
+	  tree lab = gimple_switch_default_label (stmt);
+	  edge default_e = find_edge (gimple_bb (stmt),
+				      label_to_block (cfun, CASE_LABEL (lab)));
 	  for (unsigned i = 1; i < nlabels; ++i)
 	    {
 	      tree lab = gimple_switch_label (stmt, i);
@@ -1536,7 +1539,13 @@ clean_up_after_unswitching (int ignored_edge_flag)
 	      if (e == NULL)
 		; /* The edge is already removed.  */
 	      else if (e->flags & ignored_edge_flag)
-		remove_edge (e);
+		{
+		  /* We may not remove the default label so we also have
+		     to preserve its edge.  But we can remove the
+		     non-default CASE sharing the edge.  */
+		  if (e != default_e)
+		    remove_edge (e);
+		}
 	      else
 		{
 		  gimple_switch_set_label (stmt, index, lab);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-18 12:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-18 12:23 [gcc/devel/loop-unswitch-support-switches] Avoid ICE when removing a case sharing the edge with the default case 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).