]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/58564 (possible wrong code bug at -O0)
authorJakub Jelinek <jakub@redhat.com>
Mon, 30 Sep 2013 20:15:20 +0000 (22:15 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 30 Sep 2013 20:15:20 +0000 (22:15 +0200)
PR middle-end/58564
* fold-const.c (fold_ternary_loc): For A < 0 : <sign bit of A> : 0
optimization, punt if sign_bit_p looked through any zero extension.

* gcc.c-torture/execute/pr58564.c: New test.

From-SVN: r203042

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

index ee3e01e8f93baf63b2251227e2a9ca7554e8eac2..29c8d6b2f13daa9a3df2bf30ac361c8208a62a1d 100644 (file)
@@ -1,3 +1,9 @@
+2013-09-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/58564
+       * fold-const.c (fold_ternary_loc): For A < 0 : <sign bit of A> : 0
+       optimization, punt if sign_bit_p looked through any zero extension.
+
 2013-09-30  Teresa Johnson  <tejohnson@google.com>
 
        * tree-ssa-threadupdate.c (ssa_fix_duplicate_block_edges):
index 72a43e04a44d845ae58404652077b57fcd5047a9..f68fd8b15d5a88fa4cf2bf38200966662b041d63 100644 (file)
@@ -14196,14 +14196,29 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
          && integer_zerop (op2)
          && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1)))
        {
+         /* sign_bit_p looks through both zero and sign extensions,
+            but for this optimization only sign extensions are
+            usable.  */
+         tree tem2 = TREE_OPERAND (arg0, 0);
+         while (tem != tem2)
+           {
+             if (TREE_CODE (tem2) != NOP_EXPR
+                 || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (tem2, 0))))
+               {
+                 tem = NULL_TREE;
+                 break;
+               }
+             tem2 = TREE_OPERAND (tem2, 0);
+           }
          /* sign_bit_p only checks ARG1 bits within A's precision.
             If <sign bit of A> has wider type than A, bits outside
             of A's precision in <sign bit of A> need to be checked.
             If they are all 0, this optimization needs to be done
             in unsigned A's type, if they are all 1 in signed A's type,
             otherwise this can't be done.  */
-         if (TYPE_PRECISION (TREE_TYPE (tem))
-             < TYPE_PRECISION (TREE_TYPE (arg1))
+         if (tem
+             && TYPE_PRECISION (TREE_TYPE (tem))
+                < TYPE_PRECISION (TREE_TYPE (arg1))
              && TYPE_PRECISION (TREE_TYPE (tem))
                 < TYPE_PRECISION (type))
            {
index 98147745d8137761a13b67e99036ddd9d567b441..3b22081878eb4ef9b6103a28ff59a73ef7e21330 100644 (file)
@@ -1,9 +1,13 @@
+2013-09-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/58564
+       * gcc.c-torture/execute/pr58564.c: New test.
+
 2013-09-30  Teresa Johnson  <tejohnson@google.com>
 
        * testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c (expand_one_var):
        Update for additional dump message.
 
-
 2013-09-30  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/58554
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58564.c b/gcc/testsuite/gcc.c-torture/execute/pr58564.c
new file mode 100644 (file)
index 0000000..967ee95
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR middle-end/58564 */
+
+extern void abort (void);
+int a, b;
+short *c, **d = &c;
+
+int
+main ()
+{
+  b = (0, 0 > ((&c == d) & (1 && (a ^ 1)))) | 0U;
+  if (b != 0)
+    abort ();
+  return 0;
+}