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

            Bug ID: 127521
           Summary: [avr] `ifcombine` incorrectly removes a masked
                    sign-bit condition
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mikaseianatsu at proton dot me
  Target Milestone: ---

GCC ifcombine miscompiles the following defined C program on avr-elf, where int
is 16 bits.


Reproducer:

int
cmp3 (int d1, int d2)
{
  int x = d2 ^ d1;
  if (x < 0 || d1 != (d2 & 32767))
    return 0;
  return 1;
}

Reproduced on GCC main commit 7459f91 with:

avr-elf-gcc -O2 -fdump-tree-ifcombine-details -S gcc4.c


Incorrect behavior:

ifcombine merges the comparisons into full 16-bit equality, producing code
equivalent to:

return d1 == d2;

For d1 = d2 = -32768 (bit pattern 0x8000), the expected result is 0, but the
optimized code returns 1.

The XOR sign-bit test is false, but d1 != (d2 & 32767) is true. Disabling the
pass with -fdisable-tree-ifcombine preserves the correct behavior.


Smtgcc also reports:

copyprop -> ifcombine: Transformation is not correct (retval)
.param0 = #x8000
.param1 = #x8000
src retval: #x0000
tgt retval: #x0001
tgt ub: false


Commit 52e4ede0309 fixes a related issue (PR118409), but this testcase still
fails on a revision containing that fix:
https://github.com/gcc-mirror/gcc/commit/52e4ede0309

Reply via email to