diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -864,9 +864,11 @@ if (!AI->isStaticAlloca() && isIntrinsicCall(Call, Intrinsic::stackrestore)) return ModRefInfo::Mod; - // If the pointer is to a locally allocated object that does not escape, - // then the call can not mod/ref the pointer unless the call takes the pointer - // as an argument, and itself doesn't capture it. + // A call can access a locally allocated object either because it is passed as + // an argument to the call, or because it has escaped prior to the call. + // + // Make sure the object has not escaped here, and then check that none of the + // call arguments alias the object below. if (!isa(Object) && Call != Object && AAQI.CI->isNotCapturedBeforeOrAt(Object, Call)) { @@ -877,12 +879,7 @@ unsigned OperandNo = 0; for (auto CI = Call->data_operands_begin(), CE = Call->data_operands_end(); CI != CE; ++CI, ++OperandNo) { - // Only look at the no-capture or byval pointer arguments. If this - // pointer were passed to arguments that were neither of these, then it - // couldn't be no-capture. - if (!(*CI)->getType()->isPointerTy() || - (!Call->doesNotCapture(OperandNo) && OperandNo < Call->arg_size() && - !Call->isByValArgument(OperandNo))) + if (!(*CI)->getType()->isPointerTy()) continue; // Call doesn't access memory through this operand, so we don't care diff --git a/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll b/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll --- a/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll +++ b/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll @@ -22,11 +22,16 @@ ret i1 0 } -; FIXME: At the moment, the function is incorrectly simplified to unreachable. define i32 @test() { ; CHECK-LABEL: define i32 @test() { ; CHECK-NEXT: entry: -; CHECK-NEXT: unreachable +; CHECK-NEXT: br label [[THEN_I:%.*]] +; CHECK: then.i: +; CHECK-NEXT: [[RES_I:%.*]] = call i1 @cond() +; CHECK-NEXT: br label [[CHECK_COND_EXIT:%.*]] +; CHECK: check_cond.exit: +; CHECK-NEXT: call void @llvm.assume(i1 [[RES_I]]) +; CHECK-NEXT: ret i32 0 ; entry: %a = alloca i32, align 4