https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112509

--- Comment #2 from Andrew Macleod <amacleod at redhat dot com> ---
the original switch is an unsigned value with precision of 3 bits, so 0..7 just
fits.

It gets translated to an int index during gimplification, but the case labels
are still precision 3 values. 

find_case_label_ranges in tree-vrp.cc does the following:

     tree label = gimple_switch_label (switch_stmt, i);
      tree case_high
        = CASE_HIGH (label) ? CASE_HIGH (label) : CASE_LOW (label);
      wide_int wlow = wi::to_wide (CASE_LOW (label));
      wide_int whigh = wi::to_wide (case_high);
      int_range_max label_range (type,
                                 wide_int::from (wlow, prec, sign),
                                 wide_int::from (whigh, prec, sign));

 CASE_HIGH is indeed 6, but when we to the to_wide call, it is sign extended to
produce:
(gdb) p whigh.dump ()
[0xfffffffffffffffe], precision = 3

but then when we do wide_int::from() in the signed int precision 32 of the new
switch type, we get -2 for the high value.

Whats suppose to happen here?  seems odd to me that the case labels are a
different precision than the switch itself..  but then we would also lose the
fact that there is only 3 bits of precision in the switch.

Should the low and high values be cast from the original case precision/type to
the new perhaps?

something like this seems to work:
 tree
 find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
@@ -900,9 +901,9 @@ find_case_label_range (gswitch *switch_stmt, const irange
*range_of_op)
        = CASE_HIGH (label) ? CASE_HIGH (label) : CASE_LOW (label);
       wide_int wlow = wi::to_wide (CASE_LOW (label));
       wide_int whigh = wi::to_wide (case_high);
-      int_range_max label_range (type,
-                                wide_int::from (wlow, prec, sign),
-                                wide_int::from (whigh, prec, sign));
+      int_range_max label_range (TREE_TYPE (case_high), wlow, whigh);
+      range_cast (label_range, type);
+      label_range.dump(stderr);

Reply via email to