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,17 @@ // 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)) + continue; + unsigned OperandNo = CB.getDataOperandNo(U); + if (CB.doesNotCapture(OperandNo)) // 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.onlyReadsMemory(CB.getDataOperandNo(U))) + // If it can write to memory, it can leak the alloca value. + EscapePoints.insert(&CB); break; } case Instruction::Load: { @@ -168,19 +171,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/basic.ll b/llvm/test/Transforms/TailCallElim/basic.ll --- a/llvm/test/Transforms/TailCallElim/basic.ll +++ b/llvm/test/Transforms/TailCallElim/basic.ll @@ -246,7 +246,7 @@ ; Alloca's that are readonly arguments should not be be escaped. define void @test16() { ; CHECK-LABEL: @test16 -; CHECK-NOT: tail call void @noarg +; CHECK: tail call void @noarg entry: %x = alloca i32, align 4 call void @use_readonly(ptr %x)