public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/102800] New: Incorrect UB warning with aggressive-loop-optimizations
@ 2021-10-17  3:49 phil at phord dot com
  2021-10-17  6:54 ` [Bug rtl-optimization/102800] " pinskia at gcc dot gnu.org
  2023-05-12  6:36 ` pinskia at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: phil at phord dot com @ 2021-10-17  3:49 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 102800
           Summary: Incorrect UB warning with
                    aggressive-loop-optimizations
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: phil at phord dot com
  Target Milestone: ---

I found this spurious warning occurs since gcc 11.1.  It does not occur in 10.3
or previous versions that I tested.

I believe this is a different bug from PR100801 because that bug started
appearing in 9.1.

This bug seems to be very sensitive to changes from this minimal code:
----------------[ Source ]-----------------
/* Compiled with: gcc-11 -O2 -c test.c   */
void bar(char x);
void foo(char * begin)
{
    // end = ALIGN(begin, 8);
    char * end = begin + 7 - ((((unsigned long)begin) - 1) % 8);

    if (begin != end) {
        long long x = end - begin;
        do bar(x);
        while(--x != 0);
    }
}

static char buff[1024] = { 0 };
void test(int i)
{
    foo(buff + i * 8);
}

------------[ Compiler output ]-------------

In function 'void foo(char*)',
    inlined from 'void test(int)' at <source>:16:8:
<source>:9:19: warning: iteration 0x8000000000000000 invokes undefined behavior
[-Waggressive-loop-optimizations]
    9 |         while(--x != 0);
      |               ~~~~^~~~
<source>:9:19: note: within this loop
--------------------------------------------

Notice we don't enter the loop unless x will be greater than zero because of
the `begin != end` check, and because end >= begin due to the ALIGN math.

The compiled code appears to be correct. Only the spurious warning is a
problem. (In fact, the compiled code is optimized out where the warning is
generated because the inlined function has nothing to do. But the code is
called from elsewhere, so size and correctness matter, of course.)

I found several workarounds:

> Change x to unsigned.  Produces exact same obj output but no warning:
        unsigned long long x = end - begin;

> Change x to short (int16_t). Produces exact same obj output but no warning:
        short x = end - begin;

> Compare with > 0 instead of != 0. Compiled output is 1 opcode longer:
        while(--x > 0);

> Use calculated x value to determine whether to enter loop.
    long long x = end - begin;
    if (x > 0)
        do bar(x);
        while(--x != 0);

----

I just noticed this bug (spurious warning) appears in 9.3 and earlier if I
change this line from != to <:

    if (begin < end) {

I guess it is this subtle difference that I think is a new bug. But maybe this
is a dup of PR100801 after all.

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

* [Bug rtl-optimization/102800] Incorrect UB warning with aggressive-loop-optimizations
  2021-10-17  3:49 [Bug c/102800] New: Incorrect UB warning with aggressive-loop-optimizations phil at phord dot com
@ 2021-10-17  6:54 ` pinskia at gcc dot gnu.org
  2023-05-12  6:36 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-10-17  6:54 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2021-10-17
             Status|UNCONFIRMED                 |NEW
           Keywords|                            |missed-optimization

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
  end_10 = begin_9(D) + _3;
  if (begin_9(D) != end_10)
    goto <bb 3>; [INV]
  else
    goto <bb 5>; [INV]
;;    succ:       3 (TRUE_VALUE,EXECUTABLE)
;;                5 (FALSE_VALUE,EXECUTABLE)

;;   basic block 3, loop depth 0, maybe hot
;;    prev block 2, next block 4, flags: (NEW, VISITED)
;;    pred:       2 (TRUE_VALUE,EXECUTABLE)
  # RANGE [0, 7] NONZERO 7
  _15 = (signed long) _3;

;;   basic block 4, loop depth 1, maybe hot
;;    prev block 3, next block 5, flags: (NEW, VISITED)
;;    pred:       3 (FALLTHRU,EXECUTABLE)
;;                4 (TRUE_VALUE,EXECUTABLE)
  # RANGE [-9223372036854775808, 7]
  # x_6 = PHI <_15(3), x_14(4)>
  # .MEM_7 = PHI <.MEM_11(D)(3), .MEM_13(4)>
  _4 = (charD.7) x_6;
  # RANGE [-128, 127]
  _5 = (intD.6) _4;
  # .MEM_13 = VDEF <.MEM_7>
  # USE = nonlocal escaped 
  # CLB = nonlocal escaped 
  barD.1978 (_5);
  # RANGE [-9223372036854775808, 6]
  x_14 = x_6 + -1;
  if (x_14 != 0)
    goto <bb 4>; [INV]
  else
    goto <bb 5>; [INV]
;;    succ:       4 (TRUE_VALUE,EXECUTABLE)
;;                5 (FALSE_VALUE,EXECUTABLE)

this is from evrp.  Oh We miss that _15 cannot be 1.

even though later on we can detect it.

SO simple testcase:
void bar(char x);
void link_error(void);
void foo(char * begin)
{
    // end = ALIGN(begin, 8);
    __SIZE_TYPE__ t = 7 - ((((unsigned long)begin) - 1) % 8);
    char * end = begin + t;

    if (begin != end) {
        if (!t) link_error();
        long long x = end - begin;
        do bar(x);
        while(--x != 0);
    }
}

The call to should really be removed in evrp.

So forwprop1 does not change the first begin!=end to t!=0 but changes
end-begin.  to (long long)t. And then forwprop2 changes begin!=end to t!=0 and
vrp1 can then figure out the range of x inside the loop is [1,7].

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

* [Bug rtl-optimization/102800] Incorrect UB warning with aggressive-loop-optimizations
  2021-10-17  3:49 [Bug c/102800] New: Incorrect UB warning with aggressive-loop-optimizations phil at phord dot com
  2021-10-17  6:54 ` [Bug rtl-optimization/102800] " pinskia at gcc dot gnu.org
@ 2023-05-12  6:36 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-12  6:36 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |12.0
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Fixed in GCC 12 by doing some folding inside evrp too.

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

end of thread, other threads:[~2023-05-12  6:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-17  3:49 [Bug c/102800] New: Incorrect UB warning with aggressive-loop-optimizations phil at phord dot com
2021-10-17  6:54 ` [Bug rtl-optimization/102800] " pinskia at gcc dot gnu.org
2023-05-12  6:36 ` pinskia 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).