aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-12-15 15:37:52 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-12-15 15:37:52 +0100
commite7425c18b5af5a12f68bde8b5f30adf02a774536 (patch)
tree244e650451af7f181109c73ce6cd80058234b774 /gcc/fold-const.c
parenta72610d4320925787d635cb4ddb8a40967e05bc3 (diff)
downloadgcc-e7425c18b5af5a12f68bde8b5f30adf02a774536.zip
gcc-e7425c18b5af5a12f68bde8b5f30adf02a774536.tar.gz
gcc-e7425c18b5af5a12f68bde8b5f30adf02a774536.tar.bz2
re PR tree-optimization/83269 (Wrong constant folding)
PR tree-optimization/83269 * fold-const.c (fold_binary_loc): Perform (-A) - B -> (-B) - A subtraction in arg0's type if type is signed and arg0 is unsigned. Formatting fix. * gcc.c-torture/execute/pr83269.c: New test. From-SVN: r255697
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0f11076..9fc69e8 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -9098,8 +9098,8 @@ expr_not_equal_to (tree t, const wide_int &w)
return NULL_TREE. */
tree
-fold_binary_loc (location_t loc,
- enum tree_code code, tree type, tree op0, tree op1)
+fold_binary_loc (location_t loc, enum tree_code code, tree type,
+ tree op0, tree op1)
{
enum tree_code_class kind = TREE_CODE_CLASS (code);
tree arg0, arg1, tem;
@@ -9769,10 +9769,17 @@ fold_binary_loc (location_t loc,
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR
- && negate_expr_p (op1))
- return fold_build2_loc (loc, MINUS_EXPR, type,
- negate_expr (op1),
- fold_convert_loc (loc, type,
+ && negate_expr_p (op1)
+ /* If arg0 is e.g. unsigned int and type is int, then this could
+ introduce UB, because if A is INT_MIN at runtime, the original
+ expression can be well defined while the latter is not.
+ See PR83269. */
+ && !(ANY_INTEGRAL_TYPE_P (type)
+ && TYPE_OVERFLOW_UNDEFINED (type)
+ && ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))))
+ return fold_build2_loc (loc, MINUS_EXPR, type, negate_expr (op1),
+ fold_convert_loc (loc, type,
TREE_OPERAND (arg0, 0)));
/* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to