public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/97555] New: wrong code at -Os and above on x86_64-pc-linux-gnu
@ 2020-10-23 19:23 su at cs dot ucdavis.edu
  2020-10-24  8:15 ` [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685 jakub at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: su at cs dot ucdavis.edu @ 2020-10-23 19:23 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555

            Bug ID: 97555
           Summary: wrong code at -Os and above on x86_64-pc-linux-gnu
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: su at cs dot ucdavis.edu
  Target Milestone: ---

[536] % gcctk -v
Using built-in specs.
COLLECT_GCC=gcctk
COLLECT_LTO_WRAPPER=/local/suz-local/software/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/11.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-trunk/configure --disable-bootstrap
--prefix=/local/suz-local/software/local/gcc-trunk --enable-languages=c,c++
--disable-werror --enable-multilib --with-system-zlib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.0.0 20201023 (experimental) [master revision
7991e963239:9cbfe237f74:757ba6653c2699761c2243e0194749a6695112d8] (GCC) 
[537] % 
[537] % gcctk -O1 small.c; ./a.out
[538] % 
[538] % gcctk -Os small.c
[539] % ./a.out
Floating point exception
[540] % 
[540] % cat small.c
struct {
  int a:1;
} b;

int c, d, e, f = 1, g;

int main ()
{
  for (; d < 3; d++) {
    char h = 1 % f, i = ~(0 || ~0);
    c = h;
    f = ~b.a;
    ~b.a | 1 ^ ~i && g;
    if (~e)
      i = b.a;
    b.a = i;
  }
  return 0;
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
  2020-10-23 19:23 [Bug tree-optimization/97555] New: wrong code at -Os and above on x86_64-pc-linux-gnu su at cs dot ucdavis.edu
@ 2020-10-24  8:15 ` jakub at gcc dot gnu.org
  2020-10-26 15:58 ` amacleod at redhat dot com
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-10-24  8:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2020-10-24
   Target Milestone|---                         |11.0
     Ever confirmed|0                           |1
            Summary|wrong code at -Os and above |[11 Regression] wrong code
                   |on x86_64-pc-linux-gnu      |at -Os and above on
                   |                            |x86_64-pc-linux-gnu since
                   |                            |r11-3685
             Status|UNCONFIRMED                 |NEW
                 CC|                            |aldyh at gcc dot gnu.org,
                   |                            |amacleod at redhat dot com,
                   |                            |jakub at gcc dot gnu.org
           Priority|P3                          |P1

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Started with r11-3685-gfcae5121154d1c3382b056bcc2c563cedac28e74

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
  2020-10-23 19:23 [Bug tree-optimization/97555] New: wrong code at -Os and above on x86_64-pc-linux-gnu su at cs dot ucdavis.edu
  2020-10-24  8:15 ` [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685 jakub at gcc dot gnu.org
@ 2020-10-26 15:58 ` amacleod at redhat dot com
  2020-10-26 16:01 ` aldyh at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: amacleod at redhat dot com @ 2020-10-26 15:58 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555

--- Comment #2 from Andrew Macleod <amacleod at redhat dot com> ---
  <bb 3> :
  f.0_1 = f;
  _2 = 1 % f.0_1;
  h_24 = (char) _2;
  _3 = _2;
  c = _3;
  _4 = b.a;
  _5 = (int) _4;
  _6 = ~_5;
  f = _6;
  if (_4 != -1)
    goto <bb 4>; [INV]
  else
    goto <bb 5>; [INV]

when calculating the outgoing_range_p() of edge 3->4,
we know that then range is  != -1. 

operator_not_equal::op1_range
calculates the range on the true side as:

     if (wi::eq_p (op2.lower_bound(), op2.upper_bound()))
        {
          r = op2;
          r.invert ();
        }
538               r = op2;
(gdb) p op2.dump(stderr)
<unnamed-signed:1> [-1, -1]$12 = void
(gdb) n
539               r.invert ();
(gdb) p r.dump(stderr)
<unnamed-signed:1> [-1, -1]$13 = void
(gdb) n
543           break;
(gdb) p r.dump(stderr)
UNDEFINED$14 = void

when we invert the range  <unnamed-signed:1> [-1, -1]
we should get  <unnamed-signed:1> [0, 0]
but instead its returning UNDEFINED.

which when the post dominated merge happens in bb5, we are unioning [-1,-1] and
undefined, producing [-1, -1] ofr the range of _4..
if we were unioning [-1, -1] and [0, 0] like we we are suppose to get, we'd get
VARYING, and the statement would not be incorrectly folded.


You can put a breakpoint in operator_not_equal::op1_range and it should be the
first time it is hit.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
  2020-10-23 19:23 [Bug tree-optimization/97555] New: wrong code at -Os and above on x86_64-pc-linux-gnu su at cs dot ucdavis.edu
  2020-10-24  8:15 ` [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685 jakub at gcc dot gnu.org
  2020-10-26 15:58 ` amacleod at redhat dot com
@ 2020-10-26 16:01 ` aldyh at gcc dot gnu.org
  2020-10-26 16:57 ` aldyh at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: aldyh at gcc dot gnu.org @ 2020-10-26 16:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555

Aldy Hernandez <aldyh at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |aldyh at gcc dot gnu.org

--- Comment #3 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
Mine.  Thanks for the analysis.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
  2020-10-23 19:23 [Bug tree-optimization/97555] New: wrong code at -Os and above on x86_64-pc-linux-gnu su at cs dot ucdavis.edu
                   ` (2 preceding siblings ...)
  2020-10-26 16:01 ` aldyh at gcc dot gnu.org
@ 2020-10-26 16:57 ` aldyh at gcc dot gnu.org
  2020-10-26 18:06 ` cvs-commit at gcc dot gnu.org
  2020-10-26 18:09 ` aldyh at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: aldyh at gcc dot gnu.org @ 2020-10-26 16:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555

--- Comment #4 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
The problem here is we're trying to add 1 to a -1 in a signed 1-bit field.

Signed 1-bits are annoying because you can't really add or subtract one,
because the one is unrepresentable.  For invert() we have a special
subtract_one() function that handles 1-bit signed fields.  We need a
corresponding add_one() here.

The untested patch below should do it. 

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index ee62f103598..74ab2e57fde 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -3680,15 +3680,28 @@ range_tests ()
   // Test 1-bit signed integer union.
   // [-1,-1] U [0,0] = VARYING.
   tree one_bit_type = build_nonstandard_integer_type (1, 0);
+  tree one_bit_min = vrp_val_min (one_bit_type);
+  tree one_bit_max = vrp_val_max (one_bit_type);
   {
-    tree one_bit_min = vrp_val_min (one_bit_type);
-    tree one_bit_max = vrp_val_max (one_bit_type);
     int_range<2> min (one_bit_min, one_bit_min);
     int_range<2> max (one_bit_max, one_bit_max);
     max.union_ (min);
     ASSERT_TRUE (max.varying_p ());
   }

+  // Test inversion of 1-bit signed integers.
+  {
+    int_range<2> min (one_bit_min, one_bit_min);
+    int_range<2> max (one_bit_max, one_bit_max);
+    int_range<2> t;
+    t = min;
+    t.invert ();
+    ASSERT_TRUE (t == max);
+    t = max;
+    t.invert ();
+    ASSERT_TRUE (t == min);
+  }
+
   // Test that NOT(255) is [0..254] in 8-bit land.
   int_range<1> not_255 (UCHAR (255), UCHAR (255), VR_ANTI_RANGE);
   ASSERT_TRUE (not_255 == int_range<1> (UCHAR (0), UCHAR (254)));
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 7847104050c..f45a342605a 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1772,18 +1772,29 @@ irange::irange_intersect (const irange &r)
     verify_range ();
 }

+// Signed 1-bits are strange.  You can't subtract 1, because you can't
+// represent the number 1.  This works around that for the invert routine.
+
 static wide_int inline
 subtract_one (const wide_int &x, tree type, wi::overflow_type &overflow)
 {
-  // A signed 1-bit bit-field, has a range of [-1,0] so subtracting +1
-  // overflows, since +1 is unrepresentable.  This is why we have an
-  // addition of -1 here.
   if (TYPE_SIGN (type) == SIGNED)
-    return wi::add (x, -1 , SIGNED, &overflow);
+    return wi::add (x, -1, SIGNED, &overflow);
   else
     return wi::sub (x, 1, UNSIGNED, &overflow);
 }

+// The analogous function for adding 1.
+
+static wide_int inline
+add_one (const wide_int &x, tree type, wi::overflow_type &overflow)
+{
+  if (TYPE_SIGN (type) == SIGNED)
+    return wi::sub (x, -1, SIGNED, &overflow);
+  else
+    return wi::add (x, 1, TYPE_SIGN (type), &overflow);
+}
+
 /* Return the inverse of a range.  */

 void
@@ -1881,7 +1892,7 @@ irange::invert ()
   // set the overflow bit.
   if (type_max != wi::to_wide (orig_range.m_base[i]))
     {
-      tmp = wi::add (wi::to_wide (orig_range.m_base[i]), 1, sign, &ovf);
+      tmp = add_one (wi::to_wide (orig_range.m_base[i]), ttype, ovf);
       m_base[nitems++] = wide_int_to_tree (ttype, tmp);
       m_base[nitems++] = wide_int_to_tree (ttype, type_max);
       if (ovf)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
  2020-10-23 19:23 [Bug tree-optimization/97555] New: wrong code at -Os and above on x86_64-pc-linux-gnu su at cs dot ucdavis.edu
                   ` (3 preceding siblings ...)
  2020-10-26 16:57 ` aldyh at gcc dot gnu.org
@ 2020-10-26 18:06 ` cvs-commit at gcc dot gnu.org
  2020-10-26 18:09 ` aldyh at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2020-10-26 18:06 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555

--- Comment #5 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Aldy Hernandez <aldyh@gcc.gnu.org>:

https://gcc.gnu.org/g:2118438f49f0c193abe3fa3def350a8129045746

commit r11-4390-g2118438f49f0c193abe3fa3def350a8129045746
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Mon Oct 26 17:50:37 2020 +0100

    Handle signed 1-bit ranges in irange::invert.

    The problem here is we are trying to add 1 to a -1 in a signed 1-bit
    field and coming up with UNDEFINED because of the overflow.

    Signed 1-bits are annoying because you can't really add or subtract
    one, because the one is unrepresentable.  For invert() we have a
    special subtract_one() function that handles 1-bit signed fields.

    This patch implements the analogous add_one() function so that invert
    works.

    gcc/ChangeLog:

            PR tree-optimization/97555
            * range-op.cc (range_tests): Test 1-bit signed invert.
            * value-range.cc (subtract_one): Adjust comment.
            (add_one): New.
            (irange::invert): Call add_one.

    gcc/testsuite/ChangeLog:

            * gcc.dg/pr97555.c: New test.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
  2020-10-23 19:23 [Bug tree-optimization/97555] New: wrong code at -Os and above on x86_64-pc-linux-gnu su at cs dot ucdavis.edu
                   ` (4 preceding siblings ...)
  2020-10-26 18:06 ` cvs-commit at gcc dot gnu.org
@ 2020-10-26 18:09 ` aldyh at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: aldyh at gcc dot gnu.org @ 2020-10-26 18:09 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555

Aldy Hernandez <aldyh at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #6 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
fixed

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-10-26 18:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-23 19:23 [Bug tree-optimization/97555] New: wrong code at -Os and above on x86_64-pc-linux-gnu su at cs dot ucdavis.edu
2020-10-24  8:15 ` [Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685 jakub at gcc dot gnu.org
2020-10-26 15:58 ` amacleod at redhat dot com
2020-10-26 16:01 ` aldyh at gcc dot gnu.org
2020-10-26 16:57 ` aldyh at gcc dot gnu.org
2020-10-26 18:06 ` cvs-commit at gcc dot gnu.org
2020-10-26 18:09 ` aldyh at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).