https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128551
Bug ID: 128551
Summary: wrong code with sign-extended loads
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: yuki.tanaka at defaultcase dot de
Target Milestone: ---
#include <stdint.h>
int64_t g;
__attribute__((noipa)) int64_t a(int32_t x, int64_t *d)
{
int64_t c;
*d = 0;
if (x)
c = (int32_t)*(int64_t *)&g;
else
c = (int32_t)*(long long *)&g;
*d = 1;
return c;
}
int main(void)
{
g = -1;
if (a(1, &g) != 0)
__builtin_abort();
return 0;
}
a(1, &g) must return 0: *d = 0 sets g to 0 before it is read. Instead a returns
-1 and main aborts. GCC removes *d = 0 and reads the initial value of g. This
happens on current trunk with -O2 -fdisable-tree-phiopt1 -fdisable-tree-phiopt2
-fdisable-tree-phiopt3 -fdisable-tree-phiopt4.
This variant adds an (int32_t) cast to both branches and still fails after the
fix for PR125683.
Compiler Explorer:
https://godbolt.org/z/z643TqvK3