[llvm] c0de28b - [BasicAA] Don't short-circuit non-capturing arguments

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 26 03:27:40 PDT 2023


Author: Nikita Popov
Date: 2023-06-26T12:27:32+02:00
New Revision: c0de28b92e98acbeb739eae8a4d762aec77f2705

URL: https://github.com/llvm/llvm-project/commit/c0de28b92e98acbeb739eae8a4d762aec77f2705
DIFF: https://github.com/llvm/llvm-project/commit/c0de28b92e98acbeb739eae8a4d762aec77f2705.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/Analysis/BasicAliasAnalysis.cpp
    llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 5093166b59003..ec523748e974d 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -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

diff  --git a/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll b/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll
index aed2282265bca..1297dbe795834 100644
--- a/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll
+++ b/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll
@@ -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


        


More information about the llvm-commits mailing list