aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2024-11-02 10:26:24 -0400
committerAndrew MacLeod <amacleod@redhat.com>2024-11-04 09:58:03 -0500
commit766075c47db5cc9d04463bfb2219b593bb4263ee (patch)
tree14dc570b5d6444ca5274d778b26cbd79282cede9
parent8762bb1b004c442b8dbb22a6d9eb0b7da4a3e59f (diff)
downloadgcc-766075c47db5cc9d04463bfb2219b593bb4263ee.zip
gcc-766075c47db5cc9d04463bfb2219b593bb4263ee.tar.gz
gcc-766075c47db5cc9d04463bfb2219b593bb4263ee.tar.bz2
Don't call invert on VARYING.
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.
-rw-r--r--gcc/gimple-range-edge.cc10
-rw-r--r--gcc/testsuite/gcc.dg/pr117398.c17
2 files changed, 25 insertions, 2 deletions
diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
index e3a197a..d238728 100644
--- a/gcc/gimple-range-edge.cc
+++ b/gcc/gimple-range-edge.cc
@@ -159,8 +159,14 @@ gimple_outgoing_range::calc_switch_ranges (gswitch *sw)
// Remove the case range from the default case.
int_range_max def_range (type, 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 (type, low, high);
diff --git a/gcc/testsuite/gcc.dg/pr117398.c b/gcc/testsuite/gcc.dg/pr117398.c
new file mode 100644
index 0000000..c43f2a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr117398.c
@@ -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;
+}