public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/109236] New: [avr] Invalid code of signed 16-bit compare optimization
@ 2023-03-21 15:23 gandalf at winds dot org
  2023-03-21 19:02 ` [Bug target/109236] " dimitar at gcc dot gnu.org
  2023-03-21 21:32 ` gandalf at winds dot org
  0 siblings, 2 replies; 3+ messages in thread
From: gandalf at winds dot org @ 2023-03-21 15:23 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 109236
           Summary: [avr] Invalid code of signed 16-bit compare
                    optimization
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gandalf at winds dot org
  Target Milestone: ---

I'm seeing incorrect code when -O1 or higher is used on AVR (atmega1284p). The
compiler generates code that compares "x" to "y", instead of performing the
subtraction and comparing against 0. This subtraction matters since "x" and "y"
are signed 16-bit variables, and the math in the expression "x-y <= 0" stays as
16-bit in AVR (as opposed to being promoted to 32-bit ints in e.g. x86).

gcc -v:

Using built-in specs.
Reading specs from /usr/local/avr/lib/gcc/avr/12.2.0/device-specs/specs-avr2
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/local/avr/libexec/gcc/avr/12.2.0/lto-wrapper
Target: avr
Configured with: ../configure --target=avr --prefix=/usr/local/avr
--disable-nls --enable-languages=c --disable-bootstrap --disable-libssp
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (GCC)

Sample code:

_Bool compare(short x, short y)
{
  return (x-y <= 0);
}

Compiled using: gcc -O1 -mmcu=atmega1284p -c -o test.o test.c

ASM result:

00000000 <compare>:
   0:   9c 01           movw    r18, r24
   2:   81 e0           ldi     r24, 0x01       ; 1
   4:   62 17           cp      r22, r18        <---- X compared directly to Y;
no subtraction
   6:   73 07           cpc     r23, r19
   8:   04 f4           brge    .+0             ; 0xa <compare+0xa>
   a:   80 e0           ldi     r24, 0x00       ; 0

0000000c <.L2>:
   c:   08 95           ret

I instead expect to see a subtraction between r22:23 and r18:19, then a compare
against r1 (zero).

The following testcase causes an incorrect computation:

compare(-30737, 24799) returns 1 on AVR; expected 0.  (-30737 - (24799)) as
signed 16-bit = 10000, which is not <= 0.

For the record, changing the function to "return ((short)(x-y) <= 0)" produces
the same incorrect code.

Compiling the function without optimization correctly returns 0.

It's possible other signed variable sizes besides 16-bit have the same problem,
but I did not test this.

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

* [Bug target/109236] [avr] Invalid code of signed 16-bit compare optimization
  2023-03-21 15:23 [Bug c/109236] New: [avr] Invalid code of signed 16-bit compare optimization gandalf at winds dot org
@ 2023-03-21 19:02 ` dimitar at gcc dot gnu.org
  2023-03-21 21:32 ` gandalf at winds dot org
  1 sibling, 0 replies; 3+ messages in thread
From: dimitar at gcc dot gnu.org @ 2023-03-21 19:02 UTC (permalink / raw)
  To: gcc-bugs

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

Dimitar Dimitrov <dimitar at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dimitar at gcc dot gnu.org

--- Comment #1 from Dimitar Dimitrov <dimitar at gcc dot gnu.org> ---
Pass the -Wstrict-overflow=4 option to GCC and see that compiler assumes no
integer overlow will happen:

test.c:3:12: warning: assuming signed overflow does not occur when simplifying
'X - Y <= 0' to 'X <= Y' [-Wstrict-overflow]
    3 |   return (x-y <= 0);


Consider using "__builtin_sub_overflow" for a strictly defined behaviour when
integer overflow happens.

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

* [Bug target/109236] [avr] Invalid code of signed 16-bit compare optimization
  2023-03-21 15:23 [Bug c/109236] New: [avr] Invalid code of signed 16-bit compare optimization gandalf at winds dot org
  2023-03-21 19:02 ` [Bug target/109236] " dimitar at gcc dot gnu.org
@ 2023-03-21 21:32 ` gandalf at winds dot org
  1 sibling, 0 replies; 3+ messages in thread
From: gandalf at winds dot org @ 2023-03-21 21:32 UTC (permalink / raw)
  To: gcc-bugs

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

gandalf at winds dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #2 from gandalf at winds dot org ---
Thank you, I hadn't thought of that at all. That was precisely my problem and I
developed a work-around. Not a bug.

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

end of thread, other threads:[~2023-03-21 21:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-21 15:23 [Bug c/109236] New: [avr] Invalid code of signed 16-bit compare optimization gandalf at winds dot org
2023-03-21 19:02 ` [Bug target/109236] " dimitar at gcc dot gnu.org
2023-03-21 21:32 ` gandalf at winds dot 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).