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