If exiting block is loop header, phi node could be AddRecValue. Handle the case.
It is for fixing https://bugs.llvm.org/show_bug.cgi?id=51866.
Differential D110060
[LoopBoundSplit] Handle the case in which exiting block is loop header jaykang10 on Sep 20 2021, 3:54 AM. Authored by
Details If exiting block is loop header, phi node could be AddRecValue. Handle the case. It is for fixing https://bugs.llvm.org/show_bug.cgi?id=51866.
Diff Detail
Event TimelineComment Actions I completely don't understand neither what happened nor the fix. Could you please give more details on how and why this bug is happening? Comment Actions Sorry for poor explanation... Let me try to explain something more. We need to update the IV's start value in post loop. In the example from https://bugs.llvm.org/show_bug.cgi?id=51866, the IV's start value in post loop is not updated correctly as below. The code has expected the ExitingCond.AddRecValue is add instruction like %inc = add nuw nsw i16 %i.0, 1. The ExitingCond.AddRecValue is calculated from exiting block's condition. For example, for.inc: %inc = add nuw nsw i64 %iv, 1 %cond = icmp sgt i64 %inc, %n br i1 %cond, label %exit, label %loop In above example, the latch is exiting block and the ExitingCond.AddRecValue is %inc = add nuw nsw i64 %iv, 1. for.cond: ; preds = %for.inc, %entry %i.0 = phi i16 [ 0, %entry ], [ %inc, %for.inc ] %exitcond.not = icmp eq i16 %i.0, 10 br i1 %exitcond.not, label %for.end, label %for.body In above example, the header is exiting block and the ExitingCond.AddRecValue is %i.0 = phi i16 [ 0, %entry ], [ %inc, %for.inc ]. Previously, the code missed this case. This patch detects this case and update the IV's start value in post loop correctly. If you feel something wrong, please let me know.
Comment Actions https://reviews.llvm.org/D110060 is merged into this patch. Following the comment of @mkazantsev, updated patch.
Comment Actions Update phi nodes in header of post-loop using LCSSA. We can say that the start value of phi node in post-loop is the value of phi node at last iteration in pre-loop. Let's see a simple example. for.body: %i = phi i16 [ 0, %entry ], [ %add, %cond.end ] %cmp1 = icmp ult i16 %i, 3 br i1 %cmp1, label %cond.true, label %cond.false cond.true: br label %cond.end cond.false: br label %cond.end cond.end: %call = call i16 @foo() %add = add nuw nsw i16 %i, 1 %cmp2 = icmp ult i16 %i, 11 br i1 %cmp2, label %for.body, label %end In above example, we can add a LCSSA Phi node in exit block of pre-loop and update the start value of the phi node with the LCSSA one as below. entry.split.split: %i.lcssa = phi i16 [ %add, %cond.end ] ... for.body.split.preheader: br label %for.body.split ... for.body.split: %i.split = phi i16 [ %add.split, %cond.end.split ], [ %i.lcssa, %for.body.split.preheader ] In this example, the value of phi node at last iteration is %add because the exiting condition uses it. If the exiting block is not loop latch, we need to update the phi node differently. Let's see other example. for.cond: ; preds = %for.inc, %entry %i.0 = phi i16 [ 0, %entry ], [ %inc.0, %for.inc ] %exitcond.not = icmp eq i16 %i.0, 10 br i1 %exitcond.not, label %for.end, label %for.body for.body: %cmp1 = icmp ult i16 %i.0, 5 %arrayidx = getelementptr inbounds [10 x i16], [10 x i16]* @B, i16 0, i16 %i.0 %0 = load i16, i16* %arrayidx, align 1 br i1 %cmp1, label %if.then, label %if.else if.then: br label %for.inc if.else: br label %for.inc for.inc: %inc.0 = add nuw nsw i16 %i.0, 1 For above example, we can add the LCSSA phi node as below. entry.split.split: %i.0.lcssa = phi i16 [ %i.0, %for.cond ] ... for.cond.split.preheader: br label %for.cond.split ... for.cond.split: %i.0.split = phi i16 [ %inc.0.split, %for.inc.split ], [ %i.0.lcssa, %for.cond.split.preheader ] In this example, the value of phi node at last iteration is %i.0 because the exiting condition uses it. Based on this logic, the patch is updated. @mkazantsev If you feel something wrong, please let me know.
Comment Actions Look fine as far as I can tell, but please split out the SCEV->AddRec refactoring into a separate NFC patch to reduce the scope of change here.
Comment Actions Following comments of @mkazantsev, updated patch
|
Please split out SCEV -> SCEVAddRecExpr refactoring in a separate NFC patch. It can go before the others.