Skip to content

Commit 815343e

Browse files
authored
[CGData][Merger] Avoid merging the attached call target (#121030)
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()`.
1 parent 4d8f959 commit 815343e

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

llvm/lib/CodeGen/GlobalMergeFunctions.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,17 @@ static bool canParameterizeCallOperand(const CallBase *CI, unsigned OpIdx) {
6060
if (Name.starts_with("__dtrace"))
6161
return false;
6262
}
63-
if (isCalleeOperand(CI, OpIdx) &&
64-
CI->getOperandBundle(LLVMContext::OB_ptrauth).has_value()) {
63+
if (isCalleeOperand(CI, OpIdx)) {
6564
// The operand is the callee and it has already been signed. Ignore this
6665
// because we cannot add another ptrauth bundle to the call instruction.
67-
return false;
66+
if (CI->getOperandBundle(LLVMContext::OB_ptrauth).has_value())
67+
return false;
68+
} else {
69+
// The target of the arc-attached call must be a constant and cannot be
70+
// parameterized.
71+
if (CI->isOperandBundleOfType(LLVMContext::OB_clang_arc_attachedcall,
72+
OpIdx))
73+
return false;
6874
}
6975
return true;
7076
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; This test verifies that two similar functions, f1 and f2, are not merged
2+
; when their attached call targets differ, since these targets cannot be parameterized.
3+
4+
; RUN: llc -mtriple=arm64-apple-darwin -enable-global-merge-func=true < %s | FileCheck %s
5+
6+
; CHECK-NOT: _f1.Tgm
7+
; CHECK-NOT: _f2.Tgm
8+
9+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
10+
target triple = "arm64-apple-darwin"
11+
12+
define i64 @f1(ptr %0) {
13+
%2 = call ptr @g1(ptr %0, i32 0) minsize [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
14+
tail call void (...) @llvm.objc.clang.arc.noop.use(ptr %2)
15+
%3 = call i64 @g2(ptr %2)
16+
tail call void @objc_release(ptr %2)
17+
%4 = tail call i64 @g3(i64 %3)
18+
ret i64 %4
19+
}
20+
21+
define i64 @f2(ptr %0) {
22+
%2 = call ptr @g1(ptr %0, i32 0) minsize [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
23+
tail call void (...) @llvm.objc.clang.arc.noop.use(ptr %2)
24+
%3 = call i64 @g2(ptr %2)
25+
tail call void @objc_release(ptr %2)
26+
%4 = tail call i64 @g3(i64 %3)
27+
ret i64 %4
28+
}
29+
30+
declare ptr @g1(ptr, i32)
31+
declare i64 @g2(ptr)
32+
declare i64 @g3(i64)
33+
34+
declare void @llvm.objc.clang.arc.noop.use(...)
35+
declare ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr)
36+
declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
37+
declare void @objc_release(ptr)

0 commit comments

Comments
 (0)