-
Notifications
You must be signed in to change notification settings - Fork 745
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NFC][lld-macho] Generate test bodies for icf-safe-thunk tests (#111927)
Autogenerate `.ll` code from cpp code in some `-icf-safe-thunk` tests using `update_test_body.py` ``` PATH=build/bin:$PATH llvm/utils/update_test_body.py lld/test/MachO/icf-safe-thunks.ll lld/test/MachO/icf-safe-thunks-dwarf.ll ``` https://llvm.org/docs/TestingGuide.html#elaborated-tests I recently became aware of this tool and I wanted to practice using it. This also allows to remove the custom instructions to generate the `.ll` code.
- Loading branch information
Showing
2 changed files
with
177 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,115 +1,104 @@ | ||
; NOTE: Code has been autogenerated by utils/update_test_body.py | ||
; REQUIRES: aarch64 | ||
|
||
;;; Build the | ||
; RUN: rm -rf %t; mkdir %t | ||
; RUN: llc -filetype=obj %s -O3 -o %t/icf-obj-safe-thunks-dwarf.o -enable-machine-outliner=never -mtriple arm64-apple-macos -addrsig | ||
; RUN: %lld -arch arm64 -lSystem --icf=safe_thunks -dylib -o %t/icf-safe-dwarf.dylib %t/icf-obj-safe-thunks-dwarf.o | ||
; RUN: rm -rf %t && split-file %s %t | ||
|
||
; RUN: llc -filetype=obj %t/a.ll -O3 -o %t/a.o -enable-machine-outliner=never -mtriple arm64-apple-macos -addrsig | ||
; RUN: %lld -arch arm64 -lSystem --icf=safe_thunks -dylib -o %t/a.dylib %t/a.o | ||
|
||
;;; Check that we generate valid dSYM | ||
; RUN: dsymutil %t/icf-safe-dwarf.dylib -o %t/icf-safe.dSYM | ||
; RUN: llvm-dwarfdump --verify %t/icf-safe.dSYM | FileCheck %s --check-prefix=VERIFY-DSYM | ||
; RUN: dsymutil %t/a.dylib -o %t/a.dSYM | ||
; RUN: llvm-dwarfdump --verify %t/a.dSYM | FileCheck %s --check-prefix=VERIFY-DSYM | ||
; VERIFY-DSYM: No errors. | ||
|
||
;;; Check that we don't generate STABS entries (N_FUN) for ICF'ed function thunks | ||
; RUN: dsymutil -s %t/icf-safe-dwarf.dylib | FileCheck %s --check-prefix=VERIFY-STABS | ||
; RUN: dsymutil -s %t/a.dylib | FileCheck %s --check-prefix=VERIFY-STABS | ||
; VERIFY-STABS-NOT: N_FUN{{.*}}_func_B | ||
; VERIFY-STABS-NOT: N_FUN{{.*}}_func_C | ||
|
||
;;; Check that we do generate STABS entries (N_FUN) for non-ICF'ed functions | ||
; VERIFY-STABS: N_FUN{{.*}}_func_A | ||
; VERIFY-STABS: N_FUN{{.*}}_take_func_addr | ||
|
||
;--- a.cpp | ||
#define ATTR __attribute__((noinline)) extern "C" | ||
typedef unsigned long long ULL; | ||
|
||
ATTR int func_A() { return 1; } | ||
ATTR int func_B() { return 1; } | ||
ATTR int func_C() { return 1; } | ||
|
||
ATTR ULL take_func_addr() { | ||
ULL val = 0; | ||
val += (ULL)(void*)func_A; | ||
val += (ULL)(void*)func_B; | ||
val += (ULL)(void*)func_C; | ||
return val; | ||
} | ||
|
||
;--- gen | ||
clang -target arm64-apple-macos11.0 -S -emit-llvm a.cpp -O3 -g -o - | ||
|
||
; ModuleID = 'icf-safe-thunks-dwarf.cpp' | ||
source_filename = "icf-safe-thunks-dwarf.cpp" | ||
;--- a.ll | ||
; ModuleID = 'a.cpp' | ||
source_filename = "a.cpp" | ||
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32" | ||
target triple = "arm64-apple-macosx11.0.0" | ||
|
||
; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync) | ||
define i32 @func_A() #0 !dbg !13 { | ||
entry: | ||
ret i32 1 | ||
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind ssp willreturn memory(none) uwtable(sync) | ||
define noundef i32 @func_A() #0 !dbg !12 { | ||
ret i32 1, !dbg !16 | ||
} | ||
|
||
; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync) | ||
define i32 @func_B() #0 !dbg !18 { | ||
entry: | ||
ret i32 1 | ||
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind ssp willreturn memory(none) uwtable(sync) | ||
define noundef i32 @func_B() #0 !dbg !17 { | ||
ret i32 1, !dbg !18 | ||
} | ||
|
||
; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync) | ||
define i32 @func_C() #0 !dbg !20 { | ||
entry: | ||
ret i32 1 | ||
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind ssp willreturn memory(none) uwtable(sync) | ||
define noundef i32 @func_C() #0 !dbg !19 { | ||
ret i32 1, !dbg !20 | ||
} | ||
|
||
; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync) | ||
define i64 @take_func_addr() #0 !dbg !22 { | ||
entry: | ||
%val = alloca i64, align 8 | ||
store i64 0, ptr %val, align 8 | ||
%0 = load i64, ptr %val, align 8 | ||
%add = add i64 %0, ptrtoint (ptr @func_A to i64) | ||
store i64 %add, ptr %val, align 8 | ||
%1 = load i64, ptr %val, align 8 | ||
%add1 = add i64 %1, ptrtoint (ptr @func_B to i64) | ||
store i64 %add1, ptr %val, align 8 | ||
%2 = load i64, ptr %val, align 8 | ||
%add2 = add i64 %2, ptrtoint (ptr @func_C to i64) | ||
store i64 %add2, ptr %val, align 8 | ||
%3 = load i64, ptr %val, align 8 | ||
ret i64 %3 | ||
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind ssp willreturn memory(none) uwtable(sync) | ||
define noundef i64 @take_func_addr() local_unnamed_addr #0 !dbg !21 { | ||
#dbg_value(i64 0, !25, !DIExpression(), !26) | ||
#dbg_value(i64 ptrtoint (ptr @func_A to i64), !25, !DIExpression(), !26) | ||
#dbg_value(i64 add (i64 ptrtoint (ptr @func_A to i64), i64 ptrtoint (ptr @func_B to i64)), !25, !DIExpression(), !26) | ||
#dbg_value(i64 add (i64 add (i64 ptrtoint (ptr @func_A to i64), i64 ptrtoint (ptr @func_B to i64)), i64 ptrtoint (ptr @func_C to i64)), !25, !DIExpression(), !26) | ||
ret i64 add (i64 add (i64 ptrtoint (ptr @func_A to i64), i64 ptrtoint (ptr @func_B to i64)), i64 ptrtoint (ptr @func_C to i64)), !dbg !27 | ||
} | ||
|
||
attributes #0 = { noinline nounwind } | ||
attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind ssp willreturn memory(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" } | ||
|
||
!llvm.dbg.cu = !{!0} | ||
!llvm.module.flags = !{!6, !7, !8, !9, !10, !11} | ||
!llvm.ident = !{!12} | ||
|
||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") | ||
!1 = !DIFile(filename: "icf-safe-thunks-dwarf.cpp", directory: "/tmp/test") | ||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") | ||
!1 = !DIFile(filename: "a.cpp", directory: "/proc/self/cwd") | ||
!2 = !{!3, !5} | ||
!3 = !DIDerivedType(tag: DW_TAG_typedef, name: "ULL", file: !1, line: 2, baseType: !4) | ||
!4 = !DIBasicType(name: "unsigned long long", size: 64, encoding: DW_ATE_unsigned) | ||
!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) | ||
!6 = !{i32 7, !"Dwarf Version", i32 4} | ||
!7 = !{i32 2, !"Debug Info Version", i32 3} | ||
!8 = !{i32 1, !"wchar_size", i32 4} | ||
!9 = !{i32 8, !"PIC Level", i32 2} | ||
!10 = !{i32 7, !"uwtable", i32 1} | ||
!11 = !{i32 7, !"frame-pointer", i32 1} | ||
!12 = !{!"clang version 20.0.0"} | ||
!13 = distinct !DISubprogram(name: "func_A", scope: !1, file: !1, line: 4, type: !14, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) | ||
!14 = !DISubroutineType(types: !15) | ||
!15 = !{} | ||
!18 = distinct !DISubprogram(name: "func_B", scope: !1, file: !1, line: 5, type: !14, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) | ||
!20 = distinct !DISubprogram(name: "func_C", scope: !1, file: !1, line: 6, type: !14, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) | ||
!22 = distinct !DISubprogram(name: "take_func_addr", scope: !1, file: !1, line: 8, type: !14, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) | ||
|
||
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
;;;;;;;;;;;;;; Generate the above LLVM IR with the below script ;;;;;;;;;;;;;;; | ||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
; #!/bin/bash | ||
; set -ex | ||
; TOOLCHAIN_BIN="llvm-project/build/Debug/bin" | ||
; | ||
; # Create icf-safe-thunks-dwarf.cpp file | ||
; cat > icf-safe-thunks-dwarf.cpp <<EOF | ||
; #define ATTR __attribute__((noinline)) extern "C" | ||
; typedef unsigned long long ULL; | ||
; | ||
; ATTR int func_A() { return 1; } | ||
; ATTR int func_B() { return 1; } | ||
; ATTR int func_C() { return 1; } | ||
; | ||
; ATTR ULL take_func_addr() { | ||
; ULL val = 0; | ||
; val += (ULL)(void*)func_A; | ||
; val += (ULL)(void*)func_B; | ||
; val += (ULL)(void*)func_C; | ||
; return val; | ||
; } | ||
; EOF | ||
; | ||
; $TOOLCHAIN_BIN/clang -target arm64-apple-macos11.0 -S -emit-llvm -g \ | ||
; icf-safe-thunks-dwarf.cpp | ||
!12 = distinct !DISubprogram(name: "func_A", scope: !1, file: !1, line: 4, type: !13, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) | ||
!13 = !DISubroutineType(types: !14) | ||
!14 = !{!15} | ||
!15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) | ||
!16 = !DILocation(line: 4, column: 21, scope: !12) | ||
!17 = distinct !DISubprogram(name: "func_B", scope: !1, file: !1, line: 5, type: !13, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) | ||
!18 = !DILocation(line: 5, column: 21, scope: !17) | ||
!19 = distinct !DISubprogram(name: "func_C", scope: !1, file: !1, line: 6, type: !13, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) | ||
!20 = !DILocation(line: 6, column: 21, scope: !19) | ||
!21 = distinct !DISubprogram(name: "take_func_addr", scope: !1, file: !1, line: 8, type: !22, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !24) | ||
!22 = !DISubroutineType(types: !23) | ||
!23 = !{!3} | ||
!24 = !{!25} | ||
!25 = !DILocalVariable(name: "val", scope: !21, file: !1, line: 9, type: !3) | ||
!26 = !DILocation(line: 0, scope: !21) | ||
!27 = !DILocation(line: 13, column: 5, scope: !21) |
Oops, something went wrong.