summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-02-08 16:06:26 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-02-08 16:06:26 +0100
commit600a5961b24faccf68ef5287fb3a6ed3c6b79224 (patch)
tree3bef1543331fe45a7c674d160d1cafa5e1587232 /gcc/fold-const.c
parentbe59c9322ac42053f9a752fd0748513f27cc1c96 (diff)
downloadgcc-600a5961b24faccf68ef5287fb3a6ed3c6b79224.tar.gz
re PR tree-optimization/56250 (Wrong constant folding on unsigned int)
PR tree-optimization/56250 * fold-const.c (extract_muldiv_1) <case NEGATE_EXPR>: Don't optimize if type is unsigned and code isn't MULT_EXPR. * gcc.c-torture/execute/pr56250.c: New test. From-SVN: r195888
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 93f38cbbf21..5acb4ad0059 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5695,6 +5695,11 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
break;
/* FALLTHROUGH */
case NEGATE_EXPR:
+ /* For division and modulus, type can't be unsigned, as e.g.
+ (-(x / 2U)) / 2U isn't equal to -((x / 2U) / 2U) for x >= 2.
+ For signed types, even with wrapping overflow, this is fine. */
+ if (code != MULT_EXPR && TYPE_UNSIGNED (type))
+ break;
if ((t1 = extract_muldiv (op0, c, code, wide_type, strict_overflow_p))
!= 0)
return fold_build1 (tcode, ctype, fold_convert (ctype, t1));