[llvm-branch-commits] [llvm] release/19.x: [LICM] allow MemoryAccess creation failure (#116813) (PR #117082)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Nov 21 04:18:02 PST 2024
https://github.com/DianQK updated https://github.com/llvm/llvm-project/pull/117082
>From d7c9977e092ee48d8bee2a2787af0d23b75cfee5 Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Wed, 20 Nov 2024 19:52:51 +0800
Subject: [PATCH] [LICM] allow MemoryAccess creation failure (#116813)
Fixes #116809.
After running some passes (SimpleLoopUnswitch, LoopInstSimplify, etc.),
MemorySSA might be outdated, and the instruction `I` may have become a
non-memory touching instruction.
LICM has already handled this, but it does not pass
`CreationMustSucceed=false` to `createDefinedAccess`.
(cherry picked from commit 18b02bbf441660683df7f3925946984203d49bab)
---
llvm/include/llvm/Analysis/MemorySSAUpdater.h | 5 ++
llvm/lib/Analysis/MemorySSAUpdater.cpp | 13 ++++-
llvm/lib/Transforms/Scalar/LICM.cpp | 5 +-
.../LICM/PR116813-memoryssa-outdated.ll | 50 +++++++++++++++++++
4 files changed, 70 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/Transforms/LICM/PR116813-memoryssa-outdated.ll
diff --git a/llvm/include/llvm/Analysis/MemorySSAUpdater.h b/llvm/include/llvm/Analysis/MemorySSAUpdater.h
index d4da3ef1146db7..f598dedea75fd6 100644
--- a/llvm/include/llvm/Analysis/MemorySSAUpdater.h
+++ b/llvm/include/llvm/Analysis/MemorySSAUpdater.h
@@ -192,6 +192,11 @@ class MemorySSAUpdater {
const BasicBlock *BB,
MemorySSA::InsertionPlace Point);
+ MemoryAccess *createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition,
+ const BasicBlock *BB,
+ MemorySSA::InsertionPlace Point,
+ bool CreationMustSucceed);
+
/// Create a MemoryAccess in MemorySSA before an existing MemoryAccess.
///
/// See createMemoryAccessInBB() for usage details.
diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp
index aa550f0b6a7bfd..94061c949b7f85 100644
--- a/llvm/lib/Analysis/MemorySSAUpdater.cpp
+++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp
@@ -1404,8 +1404,17 @@ void MemorySSAUpdater::changeToUnreachable(const Instruction *I) {
MemoryAccess *MemorySSAUpdater::createMemoryAccessInBB(
Instruction *I, MemoryAccess *Definition, const BasicBlock *BB,
MemorySSA::InsertionPlace Point) {
- MemoryUseOrDef *NewAccess = MSSA->createDefinedAccess(I, Definition);
- MSSA->insertIntoListsForBlock(NewAccess, BB, Point);
+ return createMemoryAccessInBB(I, Definition, BB, Point,
+ /*CreationMustSucceed=*/true);
+}
+
+MemoryAccess *MemorySSAUpdater::createMemoryAccessInBB(
+ Instruction *I, MemoryAccess *Definition, const BasicBlock *BB,
+ MemorySSA::InsertionPlace Point, bool CreationMustSucceed) {
+ MemoryUseOrDef *NewAccess = MSSA->createDefinedAccess(
+ I, Definition, /*Template=*/nullptr, CreationMustSucceed);
+ if (NewAccess)
+ MSSA->insertIntoListsForBlock(NewAccess, BB, Point);
return NewAccess;
}
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 91ef2b4b7c1839..ca03eff7a4e25f 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -1464,8 +1464,11 @@ static Instruction *cloneInstructionInExitBlock(
if (MSSAU.getMemorySSA()->getMemoryAccess(&I)) {
// Create a new MemoryAccess and let MemorySSA set its defining access.
+ // After running some passes, MemorySSA might be outdated, and the
+ // instruction `I` may have become a non-memory touching instruction.
MemoryAccess *NewMemAcc = MSSAU.createMemoryAccessInBB(
- New, nullptr, New->getParent(), MemorySSA::Beginning);
+ New, nullptr, New->getParent(), MemorySSA::Beginning,
+ /*CreationMustSucceed=*/false);
if (NewMemAcc) {
if (auto *MemDef = dyn_cast<MemoryDef>(NewMemAcc))
MSSAU.insertDef(MemDef, /*RenameUses=*/true);
diff --git a/llvm/test/Transforms/LICM/PR116813-memoryssa-outdated.ll b/llvm/test/Transforms/LICM/PR116813-memoryssa-outdated.ll
new file mode 100644
index 00000000000000..a040c3cc6947c6
--- /dev/null
+++ b/llvm/test/Transforms/LICM/PR116813-memoryssa-outdated.ll
@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>,licm)' -verify-memoryssa -S < %s | FileCheck %s
+
+; Check that running LICM after SimpleLoopUnswitch does not result in a crash.
+
+define i32 @foo(i1 %arg, ptr %arg1) {
+; CHECK-LABEL: define i32 @foo(
+; CHECK-SAME: i1 [[ARG:%.*]], ptr [[ARG1:%.*]]) {
+; CHECK-NEXT: [[START:.*:]]
+; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i1 [[ARG]]
+; CHECK-NEXT: br i1 [[ARG_FR]], label %[[START_SPLIT_US:.*]], label %[[START_SPLIT:.*]]
+; CHECK: [[START_SPLIT_US]]:
+; CHECK-NEXT: br label %[[LOOP_US:.*]]
+; CHECK: [[LOOP_US]]:
+; CHECK-NEXT: br label %[[BB0:.*]]
+; CHECK: [[BB0]]:
+; CHECK-NEXT: br label %[[BB1:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi ptr [ [[ARG1]], %[[BB0]] ]
+; CHECK-NEXT: [[I3_US:%.*]] = call i32 [[UNSWITCHED_SELECT_US]]()
+; CHECK-NEXT: br i1 true, label %[[LOOP_US]], label %[[RET_SPLIT_US:.*]]
+; CHECK: [[RET_SPLIT_US]]:
+; CHECK-NEXT: [[I3_LCSSA_US:%.*]] = phi i32 [ [[I3_US]], %[[BB1]] ]
+; CHECK-NEXT: br label %[[RET:.*]]
+; CHECK: [[START_SPLIT]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: br label %[[BB2:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: br i1 false, label %[[LOOP]], label %[[RET_SPLIT:.*]]
+; CHECK: [[RET_SPLIT]]:
+; CHECK-NEXT: [[I3_LE:%.*]] = call i32 @bar()
+; CHECK-NEXT: br label %[[RET]]
+; CHECK: [[RET]]:
+; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[I3_LE]], %[[RET_SPLIT]] ], [ [[I3_LCSSA_US]], %[[RET_SPLIT_US]] ]
+; CHECK-NEXT: ret i32 [[DOTUS_PHI]]
+;
+start:
+ br label %loop
+
+loop: ; preds = %loop, %bb
+ %i = select i1 %arg, ptr %arg1, ptr @bar
+ %i3 = call i32 %i()
+ br i1 %arg, label %loop, label %ret
+
+ret: ; preds = %loop
+ ret i32 %i3
+}
+
+declare i32 @bar() nounwind willreturn memory(none)
More information about the llvm-branch-commits
mailing list