aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/fold-const.c19
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr83269.c14
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;
+}