diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-12-15 15:37:52 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-12-15 15:37:52 +0100 |
commit | e7425c18b5af5a12f68bde8b5f30adf02a774536 (patch) | |
tree | 244e650451af7f181109c73ce6cd80058234b774 /gcc | |
parent | a72610d4320925787d635cb4ddb8a40967e05bc3 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/fold-const.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr83269.c | 14 |
4 files changed, 35 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d655ac..60f621d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2017-12-15 Jakub Jelinek <jakub@redhat.com> + 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. + PR sanitizer/81281 * match.pd ((T)(P + A) - (T)P -> (T) A): Use @@0 instead of @0 and convert? on @0 instead of convert. Check type of @1, not @0. 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e119691..c87d2cd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-12-15 Jakub Jelinek <jakub@redhat.com> + PR tree-optimization/83269 + * gcc.c-torture/execute/pr83269.c: New test. + PR sanitizer/81281 * gcc.dg/pr81281-3.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr83269.c b/gcc/testsuite/gcc.c-torture/execute/pr83269.c new file mode 100644 index 0000000..37fc5d1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr83269.c @@ -0,0 +1,14 @@ +/* PR tree-optimization/83269 */ + +int +main () +{ +#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ > 4 && __CHAR_BIT__ == 8 + volatile unsigned char a = 1; + long long b = 0x80000000L; + int c = -((int)(-b) - (-0x7fffffff * a)); + if (c != 1) + __builtin_abort (); +#endif + return 0; +} |