[llvm] [GlobalOpt] Check if users are CallBase when changing CC (PR #161399)
Hongyu Chen via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 1 01:12:33 PDT 2025
https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/161399
>From 421dbff4940078037fd3d959a846809486ab4203 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Wed, 1 Oct 2025 00:33:54 +0800
Subject: [PATCH 1/3] autogenerate tests
---
llvm/test/Transforms/GlobalOpt/fastcc.ll | 73 ++++++++++++++++++------
1 file changed, 57 insertions(+), 16 deletions(-)
diff --git a/llvm/test/Transforms/GlobalOpt/fastcc.ll b/llvm/test/Transforms/GlobalOpt/fastcc.ll
index 854357e6fad97..bca70f1c2e86f 100644
--- a/llvm/test/Transforms/GlobalOpt/fastcc.ll
+++ b/llvm/test/Transforms/GlobalOpt/fastcc.ll
@@ -1,16 +1,25 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=globalopt -S | FileCheck %s
declare token @llvm.call.preallocated.setup(i32)
declare ptr @llvm.call.preallocated.arg(token, i32)
define internal i32 @f(ptr %m) {
-; CHECK-LABEL: define internal fastcc i32 @f
+; CHECK-LABEL: define internal fastcc i32 @f(
+; CHECK-SAME: ptr [[M:%.*]]) unnamed_addr {
+; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[M]], align 4
+; CHECK-NEXT: ret i32 [[V]]
+;
%v = load i32, ptr %m
ret i32 %v
}
define internal x86_thiscallcc i32 @g(ptr %m) {
-; CHECK-LABEL: define internal fastcc i32 @g
+; CHECK-LABEL: define internal fastcc i32 @g(
+; CHECK-SAME: ptr [[M:%.*]]) unnamed_addr {
+; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[M]], align 4
+; CHECK-NEXT: ret i32 [[V]]
+;
%v = load i32, ptr %m
ret i32 %v
}
@@ -18,41 +27,80 @@ define internal x86_thiscallcc i32 @g(ptr %m) {
; Leave this one alone, because the user went out of their way to request this
; convention.
define internal coldcc i32 @h(ptr %m) {
-; CHECK-LABEL: define internal coldcc i32 @h
+; CHECK-LABEL: define internal coldcc i32 @h(
+; CHECK-SAME: ptr [[M:%.*]]) unnamed_addr {
+; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[M]], align 4
+; CHECK-NEXT: ret i32 [[V]]
+;
%v = load i32, ptr %m
ret i32 %v
}
define internal i32 @j(ptr %m) {
-; CHECK-LABEL: define internal i32 @j
+; CHECK-LABEL: define internal i32 @j(
+; CHECK-SAME: ptr [[M:%.*]]) {
+; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[M]], align 4
+; CHECK-NEXT: ret i32 [[V]]
+;
%v = load i32, ptr %m
ret i32 %v
}
define internal i32 @inalloca(ptr inalloca(i32) %p) {
-; CHECK-LABEL: define internal fastcc i32 @inalloca(ptr %p)
+; CHECK-LABEL: define internal fastcc i32 @inalloca(
+; CHECK-SAME: ptr [[P:%.*]]) unnamed_addr {
+; CHECK-NEXT: [[RV:%.*]] = load i32, ptr [[P]], align 4
+; CHECK-NEXT: ret i32 [[RV]]
+;
%rv = load i32, ptr %p
ret i32 %rv
}
define i32 @inalloca2_caller(ptr inalloca(i32) %p) {
+; CHECK-LABEL: define i32 @inalloca2_caller(
+; CHECK-SAME: ptr inalloca(i32) [[P:%.*]]) local_unnamed_addr {
+; CHECK-NEXT: [[RV:%.*]] = musttail call i32 @inalloca2(ptr inalloca(i32) [[P]])
+; CHECK-NEXT: ret i32 [[RV]]
+;
%rv = musttail call i32 @inalloca2(ptr inalloca(i32) %p)
ret i32 %rv
}
define internal i32 @inalloca2(ptr inalloca(i32) %p) {
; Because of the musttail caller, this inalloca cannot be dropped.
-; CHECK-LABEL: define internal i32 @inalloca2(ptr inalloca(i32) %p)
+; CHECK-LABEL: define internal i32 @inalloca2(
+; CHECK-SAME: ptr inalloca(i32) [[P:%.*]]) unnamed_addr {
+; CHECK-NEXT: [[RV:%.*]] = load i32, ptr [[P]], align 4
+; CHECK-NEXT: ret i32 [[RV]]
+;
%rv = load i32, ptr %p
ret i32 %rv
}
define internal i32 @preallocated(ptr preallocated(i32) %p) {
-; CHECK-LABEL: define internal fastcc i32 @preallocated(ptr %p)
+; CHECK-LABEL: define internal fastcc i32 @preallocated(
+; CHECK-SAME: ptr [[P:%.*]]) unnamed_addr {
+; CHECK-NEXT: [[RV:%.*]] = load i32, ptr [[P]], align 4
+; CHECK-NEXT: ret i32 [[RV]]
+;
%rv = load i32, ptr %p
ret i32 %rv
}
define void @call_things() {
+; CHECK-LABEL: define void @call_things() local_unnamed_addr {
+; CHECK-NEXT: [[M:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP1:%.*]] = call fastcc i32 @f(ptr [[M]])
+; CHECK-NEXT: [[TMP2:%.*]] = call fastcc i32 @g(ptr [[M]])
+; CHECK-NEXT: [[TMP3:%.*]] = call coldcc i32 @h(ptr [[M]])
+; CHECK-NEXT: [[TMP4:%.*]] = call i32 @j(ptr [[M]])
+; CHECK-NEXT: [[ARGS:%.*]] = alloca inalloca i32, align 4
+; CHECK-NEXT: [[TMP5:%.*]] = call fastcc i32 @inalloca(ptr [[ARGS]])
+; CHECK-NEXT: [[TMP6:%.*]] = call ptr @llvm.stacksave.p0()
+; CHECK-NEXT: [[PAARG:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP7:%.*]] = call fastcc i32 @preallocated(ptr [[PAARG]])
+; CHECK-NEXT: call void @llvm.stackrestore.p0(ptr [[TMP6]])
+; CHECK-NEXT: ret void
+;
%m = alloca i32
call i32 @f(ptr %m)
call x86_thiscallcc i32 @g(ptr %m)
@@ -65,15 +113,8 @@ define void @call_things() {
call i32 @preallocated(ptr preallocated(i32) %N) ["preallocated"(token %c)]
ret void
}
-; CHECK-LABEL: define void @call_things()
-; CHECK: call fastcc i32 @f
-; CHECK: call fastcc i32 @g
-; CHECK: call coldcc i32 @h
-; CHECK: call i32 @j
-; CHECK: call fastcc i32 @inalloca(ptr %args)
-; CHECK-NOT: llvm.call.preallocated
-; CHECK: call fastcc i32 @preallocated(ptr %paarg)
@llvm.used = appending global [1 x ptr] [
- ptr @j
+ ptr @j
], section "llvm.metadata"
+
>From 6baf27dc0793945cda872ff7c0bde51bbb3c771a Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Wed, 1 Oct 2025 00:35:39 +0800
Subject: [PATCH 2/3] [GlobalOpt] Check if users are CallBase when changing CC
---
llvm/lib/Transforms/IPO/GlobalOpt.cpp | 6 ++++--
llvm/test/Transforms/GlobalOpt/fastcc.ll | 8 ++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index f88d51f443bcf..c5a13c83ab39b 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1680,7 +1680,8 @@ processGlobal(GlobalValue &GV,
/// FastCC.
static void ChangeCalleesToFastCall(Function *F) {
for (User *U : F->users())
- cast<CallBase>(U)->setCallingConv(CallingConv::Fast);
+ if (auto *Call = dyn_cast<CallBase>(U))
+ Call->setCallingConv(CallingConv::Fast);
}
static AttributeList StripAttr(LLVMContext &C, AttributeList Attrs,
@@ -1779,7 +1780,8 @@ isValidCandidateForColdCC(Function &F,
static void changeCallSitesToColdCC(Function *F) {
for (User *U : F->users())
- cast<CallBase>(U)->setCallingConv(CallingConv::Cold);
+ if (auto *Call = dyn_cast<CallBase>(U))
+ Call->setCallingConv(CallingConv::Cold);
}
// This function iterates over all the call instructions in the input Function
diff --git a/llvm/test/Transforms/GlobalOpt/fastcc.ll b/llvm/test/Transforms/GlobalOpt/fastcc.ll
index bca70f1c2e86f..f63cf64ca2f11 100644
--- a/llvm/test/Transforms/GlobalOpt/fastcc.ll
+++ b/llvm/test/Transforms/GlobalOpt/fastcc.ll
@@ -118,3 +118,11 @@ define void @call_things() {
ptr @j
], section "llvm.metadata"
+define internal i32 @constexpr_self_user() addrspace(1) {
+; CHECK-LABEL: define internal fastcc i32 @constexpr_self_user() addrspace(1) {
+; CHECK-NEXT: [[OBJSIZE:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr addrspacecast (ptr addrspace(1) @constexpr_self_user to ptr), i1 false, i1 false, i1 false)
+; CHECK-NEXT: ret i32 [[OBJSIZE]]
+;
+ %objsize = call i32 @llvm.objectsize.i32.p0(ptr addrspacecast (ptr addrspace(1) @constexpr_self_user to ptr), i1 false, i1 false, i1 false)
+ ret i32 %objsize
+}
>From 05b250a021436eb656d4cf751d6d5ce6bc4e398b Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Wed, 1 Oct 2025 16:11:27 +0800
Subject: [PATCH 3/3] check called operand
---
llvm/lib/Transforms/IPO/GlobalOpt.cpp | 14 +++++++++-----
llvm/test/Transforms/GlobalOpt/fastcc.ll | 9 +++++++++
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index c5a13c83ab39b..99c4982c58b47 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1681,7 +1681,8 @@ processGlobal(GlobalValue &GV,
static void ChangeCalleesToFastCall(Function *F) {
for (User *U : F->users())
if (auto *Call = dyn_cast<CallBase>(U))
- Call->setCallingConv(CallingConv::Fast);
+ if (Call->getCalledOperand() == F)
+ Call->setCallingConv(CallingConv::Fast);
}
static AttributeList StripAttr(LLVMContext &C, AttributeList Attrs,
@@ -1767,10 +1768,12 @@ isValidCandidateForColdCC(Function &F,
return false;
for (User *U : F.users()) {
- CallBase &CB = cast<CallBase>(*U);
- Function *CallerFunc = CB.getParent()->getParent();
+ CallBase *CB = dyn_cast<CallBase>(U);
+ if (!CB || CB->getCalledOperand() != &F)
+ continue;
+ Function *CallerFunc = CB->getParent()->getParent();
BlockFrequencyInfo &CallerBFI = GetBFI(*CallerFunc);
- if (!isColdCallSite(CB, CallerBFI))
+ if (!isColdCallSite(*CB, CallerBFI))
return false;
if (!llvm::is_contained(AllCallsCold, CallerFunc))
return false;
@@ -1781,7 +1784,8 @@ isValidCandidateForColdCC(Function &F,
static void changeCallSitesToColdCC(Function *F) {
for (User *U : F->users())
if (auto *Call = dyn_cast<CallBase>(U))
- Call->setCallingConv(CallingConv::Cold);
+ if (Call->getCalledOperand() == F)
+ Call->setCallingConv(CallingConv::Cold);
}
// This function iterates over all the call instructions in the input Function
diff --git a/llvm/test/Transforms/GlobalOpt/fastcc.ll b/llvm/test/Transforms/GlobalOpt/fastcc.ll
index f63cf64ca2f11..edbd602a97f3b 100644
--- a/llvm/test/Transforms/GlobalOpt/fastcc.ll
+++ b/llvm/test/Transforms/GlobalOpt/fastcc.ll
@@ -118,6 +118,15 @@ define void @call_things() {
ptr @j
], section "llvm.metadata"
+define internal i32 @assume_fastcc() {
+; CHECK-LABEL: define internal fastcc i32 @assume_fastcc() {
+; CHECK-NEXT: [[OBJSIZE:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @assume_fastcc, i1 false, i1 false, i1 false)
+; CHECK-NEXT: ret i32 [[OBJSIZE]]
+;
+ %objsize = call i32 @llvm.objectsize.i32.p0(ptr @assume_fastcc, i1 false, i1 false, i1 false)
+ ret i32 %objsize
+}
+
define internal i32 @constexpr_self_user() addrspace(1) {
; CHECK-LABEL: define internal fastcc i32 @constexpr_self_user() addrspace(1) {
; CHECK-NEXT: [[OBJSIZE:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr addrspacecast (ptr addrspace(1) @constexpr_self_user to ptr), i1 false, i1 false, i1 false)
More information about the llvm-commits
mailing list