mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 17:56:50 +00:00
[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)
This commit is contained in:
parent
e80925b5eb
commit
5bd0474d1c
@ -192,6 +192,11 @@ public:
|
||||
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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
50
llvm/test/Transforms/LICM/PR116813-memoryssa-outdated.ll
Normal file
50
llvm/test/Transforms/LICM/PR116813-memoryssa-outdated.ll
Normal file
@ -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)
|
Loading…
x
Reference in New Issue
Block a user