]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Don't call invert on VARYING.
authorAndrew MacLeod <amacleod@redhat.com>
Mon, 4 Nov 2024 15:02:35 +0000 (10:02 -0500)
committerAndrew MacLeod <amacleod@redhat.com>
Mon, 4 Nov 2024 19:46:31 +0000 (14:46 -0500)
When all cases go to one label and resul in a VARYING value, we can't
invert that value to remove all values from the default case. Simply
check for this case and set the default to UNDEFINED.

PR tree-optimization/117398
gcc/
* gimple-range-edge.cc (gimple_outgoing_range::calc_switch_ranges):
Check for VARYING and don't call invert () on it.

gcc/testsuite/
* gcc.dg/pr117398.c: New.

gcc/gimple-range-edge.cc
gcc/testsuite/gcc.dg/pr117398.c [new file with mode: 0644]

index 6caa07c8f02ec17ea9c0aaf3b1e2ce3b47a9f037..a0cc1383a88a9bcb1dc411c42e2a010b88947292 100644 (file)
@@ -145,8 +145,14 @@ gimple_outgoing_range::calc_switch_ranges (gswitch *sw)
       // Remove the case range from the default case.
       int_range_max def_range (low, high);
       range_cast (def_range, type);
-      def_range.invert ();
-      default_range.intersect (def_range);
+      // If all possible values are taken, set default_range to UNDEFINED.
+      if (def_range.varying_p ())
+       default_range.set_undefined ();
+      else
+       {
+         def_range.invert ();
+         default_range.intersect (def_range);
+       }
 
       // Create/union this case with anything on else on the edge.
       int_range_max case_range (low, high);
diff --git a/gcc/testsuite/gcc.dg/pr117398.c b/gcc/testsuite/gcc.dg/pr117398.c
new file mode 100644 (file)
index 0000000..c43f2a3
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int a;
+void c(void);
+int d(_Bool b) {
+  switch (b+0) {
+  case 0:
+    break;
+  case 1:
+    break;
+  default:
+    c();
+  }
+  if (b)
+    return a;
+}