diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp --- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -133,14 +133,16 @@ // beyond the lifetime of the current frame. if (CB.isArgOperand(U) && CB.isByValArgument(CB.getArgOperandNo(U))) continue; - bool IsNocapture = - CB.isDataOperand(U) && CB.doesNotCapture(CB.getDataOperandNo(U)); - callUsesLocalStack(CB, IsNocapture); - if (IsNocapture) { + AllocaUsers.insert(&CB); + if (!CB.isDataOperand(U) || CB.doesNotCapture(CB.getDataOperandNo(U))) // If the alloca-derived argument is passed in as nocapture, then it // can't propagate to the call's return. That would be capturing. continue; - } + if ((CB.getMemoryEffects().getModRef(MemoryEffects::ArgMem) & + ModRefInfo::Mod) != ModRefInfo::NoModRef) + // The alloca escapes if the function writes to non argument memory, + // such as globals. + EscapePoints.insert(&CB); break; } case Instruction::Load: { @@ -168,19 +170,6 @@ } } - void callUsesLocalStack(CallBase &CB, bool IsNocapture) { - // Add it to the list of alloca users. - AllocaUsers.insert(&CB); - - // If it's nocapture then it can't capture this alloca. - if (IsNocapture) - return; - - // If it can write to memory, it can leak the alloca value. - if (!CB.onlyReadsMemory()) - EscapePoints.insert(&CB); - } - SmallPtrSet AllocaUsers; SmallPtrSet EscapePoints; }; diff --git a/llvm/test/Transforms/TailCallElim/function_readwrite_attrs.ll b/llvm/test/Transforms/TailCallElim/function_readwrite_attrs.ll --- a/llvm/test/Transforms/TailCallElim/function_readwrite_attrs.ll +++ b/llvm/test/Transforms/TailCallElim/function_readwrite_attrs.ll @@ -62,7 +62,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @use_memory_argmem_none(ptr [[X]]) -; CHECK-NEXT: call void @noarg() +; CHECK-NEXT: tail call void @noarg() ; CHECK-NEXT: ret void ; entry: @@ -77,7 +77,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @use_memory_argmem_read(ptr [[X]]) -; CHECK-NEXT: call void @noarg() +; CHECK-NEXT: tail call void @noarg() ; CHECK-NEXT: ret void ; entry: