diff options
author | Richard Biener <rguenther@suse.de> | 2017-04-07 08:20:24 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-04-07 08:20:24 +0000 |
commit | 2d143ba8cfef7ef480c639882fd5518b7afd822b (patch) | |
tree | 88b5a716645aa02574e38f724825464aecb22de9 /gcc/tree.c | |
parent | 5291ab733b6584b2b0252178625088812f66e689 (diff) | |
download | gcc-2d143ba8cfef7ef480c639882fd5518b7afd822b.zip gcc-2d143ba8cfef7ef480c639882fd5518b7afd822b.tar.gz gcc-2d143ba8cfef7ef480c639882fd5518b7afd822b.tar.bz2 |
re PR middle-end/80341 (gcc miscompiles division of signed char)
2017-04-07 Richard Biener <rguenther@suse.de>
PR middle-end/80341
* tree.c (get_unwidened): Also handle ! for_type case for
INTEGER_CSTs.
* convert.c (do_narrow): Split out from ...
(convert_to_integer_1): ... here. Do not pass final truncation
type to get_unwidened for TRUNC_DIV_EXPR.
* gcc.dg/torture/pr80341.c: New testcase.
From-SVN: r246756
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 20 |
1 files changed, 14 insertions, 6 deletions
@@ -9033,13 +9033,21 @@ get_unwidened (tree op, tree for_type) } } - /* If we finally reach a constant see if it fits in for_type and + /* If we finally reach a constant see if it fits in sth smaller and in that case convert it. */ - if (for_type - && TREE_CODE (win) == INTEGER_CST - && TREE_TYPE (win) != for_type - && int_fits_type_p (win, for_type)) - win = fold_convert (for_type, win); + if (TREE_CODE (win) == INTEGER_CST) + { + tree wtype = TREE_TYPE (win); + unsigned prec = wi::min_precision (win, TYPE_SIGN (wtype)); + if (for_type) + prec = MAX (prec, final_prec); + if (prec < TYPE_PRECISION (wtype)) + { + tree t = lang_hooks.types.type_for_size (prec, TYPE_UNSIGNED (wtype)); + if (t && TYPE_PRECISION (t) < TYPE_PRECISION (wtype)) + win = fold_convert (t, win); + } + } return win; } |