Skip to content

Commit

Permalink
[InlineCost] model calls to llvm.objectsize.*
Browse files Browse the repository at this point in the history
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: ClangBuiltLinux/linux#1302

Reviewed By: manojgupta

Differential Revision: https://reviews.llvm.org/D111456
  • Loading branch information
nickdesaulniers committed Jan 24, 2023
1 parent 7532e88 commit f1764d5
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
18 changes: 18 additions & 0 deletions llvm/lib/Analysis/InlineCost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -2214,6 +2230,8 @@ bool CallAnalyzer::visitCallBase(CallBase &Call) {
return true;
case Intrinsic::is_constant:
return simplifyIntrinsicCallIsConstant(Call);
case Intrinsic::objectsize:
return simplifyIntrinsicCallObjectSize(Call);
}
}

Expand Down
50 changes: 50 additions & 0 deletions llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
; RUN: opt -passes=inline -S %s -inline-threshold=20 2>&1 | FileCheck %s

%struct.nodemask_t = type { [16 x i64] }
@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
}

0 comments on commit f1764d5

Please sign in to comment.