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.

Reply via email to