Skip to content

Commit 393b759

Browse files
authored
indvars: don't replace a phi when that breaks LCSSA (microsoft#6695)
Induction variable simplification (indvars) tries to rewrite exit values; these appear as phi nodes in loop exit blocks. If the replacement for the phi is still in the loop, then that would break the LCSSA property. Don't do that. Add a test for this.
1 parent 98bb80a commit 393b759

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

lib/Transforms/Scalar/IndVarSimplify.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
//
2525
//===----------------------------------------------------------------------===//
2626

27-
#include "llvm/Transforms/Scalar.h"
2827
#include "llvm/ADT/DenseMap.h"
2928
#include "llvm/ADT/SmallVector.h"
3029
#include "llvm/ADT/Statistic.h"
@@ -41,11 +40,13 @@
4140
#include "llvm/IR/Instructions.h"
4241
#include "llvm/IR/IntrinsicInst.h"
4342
#include "llvm/IR/LLVMContext.h"
43+
#include "llvm/IR/Module.h"
4444
#include "llvm/IR/PatternMatch.h"
4545
#include "llvm/IR/Type.h"
4646
#include "llvm/Support/CommandLine.h"
4747
#include "llvm/Support/Debug.h"
4848
#include "llvm/Support/raw_ostream.h"
49+
#include "llvm/Transforms/Scalar.h"
4950
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
5051
#include "llvm/Transforms/Utils/Local.h"
5152
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
@@ -698,6 +699,16 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) {
698699
continue;
699700
}
700701

702+
// HLSL Change Begin
703+
// Avoid breaking LCSSA: Don't replace the PHI if its replacement
704+
// is defined inside the loop.
705+
if (auto *ExitValInst = dyn_cast<Instruction>(ExitVal)) {
706+
if (L->contains(ExitValInst)) {
707+
continue;
708+
}
709+
}
710+
// HLSL Change End
711+
701712
// Collect all the candidate PHINodes to be rewritten.
702713
RewritePhiSet.push_back(
703714
RewritePhi(PN, i, ExitVal, HighCost, LCSSASafePhiForRAUW));
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
; RUN: opt < %s -indvars -S | FileCheck %s
2+
3+
; The inner loop (%header1) has a fixed trip count.
4+
; The indvars pass is tempted to delete the phi instruction %hexit,
5+
; and replace its uses with %add3.
6+
; But %hexit is used in %latch0, which is outside the inner loop and
7+
; its exit block. Deleting the phi %hexit would break LCSSA form.
8+
9+
; CHECK: @main
10+
; CHECK: exit1:
11+
; CHECK-NEXT: %hexit = phi i32 [ %hnext, %header1 ]
12+
; CHECK-NEXT: br label %latch0
13+
14+
; CHECK: latch0:
15+
16+
target triple = "dxil-ms-dx"
17+
18+
define void @main(i32 %arg) {
19+
entry:
20+
br label %header0
21+
22+
header0:
23+
%isgt0 = icmp sgt i32 %arg, 0
24+
%smax = select i1 %isgt0, i32 %arg, i32 0
25+
%h0 = add i32 %smax, 1
26+
%j0 = add i32 %smax, 2
27+
%doinner = icmp slt i32 %j0, 1
28+
br i1 %doinner, label %header1.pre, label %latch0
29+
30+
header1.pre:
31+
br label %header1
32+
33+
header1:
34+
%hi = phi i32 [ %hnext, %header1 ], [ %h0, %header1.pre ]
35+
%ji = phi i32 [ %jnext, %header1 ], [ %j0, %header1.pre ]
36+
%add3 = add i32 %smax, 3
37+
%hnext = add i32 %hi, 1
38+
%jnext = add nsw i32 %ji, 1 ; the nsw here is essential
39+
%do1again = icmp slt i32 %ji, %add3
40+
br i1 %do1again, label %header1, label %exit1
41+
42+
exit1:
43+
%hexit = phi i32 [ %hnext, %header1 ]
44+
br label %latch0
45+
46+
latch0:
47+
%useh = phi i32 [ %h0, %header0 ], [ %hexit, %exit1 ]
48+
br label %header0
49+
}

0 commit comments

Comments
 (0)