diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2020-12-16 09:39:07 +0100 |
---|---|---|
committer | Eric Botcazou <ebotcazou@adacore.com> | 2020-12-16 09:41:47 +0100 |
commit | 61e3c180ad6913fa5af39059de5ba7b3bde50cda (patch) | |
tree | 7f04e65fce1b54282a2c8160d02ebaa2951cb60e /gcc | |
parent | 31008a8bb30d8979bba5240be6b504140c5665ff (diff) | |
download | gcc-61e3c180ad6913fa5af39059de5ba7b3bde50cda.zip gcc-61e3c180ad6913fa5af39059de5ba7b3bde50cda.tar.gz gcc-61e3c180ad6913fa5af39059de5ba7b3bde50cda.tar.bz2 |
Fix PR tree-optimization/98272
This fixes the precision mismatch introduced by the previous change.
gcc/ChangeLog:
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.
gcc/testsuite/ChangeLog:
* gcc.dg/pr98272.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/pr98272.c | 22 | ||||
-rw-r--r-- | gcc/tree-switch-conversion.c | 13 |
2 files changed, 29 insertions, 6 deletions
diff --git a/gcc/testsuite/gcc.dg/pr98272.c b/gcc/testsuite/gcc.dg/pr98272.c new file mode 100644 index 0000000..126a616 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr98272.c @@ -0,0 +1,22 @@ +/* PR tree-optimization/98272 */ +/* Reported by Zdenek Sojka <zsojka@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 (); + } +} diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 989bd77..08dfd6f 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 |