ccd682e837
* chore: [30-x-y] cherry-pick 5 changes from 2-M126 * 5d4df51d1d7d from angle * 771e74ab497d from DirectXShaderCompiler * 8f07d39227f6 from DirectXShaderCompiler * b3c64851765c from DirectXShaderCompiler * d5217a718925 from v8 * chore: update patches --------- Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
116 lines
4.1 KiB
Diff
116 lines
4.1 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antonio Maiorano <amaiorano@google.com>
|
|
Date: Thu, 20 Jun 2024 14:02:42 -0400
|
|
Subject: indvars: don't replace a phi when that breaks LCSSA (#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.
|
|
|
|
Bug: chromium:345993680
|
|
Change-Id: Ib2330afa3c6f47373cb4336cfd00e851044fea3a
|
|
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5645925
|
|
Reviewed-by: dan sinclair <dsinclair@chromium.org>
|
|
Reviewed-by: James Price <jrprice@google.com>
|
|
|
|
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
|
|
index f5b1455d5932b63dfef699991c5eeab38e447a7d..e6ff7b3ab4d81bbb782f0bd0a7b5185a30fd1285 100644
|
|
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
|
|
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
|
|
@@ -24,7 +24,6 @@
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
-#include "llvm/Transforms/Scalar.h"
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
@@ -41,11 +40,13 @@
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/IR/IntrinsicInst.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
+#include "llvm/IR/Module.h"
|
|
#include "llvm/IR/PatternMatch.h"
|
|
#include "llvm/IR/Type.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
+#include "llvm/Transforms/Scalar.h"
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
#include "llvm/Transforms/Utils/Local.h"
|
|
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
|
|
@@ -698,6 +699,16 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) {
|
|
continue;
|
|
}
|
|
|
|
+ // HLSL Change Begin
|
|
+ // Avoid breaking LCSSA: Don't replace the PHI if its replacement
|
|
+ // is defined inside the loop.
|
|
+ if (auto *ExitValInst = dyn_cast<Instruction>(ExitVal)) {
|
|
+ if (L->contains(ExitValInst)) {
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+ // HLSL Change End
|
|
+
|
|
// Collect all the candidate PHINodes to be rewritten.
|
|
RewritePhiSet.push_back(
|
|
RewritePhi(PN, i, ExitVal, HighCost, LCSSASafePhiForRAUW));
|
|
diff --git a/test/HLSL/passes/indvars/preserve-phi-when-replacement-is-in-loop.ll b/test/HLSL/passes/indvars/preserve-phi-when-replacement-is-in-loop.ll
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..b550ce993837814229f8223a47b2af328cc7c87c
|
|
--- /dev/null
|
|
+++ b/test/HLSL/passes/indvars/preserve-phi-when-replacement-is-in-loop.ll
|
|
@@ -0,0 +1,49 @@
|
|
+; RUN: opt < %s -indvars -S | FileCheck %s
|
|
+
|
|
+; The inner loop (%header1) has a fixed trip count.
|
|
+; The indvars pass is tempted to delete the phi instruction %hexit,
|
|
+; and replace its uses with %add3.
|
|
+; But %hexit is used in %latch0, which is outside the inner loop and
|
|
+; its exit block. Deleting the phi %hexit would break LCSSA form.
|
|
+
|
|
+; CHECK: @main
|
|
+; CHECK: exit1:
|
|
+; CHECK-NEXT: %hexit = phi i32 [ %hnext, %header1 ]
|
|
+; CHECK-NEXT: br label %latch0
|
|
+
|
|
+; CHECK: latch0:
|
|
+
|
|
+target triple = "dxil-ms-dx"
|
|
+
|
|
+define void @main(i32 %arg) {
|
|
+entry:
|
|
+ br label %header0
|
|
+
|
|
+header0:
|
|
+ %isgt0 = icmp sgt i32 %arg, 0
|
|
+ %smax = select i1 %isgt0, i32 %arg, i32 0
|
|
+ %h0 = add i32 %smax, 1
|
|
+ %j0 = add i32 %smax, 2
|
|
+ %doinner = icmp slt i32 %j0, 1
|
|
+ br i1 %doinner, label %header1.pre, label %latch0
|
|
+
|
|
+header1.pre:
|
|
+ br label %header1
|
|
+
|
|
+header1:
|
|
+ %hi = phi i32 [ %hnext, %header1 ], [ %h0, %header1.pre ]
|
|
+ %ji = phi i32 [ %jnext, %header1 ], [ %j0, %header1.pre ]
|
|
+ %add3 = add i32 %smax, 3
|
|
+ %hnext = add i32 %hi, 1
|
|
+ %jnext = add nsw i32 %ji, 1 ; the nsw here is essential
|
|
+ %do1again = icmp slt i32 %ji, %add3
|
|
+ br i1 %do1again, label %header1, label %exit1
|
|
+
|
|
+exit1:
|
|
+ %hexit = phi i32 [ %hnext, %header1 ]
|
|
+ br label %latch0
|
|
+
|
|
+latch0:
|
|
+ %useh = phi i32 [ %h0, %header0 ], [ %hexit, %exit1 ]
|
|
+ br label %header0
|
|
+}
|