re PR target/70941 (Test miscompiled with -O2.)
authorRichard Biener <rguenther@suse.de>
Fri, 6 May 2016 07:38:27 +0000 (07:38 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 6 May 2016 07:38:27 +0000 (07:38 +0000)
2016-05-06  Richard Biener  <rguenther@suse.de>

PR middle-end/70941
* fold-const.c (split_tree): Always convert to the original type
before negating.

* gcc.dg/torture/pr70941.c: New testcase.

From-SVN: r235943

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr70941.c [new file with mode: 0644]

index 5c5424787209a77494cb75b9336b7335698418c2..e8f7c8f8e0e4a34bfebca13b731b618737fc65c3 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-06  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70941
+       * fold-const.c (split_tree): Always convert to the original type
+       before negating.
+
 2016-05-06  Richard Biener  <rguenther@suse.de>
 
        * fwprop.c (fwprop): Remove duplicate cleanup_cfg call.
index 9ef43bf22590a0ce3b225dcaf304a4e68ece7eaf..8aabe2155fa6962e6b256d8805bc50dda6cb0942 100644 (file)
@@ -836,11 +836,10 @@ split_tree (location_t loc, tree in, tree type, enum tree_code code,
        *minus_litp = *litp, *litp = 0;
       if (neg_conp_p)
        *conp = negate_expr (*conp);
-      if (neg_var_p)
+      if (neg_var_p && var)
        {
-         /* Convert to TYPE before negating a pointer type expr.  */
-         if (var && POINTER_TYPE_P (TREE_TYPE (var)))
-           var = fold_convert_loc (loc, type, var);
+         /* Convert to TYPE before negating.  */
+         var = fold_convert_loc (loc, type, var);
          var = negate_expr (var);
        }
     }
@@ -863,10 +862,12 @@ split_tree (location_t loc, tree in, tree type, enum tree_code code,
       else if (*minus_litp)
        *litp = *minus_litp, *minus_litp = 0;
       *conp = negate_expr (*conp);
-      /* Convert to TYPE before negating a pointer type expr.  */
-      if (var && POINTER_TYPE_P (TREE_TYPE (var)))
-       var = fold_convert_loc (loc, type, var);
-      var = negate_expr (var);
+      if (var)
+       {
+         /* Convert to TYPE before negating.  */
+         var = fold_convert_loc (loc, type, var);
+         var = negate_expr (var);
+       }
     }
 
   return var;
index 9ec6eb7c322015fa75e5bb035abb1d13980600f0..d5b2df98e38714c8096bd7f75aa1ebe574f9c18e 100644 (file)
@@ -1,3 +1,8 @@
+2016-05-06  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70941
+       * gcc.dg/torture/pr70941.c: New testcase.
+
 2016-05-05  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/57206
diff --git a/gcc/testsuite/gcc.dg/torture/pr70941.c b/gcc/testsuite/gcc.dg/torture/pr70941.c
new file mode 100644 (file)
index 0000000..3a57081
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+extern void abort (void);
+
+char a = 0, b = 0, c = 0, d = 0;
+
+int main()
+{
+  a = -(b - 405418259) - ((d && c) ^ 2040097152);
+  if (a != -109)
+    abort();
+  return 0;
+}