aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-04-07 08:20:24 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-04-07 08:20:24 +0000
commit2d143ba8cfef7ef480c639882fd5518b7afd822b (patch)
tree88b5a716645aa02574e38f724825464aecb22de9 /gcc/tree.c
parent5291ab733b6584b2b0252178625088812f66e689 (diff)
downloadgcc-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.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index c87b769..c18889c 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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;
}