https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96015
Bug ID: 96015 Summary: [regression] gcc-10.1.0 miscompiles Python on hppa Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: slyfox at inbox dot ru CC: dave.anglin at bell dot net, law at redhat dot com Target Milestone: --- Target: hppa2.0-unknown-linux-gnu Originally reported as https://bugs.gentoo.org/729570 where gcc-10.1.0 miscompiles Python into generating invalid bytecode. I shrunk Python's code into single file that illustrates the problem: // $ cat bug_test.c /* The test is extracted from Python-3.9.0 miscompilation on hppa2.0: https://bugs.gentoo.org/729570 Original bug happens as an invalid bytecode generation due to bad results from 'long_richcompare(0xFFFFffff, 1, EQ)' calls. Failure example: $ hppa2.0-unknown-linux-gnu-gcc -lm -Wsign-compare -Wall -O1 bug_test.c -o good-bug $ hppa2.0-unknown-linux-gnu-gcc -lm -Wsign-compare -Wall -O2 bug_test.c -o bad-bug $ ./good-bug long_richcompare(2, 1, EQ) = FALSE (expect FALSE) $ ./bad-bug long_richcompare(2, 1, EQ) = TRUE (expect FALSE) */ // We use '__attribute__((noipa));' aggressively to simulate // unavailable function definitions from outside translation units. static int cmp(int *lhs, int *rhs) { int sign = *lhs - *rhs; // semantically this should be 'return 0;' but this condition is not // supposed to trigger on our input data. if (sign == 0) return 1; return sign; } static int yes(void) __attribute__((noipa)); static int yes(void) { return 1; } static int long_richcompare(int *self, int *other, int op) __attribute__((noipa)); static int long_richcompare(int *self, int *other, int op) { int result; if (!yes() || !yes()) return 0; if (self == other) result = 0; else result = cmp(self, other); // has to force jump table switch (op) { // only 0 case is used on actual data case 0: return (result == 0); case 1: return 0; case 3: return 0; case 5: if (result == 0) return 1; else return 0; default: __builtin_unreachable(); } } #include <stdio.h> int main() { int l = 2; int r = 1; int res = long_richcompare(&l, &r, 0); printf("long_richcompare(2, 1, EQ) = %s (expect FALSE)\n", res ? "TRUE" : "FALSE"); }