[InlineCost] isKnownNonNullInCallee - handle also dereferenceable attribute
authorDávid Bolvanský <david.bolvansky@gmail.com>
Thu, 6 Apr 2023 08:02:38 +0000 (10:02 +0200)
committerDávid Bolvanský <david.bolvansky@gmail.com>
Thu, 6 Apr 2023 14:51:28 +0000 (16:51 +0200)
llvm/lib/Analysis/InlineCost.cpp
llvm/test/Transforms/Inline/nonnull.ll

index 6877e44..1eb4f2e 100644 (file)
@@ -1732,7 +1732,7 @@ bool CallAnalyzer::isKnownNonNullInCallee(Value *V) {
   // parameter attribute, but that's a less interesting case because hopefully
   // the callee would already have been simplified based on that.
   if (Argument *A = dyn_cast<Argument>(V))
-    if (paramHasAttr(A, Attribute::NonNull))
+    if (paramHasAttr(A, Attribute::NonNull) || paramHasAttr(A, Attribute::Dereferenceable))
       return true;
 
   // Is this an alloca in the caller?  This is distinct from the attribute case
index 5f8af7f..658ae47 100644 (file)
@@ -99,10 +99,11 @@ define void @caller3(ptr %arg) {
   ret void
 }
 
+; Positive test - arg is known non null
 define void @caller4(ptr dereferenceable(8) %arg) {
 ; CHECK-LABEL: define void @caller4
 ; CHECK-SAME: (ptr dereferenceable(8) [[ARG:%.*]]) {
-; CHECK-NEXT:    call void @callee(ptr dereferenceable(8) [[ARG]])
+; CHECK-NEXT:    call void @bar()
 ; CHECK-NEXT:    ret void
 ;
   call void @callee(ptr dereferenceable(8) %arg)
@@ -122,7 +123,24 @@ define void @caller5(ptr dereferenceable(8) %arg) {
 define void @caller6(ptr %arg) {
 ; CHECK-LABEL: define void @caller6
 ; CHECK-SAME: (ptr [[ARG:%.*]]) {
-; CHECK-NEXT:    call void @callee(ptr dereferenceable(8) [[ARG]])
+; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq ptr [[ARG]], null
+; CHECK-NEXT:    br i1 [[CMP_I]], label [[EXPENSIVE_I:%.*]], label [[DONE_I:%.*]]
+; CHECK:       expensive.i:
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    call void @foo()
+; CHECK-NEXT:    br label [[CALLEE_EXIT:%.*]]
+; CHECK:       done.i:
+; CHECK-NEXT:    call void @bar()
+; CHECK-NEXT:    br label [[CALLEE_EXIT]]
+; CHECK:       callee.exit:
 ; CHECK-NEXT:    ret void
 ;
   call void @callee(ptr dereferenceable(8) %arg)