[llvm] f1764d5 - [InlineCost] model calls to llvm.objectsize.*

Nick Desaulniers via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 24 15:10:07 PST 2023


Author: Nick Desaulniers
Date: 2023-01-24T15:09:57-08:00
New Revision: f1764d5b594ff6edbf8d17d196eb0b7a653ac0fc

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

LOG: [InlineCost] model calls to llvm.objectsize.*

Very similar to https://reviews.llvm.org/D111272. We very often can
evaluate calls to llvm.objectsize.* regardless of inlining. Don't count
calls to llvm.objectsize.* against the InlineCost when we can evaluate
the call to a constant.

Link: https://github.com/ClangBuiltLinux/linux/issues/1302

Reviewed By: manojgupta

Differential Revision: https://reviews.llvm.org/D111456

Added: 
    llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll

Modified: 
    llvm/lib/Analysis/InlineCost.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index bce71b26d5386..5bcc8a2f384ad 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/InstructionSimplify.h"
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/Analysis/ProfileSummaryInfo.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
@@ -419,6 +420,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
   bool simplifyCallSite(Function *F, CallBase &Call);
   bool simplifyInstruction(Instruction &I);
   bool simplifyIntrinsicCallIsConstant(CallBase &CB);
+  bool simplifyIntrinsicCallObjectSize(CallBase &CB);
   ConstantInt *stripAndComputeInBoundsConstantOffsets(Value *&V);
 
   /// Return true if the given argument to the function being considered for
@@ -1602,6 +1604,20 @@ bool CallAnalyzer::simplifyIntrinsicCallIsConstant(CallBase &CB) {
   return true;
 }
 
+bool CallAnalyzer::simplifyIntrinsicCallObjectSize(CallBase &CB) {
+  // As per the langref, "The fourth argument to llvm.objectsize determines if
+  // the value should be evaluated at runtime."
+  if(cast<ConstantInt>(CB.getArgOperand(3))->isOne())
+    return false;
+
+  Value *V = lowerObjectSizeCall(&cast<IntrinsicInst>(CB), DL, nullptr,
+                                 /*MustSucceed=*/true);
+  Constant *C = dyn_cast_or_null<Constant>(V);
+  if (C)
+    SimplifiedValues[&CB] = C;
+  return C;
+}
+
 bool CallAnalyzer::visitBitCast(BitCastInst &I) {
   // Propagate constants through bitcasts.
   if (simplifyInstruction(I))
@@ -2214,6 +2230,8 @@ bool CallAnalyzer::visitCallBase(CallBase &Call) {
       return true;
     case Intrinsic::is_constant:
       return simplifyIntrinsicCallIsConstant(Call);
+    case Intrinsic::objectsize:
+      return simplifyIntrinsicCallObjectSize(Call);
     }
   }
 

diff  --git a/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll b/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll
new file mode 100644
index 0000000000000..bdbbb101268e5
--- /dev/null
+++ b/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll
@@ -0,0 +1,50 @@
+; RUN: opt -passes=inline -S %s -inline-threshold=20 2>&1 | FileCheck %s
+
+%struct.nodemask_t = type { [16 x i64] }
+ at numa_nodes_parsed = external constant %struct.nodemask_t, align 8
+
+declare void @foo()
+declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg)
+
+; Test that we inline @callee into @caller.
+define i64 @caller() {
+; CHECK-LABEL: @caller(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false)
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 128
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[CALLEE_EXIT:.*]], label %[[HANDLER_TYPE_MISMATCH94_I:.*]]
+; CHECK:       [[HANDLER_TYPE_MISMATCH94_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:    br label %[[CALLEE_EXIT]]
+; CHECK:       [[CALLEE_EXIT]]:
+; CHECK-NEXT:    ret i64 [[TMP1]]
+;
+  %1 = tail call i64 @callee()
+  ret i64 %1
+}
+
+; Testing the InlineCost of the call to @llvm.objectsize.i64.p0i8.
+; Do not change the linkage of @callee; that will give it a severe discount in
+; cost (LastCallToStaticBonus).
+define i64 @callee() {
+  %1 = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false)
+  %2 = icmp uge i64 %1, 128
+  br i1 %2, label %cont95, label %handler.type_mismatch94
+
+handler.type_mismatch94:
+  call void @foo()
+  call void @foo()
+  call void @foo()
+  call void @foo()
+  call void @foo()
+  call void @foo()
+  br label %cont95
+
+cont95:
+  ret i64 %1
+}
+


        


More information about the llvm-commits mailing list