-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[CGData][Merger] Avoid merging the attached call target #121030
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
For function merging, the target of the arc-attached call must be a constant and cannot be parameterized. This change adds a check to bypass this case in `canParameterizeCallOperand()`.
cc. @nocchijiang |
@llvm/pr-subscribers-backend-aarch64 Author: Kyungwoo Lee (kyulee-com) ChangesFor global function merging, the target of the arc-attached call must be a constant and cannot be parameterized. Full diff: https://github.com/llvm/llvm-project/pull/121030.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/GlobalMergeFunctions.cpp b/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
index c8f1b98c9a18e9..b5863e0551b78c 100644
--- a/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
+++ b/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
@@ -60,11 +60,17 @@ static bool canParameterizeCallOperand(const CallBase *CI, unsigned OpIdx) {
if (Name.starts_with("__dtrace"))
return false;
}
- if (isCalleeOperand(CI, OpIdx) &&
- CI->getOperandBundle(LLVMContext::OB_ptrauth).has_value()) {
+ if (isCalleeOperand(CI, OpIdx)) {
// The operand is the callee and it has already been signed. Ignore this
// because we cannot add another ptrauth bundle to the call instruction.
- return false;
+ if (CI->getOperandBundle(LLVMContext::OB_ptrauth).has_value())
+ return false;
+ } else {
+ // The target of the arc-attached call must be a constant and cannot be
+ // parameterized.
+ if (CI->isOperandBundleOfType(llvm::LLVMContext::OB_clang_arc_attachedcall,
+ OpIdx))
+ return false;
}
return true;
}
diff --git a/llvm/test/CodeGen/AArch64/cgdata-no-merge-attached-call-garget.ll b/llvm/test/CodeGen/AArch64/cgdata-no-merge-attached-call-garget.ll
new file mode 100644
index 00000000000000..1163314062df1b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cgdata-no-merge-attached-call-garget.ll
@@ -0,0 +1,37 @@
+; This test verifies that two similar functions, f1 and f2, are not merged
+; when their attached call targets differ, since these targets cannot be parameterized.
+
+; RUN: llc -mtriple=arm64-apple-darwin -enable-global-merge-func=true < %s | FileCheck %s
+
+; CHECK-NOT: _f1.Tgm
+; CHECK-NOT: _f2.Tgm
+
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "arm64-apple-darwin"
+
+define i64 @f1(ptr %0) {
+ %2 = call ptr @g1(ptr %0, i32 0) minsize [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
+ tail call void (...) @llvm.objc.clang.arc.noop.use(ptr %2)
+ %3 = call i64 @g2(ptr %2)
+ tail call void @objc_release(ptr %2)
+ %4 = tail call i64 @g3(i64 %3)
+ ret i64 %4
+}
+
+define i64 @f2(ptr %0) {
+ %2 = call ptr @g1(ptr %0, i32 0) minsize [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+ tail call void (...) @llvm.objc.clang.arc.noop.use(ptr %2)
+ %3 = call i64 @g2(ptr %2)
+ tail call void @objc_release(ptr %2)
+ %4 = tail call i64 @g3(i64 %3)
+ ret i64 %4
+}
+
+declare ptr @g1(ptr, i32)
+declare i64 @g2(ptr)
+declare i64 @g3(i64)
+
+declare void @llvm.objc.clang.arc.noop.use(...)
+declare ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr)
+declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
+declare void @objc_release(ptr)
|
} else { | ||
// The target of the arc-attached call must be a constant and cannot be | ||
// parameterized. | ||
if (CI->isOperandBundleOfType(llvm::LLVMContext::OB_clang_arc_attachedcall, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (CI->isOperandBundleOfType(llvm::LLVMContext::OB_clang_arc_attachedcall, | |
if (CI->isOperandBundleOfType(LLVMContext::OB_clang_arc_attachedcall, |
to be consistent with CI->getOperandBundle(LLVMContext::OB_ptrauth)
above.
if (CI->getOperandBundle(LLVMContext::OB_ptrauth).has_value()) | ||
return false; | ||
} else { | ||
// The target of the arc-attached call must be a constant and cannot be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a general method to determine whether a bundle is unsafe to optimize? If so, we can avoid enumerating all of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not familiar with the bundle. Conservatively, we could bail out all bundle cases, but for now I bail out the known case only. I think if we run into invalid cases, the compilation will fail/crash so we can follow up.
Any other comments? This is relatively a straightforward fix to unblock compiler crash. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but hope that someone else with commit access to review & approve before merging.
@ellishg @thevinster Do you have any comments? |
For global function merging, the target of the arc-attached call must be a constant and cannot be parameterized.
This change adds a check to bypass this case in
canParameterizeCallOperand()
.