Skip to content

Commit c0de28b

Browse files
committed
[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
1 parent 81e3779 commit c0de28b

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -864,9 +864,11 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
864864
if (!AI->isStaticAlloca() && isIntrinsicCall(Call, Intrinsic::stackrestore))
865865
return ModRefInfo::Mod;
866866

867-
// If the pointer is to a locally allocated object that does not escape,
868-
// then the call can not mod/ref the pointer unless the call takes the pointer
869-
// as an argument, and itself doesn't capture it.
867+
// A call can access a locally allocated object either because it is passed as
868+
// an argument to the call, or because it has escaped prior to the call.
869+
//
870+
// Make sure the object has not escaped here, and then check that none of the
871+
// call arguments alias the object below.
870872
if (!isa<Constant>(Object) && Call != Object &&
871873
AAQI.CI->isNotCapturedBeforeOrAt(Object, Call)) {
872874

@@ -877,12 +879,7 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
877879
unsigned OperandNo = 0;
878880
for (auto CI = Call->data_operands_begin(), CE = Call->data_operands_end();
879881
CI != CE; ++CI, ++OperandNo) {
880-
// Only look at the no-capture or byval pointer arguments. If this
881-
// pointer were passed to arguments that were neither of these, then it
882-
// couldn't be no-capture.
883-
if (!(*CI)->getType()->isPointerTy() ||
884-
(!Call->doesNotCapture(OperandNo) && OperandNo < Call->arg_size() &&
885-
!Call->isByValArgument(OperandNo)))
882+
if (!(*CI)->getType()->isPointerTy())
886883
continue;
887884

888885
// Call doesn't access memory through this operand, so we don't care

llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@ else:
2222
ret i1 0
2323
}
2424

25-
; FIXME: At the moment, the function is incorrectly simplified to unreachable.
2625
define i32 @test() {
2726
; CHECK-LABEL: define i32 @test() {
2827
; CHECK-NEXT: entry:
29-
; CHECK-NEXT: unreachable
28+
; CHECK-NEXT: br label [[THEN_I:%.*]]
29+
; CHECK: then.i:
30+
; CHECK-NEXT: [[RES_I:%.*]] = call i1 @cond()
31+
; CHECK-NEXT: br label [[CHECK_COND_EXIT:%.*]]
32+
; CHECK: check_cond.exit:
33+
; CHECK-NEXT: call void @llvm.assume(i1 [[RES_I]])
34+
; CHECK-NEXT: ret i32 0
3035
;
3136
entry:
3237
%a = alloca i32, align 4

0 commit comments

Comments
 (0)