This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR80281
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 3 Apr 2017 13:48:17 +0200 (CEST)
- Subject: [PATCH] Fix PR80281
- Authentication-results: sourceware.org; auth=none
The following fixes PR80281.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Richard.
2017-04-03 Richard Biener <rguenther@suse.de>
PR middle-end/80281
* match.pd (A + (-B) -> A - B): Make sure to preserve unsigned
arithmetic done for the negate or the plus.
* fold-const.c (split_tree): Make sure to not negate pointers.
* gcc.dg/torture/pr80281.c: New testcase.
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 246642)
+++ gcc/match.pd (working copy)
@@ -1153,7 +1153,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (tree_nop_conversion_p (type, TREE_TYPE (@0))
&& tree_nop_conversion_p (type, TREE_TYPE (@1))
&& !TYPE_OVERFLOW_SANITIZED (type))
- (minus (convert @0) (convert @1))))
+ (with
+ {
+ tree t1 = type;
+ if (INTEGRAL_TYPE_P (type)
+ && TYPE_OVERFLOW_WRAPS (type) != TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
+ t1 = TYPE_OVERFLOW_WRAPS (type) ? type : TREE_TYPE (@1);
+ }
+ (convert (minus (convert:t1 @0) (convert:t1 @1))))))
/* A - (-B) -> A + B */
(simplify
(minus (convert1? @0) (convert2? (negate @1)))
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c (revision 246642)
+++ gcc/fold-const.c (working copy)
@@ -831,8 +831,12 @@ split_tree (location_t loc, tree in, tre
/* Now do any needed negations. */
if (neg_litp_p)
*minus_litp = *litp, *litp = 0;
- if (neg_conp_p)
- *conp = negate_expr (*conp);
+ if (neg_conp_p && *conp)
+ {
+ /* Convert to TYPE before negating. */
+ *conp = fold_convert_loc (loc, type, *conp);
+ *conp = negate_expr (*conp);
+ }
if (neg_var_p && var)
{
/* Convert to TYPE before negating. */
@@ -859,7 +863,12 @@ split_tree (location_t loc, tree in, tre
*minus_litp = *litp, *litp = 0;
else if (*minus_litp)
*litp = *minus_litp, *minus_litp = 0;
- *conp = negate_expr (*conp);
+ if (*conp)
+ {
+ /* Convert to TYPE before negating. */
+ *conp = fold_convert_loc (loc, type, *conp);
+ *conp = negate_expr (*conp);
+ }
if (var)
{
/* Convert to TYPE before negating. */
Index: gcc/testsuite/gcc.dg/torture/pr80281.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr80281.c (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr80281.c (working copy)
@@ -0,0 +1,14 @@
+/* { dg-run } */
+/* { dg-require-effective-target int32plus } */
+
+int
+main ()
+{
+ volatile int a = 0;
+ long long b = 2147483648LL;
+ int c = a % 2;
+ int x = ((int) -b + c) % -2147483647;
+ if (x != -1)
+ __builtin_abort ();
+ return 0;
+}