Skip to content

Commit 7d2d4f6

Browse files
authored
[PtrAuth] Add ConstantPtrAuth comparator to FunctionComparator.cpp (#159480)
When building rustc std for arm64e, core fails to compile successfully with the error: ``` Constant ValueID not recognized. UNREACHABLE executed at rust/src/llvm-project/llvm/lib/Transforms/Utils/FunctionComparator.cpp:523! ``` This is a result of function merging so I modified FunctionComparator.cpp as the ConstantPtrAuth value would go unchecked in the switch statement. The test case is a reduction from the failure in core and fails on main with: ``` ******************** FAIL: LLVM :: Transforms/MergeFunc/ptrauth-const-compare.ll (59809 of 59995) ******************** TEST 'LLVM :: Transforms/MergeFunc/ptrauth-const-compare.ll' FAILED ******************** Exit Code: 2 Command Output (stdout): -- # RUN: at line 3 /Users/oskarwirga/llvm-project/build/bin/opt -S -passes=mergefunc < /Users/oskarwirga/llvm-project/llvm/test/Transforms/MergeFunc/ptrauth-const-compare.ll | /Users/oskarwirga/llvm-project/build/bin/FileCheck /Users/oskarwirga/llvm-project/llvm/test/Transforms/MergeFunc/ptrauth-const-compare.ll # executed command: /Users/oskarwirga/llvm-project/build/bin/opt -S -passes=mergefunc # .---command stderr------------ # | Constant ValueID not recognized. # | UNREACHABLE executed at /Users/oskarwirga/llvm-project/llvm/lib/Transforms/Utils/FunctionComparator.cpp:523! # | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug. # | Stack dump: # | 0. Program arguments: /Users/oskarwirga/llvm-project/build/bin/opt -S -passes=mergefunc # | 1. Running pass "mergefunc" on module "<stdin>" # | #0 0x0000000103335770 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/Users/oskarwirga/llvm-project/build/bin/opt+0x102651770) # | #1 0x00000001033336bc llvm::sys::RunSignalHandlers() (/Users/oskarwirga/llvm-project/build/bin/opt+0x10264f6bc) # | #2 0x0000000103336218 SignalHandler(int, __siginfo*, void*) (/Users/oskarwirga/llvm-project/build/bin/opt+0x102652218) # | #3 0x000000018e6c16a4 (/usr/lib/system/libsystem_platform.dylib+0x1804ad6a4) # | #4 0x000000018e68788c (/usr/lib/system/libsystem_pthread.dylib+0x18047388c) # | #5 0x000000018e590a3c (/usr/lib/system/libsystem_c.dylib+0x18037ca3c) # | #6 0x00000001032a84bc llvm::install_out_of_memory_new_handler() (/Users/oskarwirga/llvm-project/build/bin/opt+0x1025c44bc) # | #7 0x00000001033b37c0 llvm::FunctionComparator::cmpMDNode(llvm::MDNode const*, llvm::MDNode const*) const (/Users/oskarwirga/llvm-project/build/bin/opt+0x1026cf7c0) # | #8 0x00000001033b4d90 llvm::FunctionComparator::cmpBasicBlocks(llvm::BasicBlock const*, llvm::BasicBlock const*) const (/Users/oskarwirga/llvm-project/build/bin/opt+0x1026d0d90) # | #9 0x00000001033b5234 llvm::FunctionComparator::compare() (/Users/oskarwirga/llvm-project/build/bin/opt+0x1026d1234) # | #10 0x0000000102d6d868 (anonymous namespace)::MergeFunctions::insert(llvm::Function*) (/Users/oskarwirga/llvm-project/build/bin/opt+0x102089868) # | #11 0x0000000102d6bc0c llvm::MergeFunctionsPass::runOnModule(llvm::Module&) (/Users/oskarwirga/llvm-project/build/bin/opt+0x102087c0c) # | #12 0x0000000102d6b430 llvm::MergeFunctionsPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/Users/oskarwirga/llvm-project/build/bin/opt+0x102087430) # | #13 0x0000000102b90558 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/Users/oskarwirga/llvm-project/build/bin/opt+0x101eac558) # | #14 0x0000000103734bc4 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::__1::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool, bool) (/Users/oskarwirga/llvm-project/build/bin/opt+0x102a50bc4) # | #15 0x000000010373cc28 optMain (/Users/oskarwirga/llvm-project/build/bin/opt+0x102a58c28) # | #16 0x000000018e2e6b98 # `----------------------------- # error: command failed with exit status: -6 # executed command: /Users/oskarwirga/llvm-project/build/bin/FileCheck /Users/oskarwirga/llvm-project/llvm/test/Transforms/MergeFunc/ptrauth-const-compare.ll # .---command stderr------------ # | FileCheck error: '<stdin>' is empty. # | FileCheck command line: /Users/oskarwirga/llvm-project/build/bin/FileCheck /Users/oskarwirga/llvm-project/llvm/test/Transforms/MergeFunc/ptrauth-const-compare.ll # `----------------------------- # error: command failed with exit status: 2 ```
1 parent 5678c93 commit 7d2d4f6

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed

llvm/lib/Transforms/Utils/FunctionComparator.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,20 @@ int FunctionComparator::cmpConstants(const Constant *L,
518518
const auto *REquiv = cast<DSOLocalEquivalent>(R);
519519
return cmpGlobalValues(LEquiv->getGlobalValue(), REquiv->getGlobalValue());
520520
}
521+
case Value::ConstantPtrAuthVal: {
522+
// Handle authenticated pointer constants produced by ConstantPtrAuth::get.
523+
const ConstantPtrAuth *LPA = cast<ConstantPtrAuth>(L);
524+
const ConstantPtrAuth *RPA = cast<ConstantPtrAuth>(R);
525+
if (int Res = cmpConstants(LPA->getPointer(), RPA->getPointer()))
526+
return Res;
527+
if (int Res = cmpConstants(LPA->getKey(), RPA->getKey()))
528+
return Res;
529+
if (int Res =
530+
cmpConstants(LPA->getDiscriminator(), RPA->getDiscriminator()))
531+
return Res;
532+
return cmpConstants(LPA->getAddrDiscriminator(),
533+
RPA->getAddrDiscriminator());
534+
}
521535
default: // Unknown constant, abort.
522536
LLVM_DEBUG(dbgs() << "Looking at valueID " << L->getValueID() << "\n");
523537
llvm_unreachable("Constant ValueID not recognized.");
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
2+
; RUN: opt -passes=mergefunc -S < %s | FileCheck %s
3+
; Ensure MergeFunc handles ConstantPtrAuth correctly and does not
4+
; merge when any ptrauth operand differs (ptr, key, int disc, addr disc).
5+
; Each pair of functions differs only in a single ptrauth component but shares
6+
; the same return value, so disabling any single comparison would cause a
7+
; test failure due to unexpected merging.
8+
9+
target triple = "arm64e-apple-ios14.0.0"
10+
11+
declare void @baz()
12+
@ADDR = external global i8
13+
14+
declare void @callee(ptr)
15+
16+
; different base pointer (null vs @baz)
17+
18+
define i32 @f_ptr_null() {
19+
; CHECK-LABEL: define i32 @f_ptr_null() {
20+
; CHECK-NEXT: [[ENTRY:.*:]]
21+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr null, i32 0))
22+
; CHECK-NEXT: ret i32 1
23+
;
24+
entry:
25+
call void @callee(ptr ptrauth (ptr null, i32 0))
26+
ret i32 1
27+
}
28+
29+
define i32 @g_ptr_baz() {
30+
; CHECK-LABEL: define i32 @g_ptr_baz() {
31+
; CHECK-NEXT: [[ENTRY:.*:]]
32+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr @baz, i32 0))
33+
; CHECK-NEXT: ret i32 1
34+
;
35+
entry:
36+
call void @callee(ptr ptrauth (ptr @baz, i32 0))
37+
ret i32 1
38+
}
39+
40+
; different key (i32 0 vs i32 1)
41+
42+
define i32 @f_key0() {
43+
; CHECK-LABEL: define i32 @f_key0() {
44+
; CHECK-NEXT: [[ENTRY:.*:]]
45+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr @baz, i32 0))
46+
; CHECK-NEXT: ret i32 2
47+
;
48+
entry:
49+
call void @callee(ptr ptrauth (ptr @baz, i32 0))
50+
ret i32 2
51+
}
52+
53+
define i32 @g_key1() {
54+
; CHECK-LABEL: define i32 @g_key1() {
55+
; CHECK-NEXT: [[ENTRY:.*:]]
56+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr @baz, i32 1))
57+
; CHECK-NEXT: ret i32 2
58+
;
59+
entry:
60+
call void @callee(ptr ptrauth (ptr @baz, i32 1))
61+
ret i32 2
62+
}
63+
64+
; different integer disc (i64 0 vs i64 7)
65+
66+
define i32 @f_disc0() {
67+
; CHECK-LABEL: define i32 @f_disc0() {
68+
; CHECK-NEXT: [[ENTRY:.*:]]
69+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr @baz, i32 0))
70+
; CHECK-NEXT: ret i32 3
71+
;
72+
entry:
73+
call void @callee(ptr ptrauth (ptr @baz, i32 0))
74+
ret i32 3
75+
}
76+
77+
define i32 @g_disc7() {
78+
; CHECK-LABEL: define i32 @g_disc7() {
79+
; CHECK-NEXT: [[ENTRY:.*:]]
80+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr @baz, i32 0, i64 7))
81+
; CHECK-NEXT: ret i32 3
82+
;
83+
entry:
84+
call void @callee(ptr ptrauth (ptr @baz, i32 0, i64 7))
85+
ret i32 3
86+
}
87+
88+
; different addr disc (ptr null vs @ADDR)
89+
90+
define i32 @f_addr_null() {
91+
; CHECK-LABEL: define i32 @f_addr_null() {
92+
; CHECK-NEXT: [[ENTRY:.*:]]
93+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr @baz, i32 0))
94+
; CHECK-NEXT: ret i32 4
95+
;
96+
entry:
97+
call void @callee(ptr ptrauth (ptr @baz, i32 0))
98+
ret i32 4
99+
}
100+
101+
define i32 @g_addr_ADDR() {
102+
; CHECK-LABEL: define i32 @g_addr_ADDR() {
103+
; CHECK-NEXT: [[ENTRY:.*:]]
104+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr @baz, i32 0, i64 0, ptr @ADDR))
105+
; CHECK-NEXT: ret i32 4
106+
;
107+
entry:
108+
call void @callee(ptr ptrauth (ptr @baz, i32 0, i64 0, ptr @ADDR))
109+
ret i32 4
110+
}
111+
112+
; positive test: identical ptrauth operands, should be merged
113+
114+
define void @merge_ptrauth_a() {
115+
; CHECK-LABEL: define void @merge_ptrauth_a() {
116+
; CHECK-NEXT: [[ENTRY:.*:]]
117+
; CHECK-NEXT: call void @callee(ptr ptrauth (ptr @baz, i32 0, i64 0, ptr @ADDR))
118+
; CHECK-NEXT: ret void
119+
;
120+
entry:
121+
call void @callee(ptr ptrauth (ptr @baz, i32 0, i64 0, ptr @ADDR))
122+
ret void
123+
}
124+
125+
define void @merge_ptrauth_b() {
126+
; CHECK-LABEL: define void @merge_ptrauth_b() {
127+
; CHECK-NEXT: tail call void @merge_ptrauth_a()
128+
; CHECK-NEXT: ret void
129+
;
130+
entry:
131+
call void @callee(ptr ptrauth (ptr @baz, i32 0, i64 0, ptr @ADDR))
132+
ret void
133+
}

0 commit comments

Comments
 (0)