Given a function like the following:
void forked_ptrs_different_base_same_offset(float *Base1, float *Base2, float *Dest, int *Preds) { for (int i=0; i<100; i++) { if (Pred[i] != 0) { Dest[i] = Base1[i]; } else { Dest[i] = Base2[i]; } } }
LLVM will optimize the IR to a single load using a pointer determined by a select instruction:
%spec.select = select i1 %cmp1.not, float* %Base2, float* %Base1 %.sink.in = getelementptr inbounds float, float* %spec.select, i64 %indvars.iv %.sink = load float, float* %.sink.in, align 4
LAA is currently unable to analyze such IR, since ScalarEvolution will return a SCEVUnknown for the pointer operand for the load.
This patch adds initial optional support for analyzing both possibilities for the pointer and allowing LAA to generate runtime checks for the bounds if required.
Is this needed? Other SCEV types are forward-declared below, so ScalarEvolution.h doesn't need to be included.