328 lines · plain
1## Test that BOLT correctly handles debug line information for functions2## that belong to multiple compilation units (e.g., inline functions in3## common header files). This is the assembly version of the multi-cu-debug-line.test.4## The test covers two scenarios:5## 1. Normal processing: .debug_line section shows lines for the function6## in all CUs where it was compiled, with no duplicate rows within CUs7## 2. Functions not processed: When BOLT doesn't process functions (using8## --funcs with nonexistent function), original debug info is preserved9 10# REQUIRES: system-linux11 12# RUN: split-file %s %t13# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/multi-cu-file1.s -o %t/multi-cu-file1.o14# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/multi-cu-file2.s -o %t/multi-cu-file2.o15# RUN: %clang %cflags %t/multi-cu-file1.o %t/multi-cu-file2.o -o %t.exe -Wl,-q16 17## Test 1: Normal BOLT processing (functions are processed/optimized)18# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections19# RUN: llvm-dwarfdump --debug-line %t.bolt > %t.debug-line.txt20# RUN: FileCheck %s --check-prefix=BASIC --input-file %t.debug-line.txt21 22## Check that debug line information is present for both compilation units23# BASIC: debug_line[{{.*}}]24# BASIC: file_names[{{.*}}]:25# BASIC: name: "{{.*}}multi-cu-file1.c"26# BASIC: debug_line[{{.*}}]27# BASIC: file_names[{{.*}}]:28# BASIC: name: "{{.*}}multi-cu-file2.c"29 30## Use our helper script to create a normalized table without addresses31# RUN: process-debug-line %t.debug-line.txt > %t.normalized-debug-line.txt32# RUN: FileCheck %s --check-prefix=NORMALIZED --input-file %t.normalized-debug-line.txt33 34## Check that we have line entries for the inline function (lines 5, 6, 7) from multi-cu-common.h35## in both compilation units36# NORMALIZED: multi-cu-file1.c 5 {{[0-9]+}} multi-cu-common.h37# NORMALIZED: multi-cu-file1.c 6 {{[0-9]+}} multi-cu-common.h38# NORMALIZED: multi-cu-file1.c 7 {{[0-9]+}} multi-cu-common.h39# NORMALIZED: multi-cu-file2.c 5 {{[0-9]+}} multi-cu-common.h40# NORMALIZED: multi-cu-file2.c 6 {{[0-9]+}} multi-cu-common.h41# NORMALIZED: multi-cu-file2.c 7 {{[0-9]+}} multi-cu-common.h42 43## Verify that we have line entries for the inline function in multiple CUs44## by checking that the header file appears multiple times in different contexts45# RUN: grep -c "multi-cu-common.h" %t.debug-line.txt > %t.header-count.txt46# RUN: FileCheck %s --check-prefix=MULTI-CU --input-file %t.header-count.txt47 48## The header should appear in debug line info for multiple CUs49# MULTI-CU: {{[2-9]|[1-9][0-9]+}}50 51## Check that there are no duplicate line table rows within the same CU52## This verifies the fix for the bug where duplicate entries were created53# RUN: sort %t.normalized-debug-line.txt | uniq -c | \54# RUN: awk '$1 > 1 {print "DUPLICATE_ROW: " $0}' > %t.duplicates.txt55# RUN: FileCheck %s --check-prefix=NO-DUPLICATES --input-file %t.duplicates.txt --allow-empty56 57## Should have no duplicate normalized rows (file should be empty)58## Note: Cross-CU duplicates are expected and valid (same function in different CUs)59## but within-CU duplicates would indicate a bug60# NO-DUPLICATES-NOT: DUPLICATE_ROW61 62## Test 2: Functions not processed by BOLT (using --funcs with nonexistent function)63## This tests the code path where BOLT preserves original debug info64# RUN: llvm-bolt %t.exe -o %t.not-emitted.bolt --update-debug-sections --funcs=nonexistent_function65# RUN: llvm-dwarfdump --debug-line %t.not-emitted.bolt > %t.not-emitted.debug-line.txt66# RUN: FileCheck %s --check-prefix=PRESERVED-BASIC --input-file %t.not-emitted.debug-line.txt67 68## Check that debug line information is still present for both compilation units when functions aren't processed69# PRESERVED-BASIC: debug_line[{{.*}}]70# PRESERVED-BASIC: file_names[{{.*}}]:71# PRESERVED-BASIC: name: "{{.*}}multi-cu-file1.c"72# PRESERVED-BASIC: debug_line[{{.*}}]73# PRESERVED-BASIC: file_names[{{.*}}]:74# PRESERVED-BASIC: name: "{{.*}}multi-cu-file2.c"75 76## Create normalized output for the not-emitted case77# RUN: process-debug-line %t.not-emitted.debug-line.txt > %t.not-emitted.normalized.txt78# RUN: FileCheck %s --check-prefix=PRESERVED-NORMALIZED --input-file %t.not-emitted.normalized.txt79 80## Check that we have line entries for the inline function (lines 5, 6, 7) from multi-cu-common.h81## in both compilation units (preserved from original)82# PRESERVED-NORMALIZED: multi-cu-file1.c 5 {{[0-9]+}} multi-cu-common.h83# PRESERVED-NORMALIZED: multi-cu-file1.c 6 {{[0-9]+}} multi-cu-common.h84# PRESERVED-NORMALIZED: multi-cu-file1.c 7 {{[0-9]+}} multi-cu-common.h85# PRESERVED-NORMALIZED: multi-cu-file2.c 5 {{[0-9]+}} multi-cu-common.h86# PRESERVED-NORMALIZED: multi-cu-file2.c 6 {{[0-9]+}} multi-cu-common.h87# PRESERVED-NORMALIZED: multi-cu-file2.c 7 {{[0-9]+}} multi-cu-common.h88 89## Verify that we have line entries for the inline function in multiple CUs (preserved)90## by checking that the header file appears multiple times in different contexts91# RUN: grep -c "multi-cu-common.h" %t.not-emitted.debug-line.txt > %t.preserved-header-count.txt92# RUN: FileCheck %s --check-prefix=PRESERVED-MULTI-CU --input-file %t.preserved-header-count.txt93 94## The header should appear in debug line info for multiple CUs (preserved from original)95# PRESERVED-MULTI-CU: {{[2-9]|[1-9][0-9]+}}96 97## Check that original debug info is preserved for main functions98# RUN: grep "multi-cu-file1.c.*multi-cu-file1.c" %t.not-emitted.normalized.txt > %t.preserved-main.txt99# RUN: FileCheck %s --check-prefix=PRESERVED-MAIN --input-file %t.preserved-main.txt100 101# PRESERVED-MAIN: multi-cu-file1.c {{[0-9]+}} {{[0-9]+}} multi-cu-file1.c102 103## Check that original debug info is preserved for file2 functions104# RUN: grep "multi-cu-file2.c.*multi-cu-file2.c" %t.not-emitted.normalized.txt > %t.preserved-file2.txt105# RUN: FileCheck %s --check-prefix=PRESERVED-FILE2 --input-file %t.preserved-file2.txt106 107# PRESERVED-FILE2: multi-cu-file2.c {{[0-9]+}} {{[0-9]+}} multi-cu-file2.c108 109;--- multi-cu-file1.s110 .text111 .file 1 "/repo/llvm-project" "bolt/test/Inputs/multi-cu-file1.c"112 .file 2 "/repo/llvm-project" "bolt/test/Inputs/multi-cu-common.h"113 114 .globl main115 .type main,@function116main:117.Lfunc_begin0:118 .loc 1 4 0119 callq common_inline_function120 .loc 1 8 0121 retq122.Lfunc_end0:123 .size main, .Lfunc_end0-main124 125 .type common_inline_function,@function126common_inline_function:127.Lfunc_begin1:128 .loc 2 5 0129 movl $42, %eax130 .loc 2 6 0131 addl $10, %eax132 .loc 2 7 0133 retq134.Lfunc_end1:135 .size common_inline_function, .Lfunc_end1-common_inline_function136 137 .section .debug_abbrev,"",@progbits138 .byte 1 # Abbreviation Code139 .byte 17 # DW_TAG_compile_unit140 .byte 1 # DW_CHILDREN_yes141 .byte 37 # DW_AT_producer142 .byte 14 # DW_FORM_strp143 .byte 19 # DW_AT_language144 .byte 5 # DW_FORM_data2145 .byte 3 # DW_AT_name146 .byte 14 # DW_FORM_strp147 .byte 16 # DW_AT_stmt_list148 .byte 23 # DW_FORM_sec_offset149 .byte 27 # DW_AT_comp_dir150 .byte 14 # DW_FORM_strp151 .byte 17 # DW_AT_low_pc152 .byte 1 # DW_FORM_addr153 .byte 18 # DW_AT_high_pc154 .byte 6 # DW_FORM_data4155 .byte 0 # EOM(1)156 .byte 0 # EOM(2)157 .byte 2 # Abbreviation Code158 .byte 46 # DW_TAG_subprogram159 .byte 0 # DW_CHILDREN_no160 .byte 17 # DW_AT_low_pc161 .byte 1 # DW_FORM_addr162 .byte 18 # DW_AT_high_pc163 .byte 6 # DW_FORM_data4164 .byte 3 # DW_AT_name165 .byte 14 # DW_FORM_strp166 .byte 58 # DW_AT_decl_file167 .byte 11 # DW_FORM_data1168 .byte 59 # DW_AT_decl_line169 .byte 11 # DW_FORM_data1170 .byte 0 # EOM(1)171 .byte 0 # EOM(2)172 .byte 0 # EOM(3)173 174 .section .debug_info,"",@progbits175.Lcu_begin0:176 .long .Ldebug_info_end0-.Ldebug_info_start0177.Ldebug_info_start0:178 .short 4 # DWARF version number179 .long .debug_abbrev # Offset Into Abbrev. Section180 .byte 8 # Address Size (in bytes)181 .byte 1 # Abbrev [1] 0xb:0x30 DW_TAG_compile_unit182 .long .Linfo_string0 # DW_AT_producer183 .short 29 # DW_AT_language184 .long .Linfo_string1 # DW_AT_name185 .long .Lline_table_start0 # DW_AT_stmt_list186 .long .Linfo_string2 # DW_AT_comp_dir187 .quad .Lfunc_begin0 # DW_AT_low_pc188 .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc189 .byte 2 # Abbrev [2] 0x2a:0x10 DW_TAG_subprogram190 .quad .Lfunc_begin0 # DW_AT_low_pc191 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc192 .long .Linfo_string3 # DW_AT_name193 .byte 1 # DW_AT_decl_file194 .byte 4 # DW_AT_decl_line195 .byte 2 # Abbrev [2] 0x3a:0x10 DW_TAG_subprogram196 .quad .Lfunc_begin1 # DW_AT_low_pc197 .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc198 .long .Linfo_string4 # DW_AT_name199 .byte 2 # DW_AT_decl_file200 .byte 5 # DW_AT_decl_line201 .byte 0 # End Of Children Mark202.Ldebug_info_end0:203 204 .section .debug_str,"MS",@progbits,1205.Linfo_string0:206 .asciz "clang version 18.0.0"207.Linfo_string1:208 .asciz "/repo/llvm-project/bolt/test/Inputs/multi-cu-file1.c"209.Linfo_string2:210 .asciz "/repo/llvm-project"211.Linfo_string3:212 .asciz "main"213.Linfo_string4:214 .asciz "common_inline_function"215 216 .section .debug_line,"",@progbits217.Lline_table_start0:218 219;--- multi-cu-file2.s220 .text221 .file 1 "/repo/llvm-project" "bolt/test/Inputs/multi-cu-file2.c"222 .file 2 "/repo/llvm-project" "bolt/test/Inputs/multi-cu-common.h"223 224 .globl helper_function225 .type helper_function,@function226helper_function:227.Lfunc_begin0:228 .loc 1 4 0229 callq common_inline_function230 .loc 1 8 0231 retq232.Lfunc_end0:233 .size helper_function, .Lfunc_end0-helper_function234 235 .type common_inline_function,@function236common_inline_function:237.Lfunc_begin1:238 .loc 2 5 0239 movl $42, %eax240 .loc 2 6 0241 addl $10, %eax242 .loc 2 7 0243 retq244.Lfunc_end1:245 .size common_inline_function, .Lfunc_end1-common_inline_function246 247 .section .debug_abbrev,"",@progbits248 .byte 1 # Abbreviation Code249 .byte 17 # DW_TAG_compile_unit250 .byte 1 # DW_CHILDREN_yes251 .byte 37 # DW_AT_producer252 .byte 14 # DW_FORM_strp253 .byte 19 # DW_AT_language254 .byte 5 # DW_FORM_data2255 .byte 3 # DW_AT_name256 .byte 14 # DW_FORM_strp257 .byte 16 # DW_AT_stmt_list258 .byte 23 # DW_FORM_sec_offset259 .byte 27 # DW_AT_comp_dir260 .byte 14 # DW_FORM_strp261 .byte 17 # DW_AT_low_pc262 .byte 1 # DW_FORM_addr263 .byte 18 # DW_AT_high_pc264 .byte 6 # DW_FORM_data4265 .byte 0 # EOM(1)266 .byte 0 # EOM(2)267 .byte 2 # Abbreviation Code268 .byte 46 # DW_TAG_subprogram269 .byte 0 # DW_CHILDREN_no270 .byte 17 # DW_AT_low_pc271 .byte 1 # DW_FORM_addr272 .byte 18 # DW_AT_high_pc273 .byte 6 # DW_FORM_data4274 .byte 3 # DW_AT_name275 .byte 14 # DW_FORM_strp276 .byte 58 # DW_AT_decl_file277 .byte 11 # DW_FORM_data1278 .byte 59 # DW_AT_decl_line279 .byte 11 # DW_FORM_data1280 .byte 0 # EOM(1)281 .byte 0 # EOM(2)282 .byte 0 # EOM(3)283 284 .section .debug_info,"",@progbits285.Lcu_begin0:286 .long .Ldebug_info_end0-.Ldebug_info_start0287.Ldebug_info_start0:288 .short 4 # DWARF version number289 .long .debug_abbrev # Offset Into Abbrev. Section290 .byte 8 # Address Size (in bytes)291 .byte 1 # Abbrev [1] 0xb:0x30 DW_TAG_compile_unit292 .long .Linfo_string0 # DW_AT_producer293 .short 29 # DW_AT_language294 .long .Linfo_string1 # DW_AT_name295 .long .Lline_table_start0 # DW_AT_stmt_list296 .long .Linfo_string2 # DW_AT_comp_dir297 .quad .Lfunc_begin0 # DW_AT_low_pc298 .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc299 .byte 2 # Abbrev [2] 0x2a:0x10 DW_TAG_subprogram300 .quad .Lfunc_begin0 # DW_AT_low_pc301 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc302 .long .Linfo_string3 # DW_AT_name303 .byte 1 # DW_AT_decl_file304 .byte 4 # DW_AT_decl_line305 .byte 2 # Abbrev [2] 0x3a:0x10 DW_TAG_subprogram306 .quad .Lfunc_begin1 # DW_AT_low_pc307 .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc308 .long .Linfo_string4 # DW_AT_name309 .byte 2 # DW_AT_decl_file310 .byte 5 # DW_AT_decl_line311 .byte 0 # End Of Children Mark312.Ldebug_info_end0:313 314 .section .debug_str,"MS",@progbits,1315.Linfo_string0:316 .asciz "clang version 18.0.0"317.Linfo_string1:318 .asciz "/repo/llvm-project/bolt/test/Inputs/multi-cu-file2.c"319.Linfo_string2:320 .asciz "/repo/llvm-project"321.Linfo_string3:322 .asciz "helper_function"323.Linfo_string4:324 .asciz "common_inline_function"325 326 .section .debug_line,"",@progbits327.Lline_table_start0:328