I came across an assertion which was caused due to a call to isInductionPhi() on a Phi which is present in the Loop body and not the Loop header.
def void @temp() {
br label %1
1: ; preds = %5, %0
%2 = phi i64 [ %3, %5 ], [ 0, %0 ]
%3 = add i64 %2, 1
br i1 false, label %5, label %4
4: ; preds = %1
br label %5
5: ; preds = %4, %1
%6 = phi i64 [ %2, %4 ], [ 0, %1 ]
%7 = getelementptr double, ptr null, i64 %6
%8 = load double, ptr %7, align 8
br i1 true, label %9, label %1
9: ; preds = %5
ret void
}
Lets consider this LLVM IR snip, for the bug. If you see the Phi (%6 = phi i64 [ %2, %4 ], [ 0, %1 ]), and call the function isInductionPhi on the given function, it will crash with an assert “Invalid basic block argument!”.
bool InductionDescriptor::isInductionPHI(
{
...
Value *StartValue =
Phi->getIncomingValueForBlock(AR->getLoop()->getLoopPreheader());
...
}
Expanding the said function, it triggered an assertion inside the getIncomingValueForBlock function.
Value *getIncomingValueForBlock(const BasicBlock *BB) const {
int Idx = getBasicBlockIndex(BB);
assert(Idx >= 0 && "Invalid basic block argument!");
return getIncomingValue(Idx);
}
Now, the assertion seems correct as, the basic block passed to this function is the Loop preheader, which is not there in the value list of the given Phi (%6). So, getBasicBlockIndex() returns -1 as a result of that.
Now, here are my questions.
- Is it correct to say that, Phis that are induction variables cannot be present inside a Loop body and can only be in a Loop header ? (I believe it is correct to say that)
- If (1) is true, should isInductionPhi have such a check ? instead of asserting, if this function is called on a Phi present inside a Loop body, it should return false.