> OK.

Thanks.  Unfortunately I overlooked the comment of the function:

    MINVAL is the lowest case value of in the case nodes,
    and RANGE is highest value minus MINVAL.  MINVAL and RANGE
    are not guaranteed to be of the same type as INDEX_EXPR
    (the gimplifier doesn't change the type of case label values,
    and MINVAL and RANGE are derived from those values).

so PR tree-optimization/98272 exhibits a precision mismatch now.

Bootstrapped/regtested on x86-64/Linux, OK for the mainline?


2020-12-15  Eric Botcazou  <ebotca...@adacore.com>

        PR tree-optimization/98272
        * tree-switch-conversion.c (bit_test_cluster::emit): When finding
        out whether the entry test can be merged in the bit test, do the
        computation using the type of the index expression.


2020-12-15  Eric Botcazou  <ebotca...@adacore.com>

        * gcc.dg/pr98272.c: New test.

-- 
Eric Botcazou
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 989bd7710d1..08dfd6f3580 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -1557,21 +1557,22 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
       && get_range_info (index_expr, &min, &max) == VR_RANGE
       && wi::leu_p (max - min, prec - 1))
     {
+      tree index_type = TREE_TYPE (index_expr);
+      minval = fold_convert (index_type, minval);
       wide_int iminval = wi::to_wide (minval);
-      tree minval_type = TREE_TYPE (minval);
-      if (wi::lt_p (min, iminval, TYPE_SIGN (minval_type)))
+      if (wi::lt_p (min, iminval, TYPE_SIGN (index_type)))
 	{
-	  minval = wide_int_to_tree (minval_type, min);
+	  minval = wide_int_to_tree (index_type, min);
 	  for (i = 0; i < count; i++)
 	    test[i].mask = wi::lshift (test[i].mask, iminval - min);
 	}
-      else if (wi::gt_p (min, iminval, TYPE_SIGN (minval_type)))
+      else if (wi::gt_p (min, iminval, TYPE_SIGN (index_type)))
 	{
-	  minval = wide_int_to_tree (minval_type, min);
+	  minval = wide_int_to_tree (index_type, min);
 	  for (i = 0; i < count; i++)
 	    test[i].mask = wi::lrshift (test[i].mask, min - iminval);
 	}
-      maxval = wide_int_to_tree (minval_type, max);
+      maxval = wide_int_to_tree (index_type, max);
       entry_test_needed = false;
     }
   else
/* PR tree-optimization/98272 */
/* Reported by Zdenek Sojka <zso...@seznam.cz> */

/* { dg-do compile } */
/* { dg-options "-O -fno-tree-forwprop" } */

void bar (void);

void
foo (unsigned char uc)
{
  if (uc >= 5)
    return;

  switch (uc)
    {
    case 0:
    case 2:
    case 4:
      bar ();
    }
}

Reply via email to