There doesn't appear to be any reason why GVN-PRE couldn't be extended to do strength reduction. If this is added, the strength reduction currently done in DOM and IVOPTS may be removed or simplified. The implementation in IVOPTS only works on loops, and the transformations done in DOM only works in a few special cases and only on a branch of the dominator tree (i.e. not a global pass). Also, GVN-PRE could replace the flag_unsafe_math_optimizations trick that used to be in expr.c and is now in tree-ssa-loop-im.c: /* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal to be hoisted out of loop, saving expensive divide. */ Adding this transformation as a special case of "strength reduction" to GVN-PRE would allow the transformation to be done on straight-line code as well (the code in expr.c used to do this, but we don't do the transformation anymore at the moment). Consider as an example: int foo (int a[], int b[], int i) { a[i] = b[i] + 2; i++; a[i] = b[i] + 2; i++; a[i] = b[i] + 2; i++; a[i] = b[i] + 2; i++; return i; } "GCC 4.1.0 20050721 (experimental)" produces the following .vars dump: foo (a, b, i) { int * temp.44; int * temp.43; int * temp.42; int * D.1608; <bb 0>: D.1608 = (int *) ((long unsigned int) i * 4); *(D.1608 + a) = *(D.1608 + b) + 2; temp.42 = (int *) ((long unsigned int) (i + 1) * 4); *(a + temp.42) = *(b + temp.42) + 2; temp.43 = (int *) ((long unsigned int) (i + 2) * 4); *(a + temp.43) = *(b + temp.43) + 2; temp.44 = (int *) ((long unsigned int) (i + 3) * 4); *(a + temp.44) = *(b + temp.44) + 2; return i + 4; } Note the redundant computations of "i*4". Indeed, we don't optimize these away on RTL either.
Confirmed. Note there is a pass at the tree level which already does the replace "a/b to a*(1/b)" at the rtl level.
*** Bug 35308 has been marked as a duplicate of this bug. ***
Related to PR 32120, actually I think PR 32120 is really asking for strength reduction just it was not called that in the bug report.
(In reply to comment #3) > Related to PR 32120, actually I think PR 32120 is really asking for strength > reduction just it was not called that in the bug report. And it needs PR 37242 to fix the (long unsigned int) (i + 1)*4 and (long unsigned int) (i)*4 issue.
This specific case is handled by the new strength reduction pass. Some more complex scenarios will be added later.