https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122610
--- Comment #10 from liu zhenyu <lzy20000419 at outlook dot com> ---
Thanks for pointing that out, Jonathan! That was an oversight in the minimizer.
I have fixed the signed overflow by using unsigned int arithmetic to ensure
well-defined wrapping behavior.
The miscompilation persists with the UB-free code.
Updated Reproducer:
// Complete GCC Bug - 2025 + Regression Analysis
// Generation: 0
// Results: {'-O1': 1760, '-O2': 160, '-O3': 1440}
// Compile with: gcc -O1/-O2/-O3 -fstrict-aliasing
#include <stdio.h>
#include <stdint.h>
#include <string.h>
struct RString_0 {
char *ptr;
long len;
};
char *ptr_global_0;
__attribute__((noinline))
char * get_ptr_0(struct RString_0 *str) {
return str->ptr;
}
// Trick GCC's IPA into thinking this store is dead code
__attribute__((noinline))
int ipa_modref_bug(struct RString_0 *str) {
str->ptr = ptr_global_0;
char *val = get_ptr_0(str);
if (val == NULL) {
return -1;
}
int result = 0;
// Safe approach: Cast the pointer to an integer, then take the lower 8
bits.
uintptr_t addr = (uintptr_t)val;
int addend = (int)(addr & 0xFF);
for (int i = 0; i < 10; i++) {
result += addend;
}
return result;
}
__attribute__((noinline))
int test_ipa_modref_dse() {
struct RString_0 str;
char buffer[116];
ptr_global_0 = buffer;
for (int i = 0; i < 116; i++) {
buffer[i] = (char)(((unsigned int)i * 827312095U) & 0xFF);
}
int result = ipa_modref_bug(&str);
if (str.ptr != buffer) {
result += 1000;
}
return result;
}
int main() {
int result = test_ipa_modref_dse();
printf("%d\n", result);
return 0;
}
Since the code is now free of UB but the discrepancy between -O1 and -O3
remains, this confirms it is indeed an optimization regression.