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.
It would be good to add a test for the option, e.g. a case that requires 2 or 3 recursions and set test with max-forked-scev-depth=2/3