[BasicAA] Don't short-circuit non-capturing arguments
This is an alternative to D153464. BasicAA currently assumes that an unescaped alloca cannot be read through non-nocapture arguments of a call, based on the argument that if the argument were based on the alloca, it would not be unescaped. This currently fails in the case where the call is an ephemeral value and as such does not count as a capture. It also happens for calls that are readonly+nounwind+void, though that case tends to not matter in practice, because such calls will get DCEd anyway. Differential Revision: https://reviews.llvm.org/D153511
This commit is contained in:
1 parent
81e3779a13
commit
c0de28b92e
2 files changed
+13
-11
No files matched your search
@@ -864,9 +864,11 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
|
||||
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<Constant>(Object) && Call != Object &&
|
||||
AAQI.CI->isNotCapturedBeforeOrAt(Object, Call)) {
|
||||
|
||||
@@ -877,12 +879,7 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
|
||||
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
|
||||
|
||||
@@ -22,11 +22,16 @@ else:
|
||||
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
|
||||
|
||||
Reference in new issue
Block a user