https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109393
--- Comment #4 from manolis.tsamis at vrull dot eu --- (In reply to Richard Biener from comment #3) > It's probably a mismatch of GENERIC/GIMPLE folding. In this case it's > pointer_int_sum prematurely distributing the multiplication: > > /* Return a tree for the sum or difference (RESULTCODE says which) > of pointer PTROP and integer INTOP. */ > > tree > pointer_int_sum (location_t loc, enum tree_code resultcode, > tree ptrop, tree intop, bool complain) > { > ... > /* If what we are about to multiply by the size of the elements > contains a constant term, apply distributive law > and multiply that constant term separately. > This helps produce common subexpressions. */ > > but this kind of stuff shouldn't be done by the frontends these days. > > Gating this fixes the issue. I think this piece of code should be axed > (after careful evaluation of its effect) I have been testing this change and by looking at some tests that it causes to fail, there is a regression on testcases like this (taken from copy-headers-5.c, there are some similar fails): int is_sorted(int *a, int n) { for (int i = 0; i < n - 1; i++) if (a[i] > a[i + 1]) return 0; return 1; } The gimple code for gcc currently is (taken from dump-tree-ch2): _1 = (long unsigned int) i_18; _2 = _1 * 4; _3 = a_13(D) + _2; _4 = *_3; _5 = _1 + 1; _6 = _5 * 4; _7 = a_13(D) + _6; _8 = *_7; While with this change the result is: _1 = (long unsigned int) i_11; _2 = _1 * 4; _3 = a_14(D) + _2; _4 = *_3; _5 = i_11 + 1; _6 = (long unsigned int) _5; _7 = _6 * 4; _8 = a_14(D) + _7; _9 = *_8; As a result the generated code has two loads per loop instead of one. The same holds if e.g. a[i + 1] > a[i + 2] is used because the constant addition is done before the cast to long unsigned int. I believe this is because the logic to distribute the constant is missing as a GIMPLE pattern? Given the original transform it should be valid to propagate the constant addition through the cast?