Skip to content

Commit 89cdac4

Browse files
committed
[BasicAA] MemCpyOpt fix on tail stackrestore
1 parent 05c3a4b commit 89cdac4

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,12 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
914914

915915
const Value *Object = getUnderlyingObject(Loc.Ptr);
916916

917+
// Stack restore is able to modify unescaped dynamic allocas. Assume it may
918+
// modify them even though the alloca is not escaped.
919+
if (auto *AI = dyn_cast<AllocaInst>(Object))
920+
if (!AI->isStaticAlloca() && isIntrinsicCall(Call, Intrinsic::stackrestore))
921+
return ModRefInfo::Mod;
922+
917923
// Calls marked 'tail' cannot read or write allocas from the current frame
918924
// because the current frame might be destroyed by the time they run. However,
919925
// a tail call may use an alloca with byval. Calling with byval copies the
@@ -925,12 +931,6 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
925931
!CI->getAttributes().hasAttrSomewhere(Attribute::ByVal))
926932
return ModRefInfo::NoModRef;
927933

928-
// Stack restore is able to modify unescaped dynamic allocas. Assume it may
929-
// modify them even though the alloca is not escaped.
930-
if (auto *AI = dyn_cast<AllocaInst>(Object))
931-
if (!AI->isStaticAlloca() && isIntrinsicCall(Call, Intrinsic::stackrestore))
932-
return ModRefInfo::Mod;
933-
934934
// A call can access a locally allocated object either because it is passed as
935935
// an argument to the call, or because it has escaped prior to the call.
936936
//

llvm/test/Transforms/MemCpyOpt/stackrestore.ll

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt -S -passes=memcpyopt < %s -verify-memoryssa | FileCheck %s
3+
; RUN: opt -S -passes="tailcallelim,memcpyopt" < %s -verify-memoryssa | FileCheck %s
34

45
; PR40118: BasicAA didn't realize that stackrestore ends the lifetime of
56
; unescaped dynamic allocas, such as those that might come from inalloca.
@@ -23,7 +24,7 @@ define i32 @test_norestore(i32 %n) {
2324
; CHECK-NEXT: store i8 0, ptr [[P10]], align 1
2425
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[TMPMEM]], ptr [[P]], i32 10, i1 false)
2526
; CHECK-NEXT: call void @external()
26-
; CHECK-NEXT: [[HEAP:%.*]] = call ptr @malloc(i32 9)
27+
; CHECK-NEXT: [[HEAP:%.*]] = tail call ptr @malloc(i32 9)
2728
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[HEAP]], ptr align 1 @str, i32 9, i1 false)
2829
; CHECK-NEXT: call void @useit(ptr [[HEAP]])
2930
; CHECK-NEXT: ret i32 0
@@ -40,7 +41,7 @@ define i32 @test_norestore(i32 %n) {
4041

4142
call void @llvm.memcpy.p0.p0.i32(ptr %tmpmem, ptr %p, i32 10, i1 false)
4243
call void @external()
43-
%heap = call ptr @malloc(i32 9)
44+
%heap = tail call ptr @malloc(i32 9)
4445
call void @llvm.memcpy.p0.p0.i32(ptr %heap, ptr %tmpmem, i32 9, i1 false)
4546
call void @useit(ptr %heap)
4647
ret i32 0
@@ -58,7 +59,7 @@ define i32 @test_stackrestore() {
5859
; CHECK-NEXT: store i8 0, ptr [[P10]], align 1
5960
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[TMPMEM]], ptr [[ARGMEM]], i32 10, i1 false)
6061
; CHECK-NEXT: call void @llvm.stackrestore.p0(ptr [[INALLOCA_SAVE]])
61-
; CHECK-NEXT: [[HEAP:%.*]] = call ptr @malloc(i32 9)
62+
; CHECK-NEXT: [[HEAP:%.*]] = tail call ptr @malloc(i32 9)
6263
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[HEAP]], ptr [[TMPMEM]], i32 9, i1 false)
6364
; CHECK-NEXT: call void @useit(ptr [[HEAP]])
6465
; CHECK-NEXT: ret i32 0
@@ -74,7 +75,7 @@ define i32 @test_stackrestore() {
7475

7576
call void @llvm.memcpy.p0.p0.i32(ptr %tmpmem, ptr %argmem, i32 10, i1 false)
7677
call void @llvm.stackrestore(ptr %inalloca.save)
77-
%heap = call ptr @malloc(i32 9)
78+
%heap = tail call ptr @malloc(i32 9)
7879
call void @llvm.memcpy.p0.p0.i32(ptr %heap, ptr %tmpmem, i32 9, i1 false)
7980
call void @useit(ptr %heap)
8081
ret i32 0

0 commit comments

Comments
 (0)