https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103037
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> --- More reduced testcase - the min() obfuscation is to avoid recognizing a MIN_EXPR before jump threading gets the chance to disrupt it. A GIMPLE unit testcase for PRE is difficult since we are not supporting SSA annotations (ranges) at the moment. static inline const unsigned short * min(unsigned short *d, const unsigned short *e) { return *e < *d ? e : d; } unsigned short __attribute__((noipa)) test(unsigned short arr, unsigned short val) { unsigned short tem = 1; unsigned short tem2 = *min(&arr, &tem); return tem2 / (arr ? arr : val); } int main() { if (test (2, 2) != 0) __builtin_abort(); return 0; } The IL for the reduced testcase before PRE is <bb 2> [local count: 1073741824]: if (arr_6(D) > 1) goto <bb 4>; [50.00%] else goto <bb 3>; [50.00%] <bb 3> [local count: 536870912]: # RANGE [0, 1] NONZERO 1 _1 = (int) arr_6(D); // (A) if (arr_6(D) != 0) goto <bb 4>; [20.00%] else goto <bb 5>; [80.00%] <bb 4> [local count: 536870913]: # RANGE [0, 1] NONZERO 1 # _17 = PHI <_1(3), 1(2)> # RANGE [1, 65535] NONZERO 65535 iftmp.0_9 = (int) arr_6(D); // (B) goto <bb 6>; [100.00%] <bb 5> [local count: 536870913]: # RANGE [0, 65535] NONZERO 65535 iftmp.0_8 = (int) val_7(D); <bb 6> [local count: 1073741824]: # RANGE [0, 65535] NONZERO 65535 # iftmp.0_3 = PHI <iftmp.0_9(4), iftmp.0_8(5)> # RANGE [0, 1] NONZERO 1 # _18 = PHI <_17(4), 0(5)> # RANGE [0, 1] NONZERO 1 _2 = _18 / iftmp.0_3; # RANGE [0, 1] NONZERO 1 _10 = (short unsigned int) _2; return _10; and the problematic value-numbering is iftmp.0_9 = _1 (0001) at (A) and (B). By design we may only use _available_ expressions during simplification but _1 is not available on the 4 -> 6 edge. That's working OK for the translation from 4 -> 6 but then we record a valueized expression into the ANTIC set of 4 which when further translated and simplified has the wrong representative inside.