"In software engineering, strength reduction is a compiler optimization
where expensive operations are replaced with equivalent but less
expensive operations. The classic example of strength reduction converts
"strong" multiplications inside a loop into "weaker" additions –
something that frequently occurs in array addressing." )
And here is another loop:
extern void foo(int);
typedef struct {int i; int a[10];} S;
void bar(S* A) {
for(int i = 50; i < 400;i++)
foo(A[i].i);
}
In this case, there is a multiplication in each loop iteration 'hidden'
in the GEP. Can this be turned into addition too?
I was hoping the loop-reduce pass would do this kind of thing; should it?
I believe the reason you still see multiplies with “clang -emit-llvm” is that LoopStrengthReduction is not in the target-independent optimization pipeline. It runs in the target-specific IR optimizer.
If you take the IR emitted with “clang -emit-llvm” and run “llc foo.ll -print-after-all”, you should be able to see the IR right after applying LSR. The x86 backend adds LoopStrengthReduce to its target-specific pipeline here. If you want LLVM to run LSR for your backend, make sure your TargetPassConfig adds LSR or calls the generic TargetPassConfig::addIRPasses (e.g. see how the NVPTX backend adds LSR).