2018-10-06 04:37:17 +08:00
; $ clang++ -S -emit-llvm -o - -gdwarf-5 -o - -O1 tail2.cc
; volatile int sink;
; void __attribute__((noinline)) bat() { sink++; }
; void __attribute__((noinline)) bar() { sink++; }
; void __attribute__((noinline)) foo() {
; bar(); bat();
; bar(); bat();
; }
; int __attribute__((disable_tail_calls)) main() { foo(); }
2018-10-06 05:28:14 +08:00
; On Windows, we don't handle the relocations needed for AT_return_pc properly
; and fail with "failed to compute relocation: IMAGE_REL_AMD64_ADDR32".
; UNSUPPORTED: cygwin,windows-gnu,windows-msvc
2018-10-06 05:54:58 +08:00
; RUN: %llc_dwarf -mtriple=x86_64-- < %s -o - | FileCheck %s -check-prefix=ASM
2019-08-01 00:51:28 +08:00
; RUN: %llc_dwarf -debugger-tune=lldb -mtriple=x86_64-- < %s -filetype=obj -o %t.o
2020-03-18 08:56:28 +08:00
; RUN: llvm-dwarfdump %t.o -o - | FileCheck %s -check-prefix=OBJ -implicit-check-not=DW_TAG_call -implicit-check-not=DW_AT_call
2018-10-06 04:37:17 +08:00
; RUN: llvm-dwarfdump -verify %t.o 2>&1 | FileCheck %s -check-prefix=VERIFY
; RUN: llvm-dwarfdump -statistics %t.o | FileCheck %s -check-prefix=STATS
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis -o /dev/null
; VERIFY: No errors.
2019-08-01 00:51:28 +08:00
; STATS: "call site DIEs":6
2018-10-06 04:37:17 +08:00
@sink = global i32 0 , align 4 , !dbg !0
2019-11-14 10:19:32 +08:00
define void @__has_no_subprogram ( ) {
entry:
%0 = load volatile i32 , i32 * @sink , align 4
%inc = add nsw i32 %0 , 1
store volatile i32 %inc , i32 * @sink , align 4
ret void
}
2018-10-06 04:37:17 +08:00
; ASM: DW_TAG_subprogram
; ASM: DW_AT_call_all_calls
; OBJ: [[bat_sp:.*]]: DW_TAG_subprogram
; OBJ: DW_AT_call_all_calls (true)
; OBJ: DW_AT_name ("bat")
define void @_Z3batv ( ) !dbg !13 {
entry:
%0 = load volatile i32 , i32 * @sink , align 4 , !dbg !16 , !tbaa !17
%inc = add nsw i32 %0 , 1 , !dbg !16
store volatile i32 %inc , i32 * @sink , align 4 , !dbg !16 , !tbaa !17
ret void , !dbg !21
}
; ASM: DW_TAG_subprogram
; ASM: DW_AT_call_all_calls
; OBJ: [[bar_sp:.*]]: DW_TAG_subprogram
; OBJ: DW_AT_call_all_calls (true)
; OBJ: DW_AT_name ("bar")
define void @_Z3barv ( ) !dbg !22 {
entry:
%0 = load volatile i32 , i32 * @sink , align 4 , !dbg !23 , !tbaa !17
%inc = add nsw i32 %0 , 1 , !dbg !23
store volatile i32 %inc , i32 * @sink , align 4 , !dbg !23 , !tbaa !17
ret void , !dbg !24
}
; ASM: DW_TAG_subprogram
; ASM: DW_AT_call_all_calls
; OBJ: [[foo_sp:.*]]: DW_TAG_subprogram
; OBJ: DW_AT_call_all_calls (true)
; OBJ: DW_AT_name ("foo")
; OBJ: DW_TAG_call_site
; OBJ: DW_AT_call_origin ([[bar_sp]])
2018-10-06 05:05:31 +08:00
; OBJ: DW_AT_call_return_pc
2018-10-06 04:37:17 +08:00
; OBJ: DW_TAG_call_site
; OBJ: DW_AT_call_origin ([[bat_sp]])
2018-10-06 05:05:31 +08:00
; OBJ: DW_AT_call_return_pc
2018-10-06 04:37:17 +08:00
; OBJ: DW_TAG_call_site
; OBJ: DW_AT_call_origin ([[bar_sp]])
2018-10-06 05:05:31 +08:00
; OBJ: DW_AT_call_return_pc
2018-10-06 04:37:17 +08:00
; OBJ: DW_TAG_call_site
; OBJ: DW_AT_call_origin ([[bat_sp]])
; OBJ: DW_AT_call_tail_call
2020-03-18 08:56:28 +08:00
; OBJ: DW_AT_call_pc
2018-10-06 04:37:17 +08:00
define void @_Z3foov ( ) !dbg !25 {
entry:
2019-11-14 10:19:32 +08:00
tail call void @__has_no_subprogram ( )
2018-10-06 04:37:17 +08:00
tail call void @_Z3barv ( ) , !dbg !26
tail call void @_Z3batv ( ) , !dbg !27
tail call void @_Z3barv ( ) , !dbg !26
tail call void @_Z3batv ( ) , !dbg !27
ret void , !dbg !28
}
; ASM: DW_TAG_subprogram
; ASM: DW_AT_call_all_calls
; OBJ: DW_TAG_subprogram
; OBJ: DW_AT_call_all_calls (true)
; OBJ: DW_AT_name ("main")
; OBJ: DW_TAG_call_site
; OBJ: DW_AT_call_origin ([[foo_sp]])
2018-10-06 05:05:31 +08:00
; OBJ: DW_AT_call_return_pc
2019-08-01 00:51:28 +08:00
; OBJ: DW_TAG_call_site
; OBJ: DW_AT_call_target
; OBJ: DW_AT_call_return_pc
2018-10-06 04:37:17 +08:00
define i32 @main ( ) !dbg !29 {
entry:
call void @_Z3foov ( ) , !dbg !32
%indirect_target = load void ( ) * , void ( ) * * undef
call void %indirect_target ( )
call void asm sideeffect "" , "~{dirflag},~{fpsr},~{flags}" ( )
ret i32 0 , !dbg !33
}
!llvm.dbg.cu = ! { !2 }
!llvm.module.flags = ! { !8 , !9 , !10 , !11 }
!llvm.ident = ! { !12 }
!0 = !DIGlobalVariableExpression ( var: !1 , expr: !DIExpression ( ) )
!1 = distinct !DIGlobalVariable ( name: "sink" , scope: !2 , file: !3 , line: 1 , type: !6 , isLocal: false , isDefinition: true )
!2 = distinct !DICompileUnit ( language: D W _ L A N G _ C _ p l u s _ p l u s , file: !3 , producer: "clang version 7.0.0 " , isOptimized: true , runtimeVersion: 0 , emissionKind: F u l l D e b u g , enums: !4 , globals: !5 )
!3 = !DIFile ( filename: "/Users/vsk/src/llvm.org-tailcall/tail2.cc" , directory: "/Users/vsk/src/builds/llvm-project-tailcall-RA" , checksumkind: C S K _ M D 5 , checksum: "3b61952c21b7f657ddb7c0ad44cf5529" )
!4 = ! { }
!5 = ! { !0 }
!6 = !DIDerivedType ( tag: D W _ T A G _ v o l a t i l e _ type , baseType: !7 )
!7 = !DIBasicType ( name: "int" , size: 32 , encoding: D W _ A T E _ s i g n e d )
!8 = ! { i32 2 , !"Dwarf Version" , i32 5 }
!9 = ! { i32 2 , !"Debug Info Version" , i32 3 }
!10 = ! { i32 1 , !"wchar_size" , i32 4 }
!11 = ! { i32 7 , !"PIC Level" , i32 2 }
!12 = ! { !"clang version 7.0.0 " }
!13 = distinct !DISubprogram ( name: "bat" , linkageName: "_Z3batv" , scope: !3 , file: !3 , line: 2 , type: !14 , isLocal: false , isDefinition: true , scopeLine: 2 , flags: D I F l a g P r o t o t y p e d | D I F l a g A l l C a l l s D e s c r i b e d , isOptimized: true , unit: !2 , retainedNodes: !4 )
!14 = !DISubroutineType ( types: !15 )
!15 = ! { null }
!16 = !DILocation ( line: 2 , column: 44 , scope: !13 )
!17 = ! { !18 , !18 , i64 0 }
!18 = ! { !"int" , !19 , i64 0 }
!19 = ! { !"omnipotent char" , !20 , i64 0 }
!20 = ! { !"Simple C++ TBAA" }
!21 = !DILocation ( line: 2 , column: 48 , scope: !13 )
!22 = distinct !DISubprogram ( name: "bar" , linkageName: "_Z3barv" , scope: !3 , file: !3 , line: 3 , type: !14 , isLocal: false , isDefinition: true , scopeLine: 3 , flags: D I F l a g P r o t o t y p e d | D I F l a g A l l C a l l s D e s c r i b e d , isOptimized: true , unit: !2 , retainedNodes: !4 )
!23 = !DILocation ( line: 3 , column: 44 , scope: !22 )
!24 = !DILocation ( line: 3 , column: 48 , scope: !22 )
!25 = distinct !DISubprogram ( name: "foo" , linkageName: "_Z3foov" , scope: !3 , file: !3 , line: 4 , type: !14 , isLocal: false , isDefinition: true , scopeLine: 4 , flags: D I F l a g P r o t o t y p e d | D I F l a g A l l C a l l s D e s c r i b e d , isOptimized: true , unit: !2 , retainedNodes: !4 )
!26 = !DILocation ( line: 5 , column: 3 , scope: !25 )
!27 = !DILocation ( line: 6 , column: 3 , scope: !25 )
!28 = !DILocation ( line: 7 , column: 1 , scope: !25 )
!29 = distinct !DISubprogram ( name: "main" , scope: !3 , file: !3 , line: 8 , type: !30 , isLocal: false , isDefinition: true , scopeLine: 8 , flags: D I F l a g P r o t o t y p e d | D I F l a g A l l C a l l s D e s c r i b e d , isOptimized: true , unit: !2 , retainedNodes: !4 )
!30 = !DISubroutineType ( types: !31 )
!31 = ! { !7 }
!32 = !DILocation ( line: 8 , column: 50 , scope: !29 )
!33 = !DILocation ( line: 8 , column: 57 , scope: !29 )