1; NOTE: Code has been autogenerated by utils/update_test_body.py 2; REQUIRES: aarch64 3 4; RUN: rm -rf %t && split-file %s %t 5 6; RUN: llc -filetype=obj %t/a.ll -O3 -o %t/a.o -enable-machine-outliner=never -mtriple arm64-apple-macos -addrsig 7; RUN: %lld -arch arm64 -lSystem --icf=safe_thunks -dylib -o %t/a.dylib -map %t/a.map %t/a.o 8; RUN: llvm-objdump %t/a.dylib -d --macho | FileCheck %s --check-prefixes=CHECK-ARM64 9; RUN: cat %t/a.map | FileCheck %s --check-prefixes=CHECK-ARM64-MAP 10 11; CHECK-ARM64: (__TEXT,__text) section 12; CHECK-ARM64-NEXT: _func_unique_1: 13; CHECK-ARM64-NEXT: mov {{.*}}, #0x1 14; 15; CHECK-ARM64: _func_unique_2_canmerge: 16; CHECK-ARM64-NEXT: _func_2identical_v1: 17; CHECK-ARM64-NEXT: mov {{.*}}, #0x2 18; 19; CHECK-ARM64: _func_3identical_v1: 20; CHECK-ARM64-NEXT: mov {{.*}}, #0x3 21; 22; CHECK-ARM64: _func_3identical_v1_canmerge: 23; CHECK-ARM64-NEXT: _func_3identical_v2_canmerge: 24; CHECK-ARM64-NEXT: _func_3identical_v3_canmerge: 25; CHECK-ARM64-NEXT: mov {{.*}}, #0x21 26; 27; CHECK-ARM64: _func_call_thunked_1_nomerge: 28; CHECK-ARM64-NEXT: stp x29 29; 30; CHECK-ARM64: _func_call_thunked_2_nomerge: 31; CHECK-ARM64-NEXT: _func_call_thunked_2_merge: 32; CHECK-ARM64-NEXT: stp x29 33; 34; CHECK-ARM64: _call_all_funcs: 35; CHECK-ARM64-NEXT: stp x29 36; 37; CHECK-ARM64: _take_func_addr: 38; CHECK-ARM64-NEXT: adr 39; 40; CHECK-ARM64: _func_2identical_v2: 41; CHECK-ARM64-NEXT: b _func_2identical_v1 42; CHECK-ARM64-NEXT: _func_3identical_v2: 43; CHECK-ARM64-NEXT: b _func_3identical_v1 44; CHECK-ARM64-NEXT: _func_3identical_v3: 45; CHECK-ARM64-NEXT: b _func_3identical_v1 46 47 48; CHECK-ARM64-MAP: 0x00000010 [ 2] _func_unique_1 49; CHECK-ARM64-MAP-NEXT: 0x00000010 [ 2] _func_2identical_v1 50; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_unique_2_canmerge 51; CHECK-ARM64-MAP-NEXT: 0x00000010 [ 2] _func_3identical_v1 52; CHECK-ARM64-MAP-NEXT: 0x00000010 [ 2] _func_3identical_v1_canmerge 53; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_3identical_v2_canmerge 54; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_3identical_v3_canmerge 55; CHECK-ARM64-MAP-NEXT: 0x00000020 [ 2] _func_call_thunked_1_nomerge 56; CHECK-ARM64-MAP-NEXT: 0x00000020 [ 2] _func_call_thunked_2_nomerge 57; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_call_thunked_2_merge 58; CHECK-ARM64-MAP-NEXT: 0x00000034 [ 2] _call_all_funcs 59; CHECK-ARM64-MAP-NEXT: 0x00000050 [ 2] _take_func_addr 60; CHECK-ARM64-MAP-NEXT: 0x00000004 [ 2] _func_2identical_v2 61; CHECK-ARM64-MAP-NEXT: 0x00000004 [ 2] _func_3identical_v2 62; CHECK-ARM64-MAP-NEXT: 0x00000004 [ 2] _func_3identical_v3 63 64;--- a.cpp 65#define ATTR __attribute__((noinline)) extern "C" 66typedef unsigned long long ULL; 67 68volatile char g_val = 0; 69void *volatile g_ptr = 0; 70 71ATTR void func_unique_1() { g_val = 1; } 72 73ATTR void func_unique_2_canmerge() { g_val = 2; } 74 75ATTR void func_2identical_v1() { g_val = 2; } 76 77ATTR void func_2identical_v2() { g_val = 2; } 78 79ATTR void func_3identical_v1() { g_val = 3; } 80 81ATTR void func_3identical_v2() { g_val = 3; } 82 83ATTR void func_3identical_v3() { g_val = 3; } 84 85ATTR void func_3identical_v1_canmerge() { g_val = 33; } 86 87ATTR void func_3identical_v2_canmerge() { g_val = 33; } 88 89ATTR void func_3identical_v3_canmerge() { g_val = 33; } 90 91ATTR void func_call_thunked_1_nomerge() { 92 func_2identical_v1(); 93 g_val = 77; 94} 95 96ATTR void func_call_thunked_2_nomerge() { 97 func_2identical_v2(); 98 g_val = 77; 99} 100 101ATTR void func_call_thunked_2_merge() { 102 func_2identical_v2(); 103 g_val = 77; 104} 105 106ATTR void call_all_funcs() { 107 func_unique_1(); 108 func_unique_2_canmerge(); 109 func_2identical_v1(); 110 func_2identical_v2(); 111 func_3identical_v1(); 112 func_3identical_v2(); 113 func_3identical_v3(); 114 func_3identical_v1_canmerge(); 115 func_3identical_v2_canmerge(); 116 func_3identical_v3_canmerge(); 117} 118 119ATTR void take_func_addr() { 120 g_ptr = (void*)func_unique_1; 121 g_ptr = (void*)func_2identical_v1; 122 g_ptr = (void*)func_2identical_v2; 123 g_ptr = (void*)func_3identical_v1; 124 g_ptr = (void*)func_3identical_v2; 125 g_ptr = (void*)func_3identical_v3; 126} 127 128;--- gen 129clang -target arm64-apple-macos11.0 -S -emit-llvm a.cpp -O3 -o - 130 131;--- a.ll 132; ModuleID = 'a.cpp' 133source_filename = "a.cpp" 134target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32" 135target triple = "arm64-apple-macosx11.0.0" 136 137@g_val = global i8 0, align 1 138@g_ptr = global ptr null, align 8 139 140; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 141define void @func_unique_1() #0 { 142 store volatile i8 1, ptr @g_val, align 1, !tbaa !4 143 ret void 144} 145 146; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 147define void @func_unique_2_canmerge() local_unnamed_addr #0 { 148 store volatile i8 2, ptr @g_val, align 1, !tbaa !4 149 ret void 150} 151 152; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 153define void @func_2identical_v1() #0 { 154 store volatile i8 2, ptr @g_val, align 1, !tbaa !4 155 ret void 156} 157 158; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 159define void @func_2identical_v2() #0 { 160 store volatile i8 2, ptr @g_val, align 1, !tbaa !4 161 ret void 162} 163 164; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 165define void @func_3identical_v1() #0 { 166 store volatile i8 3, ptr @g_val, align 1, !tbaa !4 167 ret void 168} 169 170; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 171define void @func_3identical_v2() #0 { 172 store volatile i8 3, ptr @g_val, align 1, !tbaa !4 173 ret void 174} 175 176; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 177define void @func_3identical_v3() #0 { 178 store volatile i8 3, ptr @g_val, align 1, !tbaa !4 179 ret void 180} 181 182; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 183define void @func_3identical_v1_canmerge() local_unnamed_addr #0 { 184 store volatile i8 33, ptr @g_val, align 1, !tbaa !4 185 ret void 186} 187 188; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 189define void @func_3identical_v2_canmerge() local_unnamed_addr #0 { 190 store volatile i8 33, ptr @g_val, align 1, !tbaa !4 191 ret void 192} 193 194; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 195define void @func_3identical_v3_canmerge() local_unnamed_addr #0 { 196 store volatile i8 33, ptr @g_val, align 1, !tbaa !4 197 ret void 198} 199 200; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync) 201define void @func_call_thunked_1_nomerge() local_unnamed_addr #1 { 202 tail call void @func_2identical_v1() 203 store volatile i8 77, ptr @g_val, align 1, !tbaa !4 204 ret void 205} 206 207; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync) 208define void @func_call_thunked_2_nomerge() local_unnamed_addr #1 { 209 tail call void @func_2identical_v2() 210 store volatile i8 77, ptr @g_val, align 1, !tbaa !4 211 ret void 212} 213 214; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync) 215define void @func_call_thunked_2_merge() local_unnamed_addr #1 { 216 tail call void @func_2identical_v2() 217 store volatile i8 77, ptr @g_val, align 1, !tbaa !4 218 ret void 219} 220 221; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync) 222define void @call_all_funcs() local_unnamed_addr #1 { 223 tail call void @func_unique_1() 224 tail call void @func_unique_2_canmerge() 225 tail call void @func_2identical_v1() 226 tail call void @func_2identical_v2() 227 tail call void @func_3identical_v1() 228 tail call void @func_3identical_v2() 229 tail call void @func_3identical_v3() 230 tail call void @func_3identical_v1_canmerge() 231 tail call void @func_3identical_v2_canmerge() 232 tail call void @func_3identical_v3_canmerge() 233 ret void 234} 235 236; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) 237define void @take_func_addr() local_unnamed_addr #0 { 238 store volatile ptr @func_unique_1, ptr @g_ptr, align 8, !tbaa !7 239 store volatile ptr @func_2identical_v1, ptr @g_ptr, align 8, !tbaa !7 240 store volatile ptr @func_2identical_v2, ptr @g_ptr, align 8, !tbaa !7 241 store volatile ptr @func_3identical_v1, ptr @g_ptr, align 8, !tbaa !7 242 store volatile ptr @func_3identical_v2, ptr @g_ptr, align 8, !tbaa !7 243 store volatile ptr @func_3identical_v3, ptr @g_ptr, align 8, !tbaa !7 244 ret void 245} 246 247attributes #0 = { mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,+zcm,+zcz" } 248attributes #1 = { mustprogress nofree noinline norecurse nounwind ssp uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,+zcm,+zcz" } 249 250!llvm.module.flags = !{!0, !1, !2, !3} 251 252!0 = !{i32 1, !"wchar_size", i32 4} 253!1 = !{i32 8, !"PIC Level", i32 2} 254!2 = !{i32 7, !"uwtable", i32 1} 255!3 = !{i32 7, !"frame-pointer", i32 1} 256!4 = !{!5, !5, i64 0} 257!5 = !{!"omnipotent char", !6, i64 0} 258!6 = !{!"Simple C++ TBAA"} 259!7 = !{!8, !8, i64 0} 260!8 = !{!"any pointer", !5, i64 0} 261