2019-10-29 05:53:32 +08:00
; RUN: llc < %s | FileCheck --check-prefixes=CHECK %s
; RUN: llc -O0 < %s | FileCheck --check-prefixes=CHECK %s
2019-04-25 07:02:48 +08:00
; Source to regenerate:
2019-08-08 06:49:40 +08:00
; $ clang -cc1 -triple x86_64-windows-msvc t.cpp -debug-info-kind=limited \
; -gcodeview -O2 -fms-extensions -emit-llvm -o t.ll
2019-04-25 07:02:48 +08:00
;
2019-08-08 06:49:40 +08:00
; extern "C" struct Foo {
2019-04-25 07:02:48 +08:00
; __declspec(allocator) virtual void *alloc();
; };
2019-05-07 07:37:03 +08:00
; extern "C" __declspec(allocator) Foo *alloc_foo();
2019-08-08 06:49:40 +08:00
; extern "C" void use_result(void *);
; extern "C" Foo *call_tail() {
; return alloc_foo();
2019-07-31 08:16:13 +08:00
; }
2019-08-08 06:49:40 +08:00
; extern "C" int call_virtual(Foo *p) {
; use_result(p->alloc());
; return 0;
; }
; extern "C" int call_multiple() {
; use_result(alloc_foo());
; use_result(alloc_foo());
; return 0;
2019-05-07 07:37:03 +08:00
; }
2019-04-25 07:02:48 +08:00
2019-08-08 06:49:40 +08:00
; ModuleID = 't.cpp'
source_filename = "t.cpp"
2019-04-25 07:02:48 +08:00
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-windows-msvc"
%struct.Foo = type { i32 ( . . . ) * * }
2019-08-08 06:49:40 +08:00
; Function Attrs: nounwind
define d s o _ l o c a l %struct.Foo * @call_tail ( ) local_unnamed_addr #0 !dbg !7 {
2019-04-25 07:02:48 +08:00
entry:
2019-08-08 06:49:40 +08:00
%call = tail call %struct.Foo * @alloc_foo ( ) #3 , !dbg !13 , !heapallocsite !12
ret %struct.Foo * %call , !dbg !13
2019-04-25 07:02:48 +08:00
}
2019-08-08 06:49:40 +08:00
declare d s o _ l o c a l %struct.Foo * @alloc_foo ( ) local_unnamed_addr #1
; Function Attrs: nounwind
define d s o _ l o c a l i32 @call_virtual ( %struct.Foo * %p ) local_unnamed_addr #0 !dbg !14 {
entry:
call void @llvm.dbg.value ( metadata %struct.Foo * %p , metadata !19 , metadata !DIExpression ( ) ) , !dbg !20
%0 = bitcast %struct.Foo * %p to i8 * ( %struct.Foo * ) * * * , !dbg !21
%vtable = load i8 * ( %struct.Foo * ) * * , i8 * ( %struct.Foo * ) * * * %0 , align 8 , !dbg !21 , !tbaa !22
%1 = load i8 * ( %struct.Foo * ) * , i8 * ( %struct.Foo * ) * * %vtable , align 8 , !dbg !21
%call = tail call i8 * %1 ( %struct.Foo * %p ) #3 , !dbg !21 , !heapallocsite !2
tail call void @use_result ( i8 * %call ) #3 , !dbg !21
ret i32 0 , !dbg !25
}
2019-04-25 07:02:48 +08:00
2019-08-08 06:49:40 +08:00
declare d s o _ l o c a l void @use_result ( i8 * ) local_unnamed_addr #1
2019-04-25 07:02:48 +08:00
2019-08-08 06:49:40 +08:00
; Function Attrs: nounwind
define d s o _ l o c a l i32 @call_multiple ( ) local_unnamed_addr #0 !dbg !26 {
2019-04-25 07:02:48 +08:00
entry:
2019-08-08 06:49:40 +08:00
%call = tail call %struct.Foo * @alloc_foo ( ) #3 , !dbg !29 , !heapallocsite !12
%0 = bitcast %struct.Foo * %call to i8 * , !dbg !29
tail call void @use_result ( i8 * %0 ) #3 , !dbg !29
%call1 = tail call %struct.Foo * @alloc_foo ( ) #3 , !dbg !30 , !heapallocsite !12
%1 = bitcast %struct.Foo * %call1 to i8 * , !dbg !30
tail call void @use_result ( i8 * %1 ) #3 , !dbg !30
ret i32 0 , !dbg !31
2019-04-25 07:02:48 +08:00
}
2019-08-08 06:49:40 +08:00
; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.value ( metadata , metadata , metadata ) #2
2019-05-07 07:37:03 +08:00
2019-08-08 06:49:40 +08:00
; Don't emit metadata for tail calls.
; CHECK-LABEL: call_tail: # @call_tail
; CHECK: jmp alloc_foo
; CHECK-LABEL: call_virtual: # @call_virtual
2019-10-29 05:53:32 +08:00
; CHECK: callq *{{.*}}%rax{{.*}}
; CHECK-NEXT: [[LABEL1:.Ltmp[0-9]+]]:
2019-05-07 07:37:03 +08:00
2019-08-08 06:49:40 +08:00
; CHECK-LABEL: call_multiple: # @call_multiple
2019-10-29 05:53:32 +08:00
; CHECK: callq alloc_foo
; CHECK-NEXT: [[LABEL3:.Ltmp[0-9]+]]:
; CHECK: callq alloc_foo
; CHECK-NEXT: [[LABEL5:.Ltmp[0-9]+]]:
2019-04-25 07:02:48 +08:00
; CHECK-LABEL: .short 4423 # Record kind: S_GPROC32_ID
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
2019-10-29 05:53:32 +08:00
; CHECK-NEXT: .secrel32 [[LABEL0:.Ltmp[0-9]+]]
; CHECK-NEXT: .secidx [[LABEL0]]
; CHECK-NEXT: .short [[LABEL1]]-[[LABEL0]]
2019-08-01 07:59:31 +08:00
; CHECK-NEXT: .long 3
2019-04-25 07:02:48 +08:00
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
2019-10-29 05:53:32 +08:00
; CHECK-NEXT: .secrel32 [[LABEL2:.Ltmp[0-9]+]]
; CHECK-NEXT: .secidx [[LABEL2]]
; CHECK-NEXT: .short [[LABEL3]]-[[LABEL2]]
2019-08-01 07:59:31 +08:00
; CHECK-NEXT: .long 4096
2019-05-07 07:37:03 +08:00
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
2019-10-29 05:53:32 +08:00
; CHECK-NEXT: .secrel32 [[LABEL4:.Ltmp[0-9]+]]
; CHECK-NEXT: .secidx [[LABEL4]]
; CHECK-NEXT: .short [[LABEL5]]-[[LABEL4]]
2019-08-01 07:59:31 +08:00
; CHECK-NEXT: .long 4096
2019-08-08 06:49:40 +08:00
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math" = "false" "disable-tail-calls" = "false" "frame-pointer" = "none" "less-precise-fpmad" = "false" "min-legal-vector-width" = "0" "no-infs-fp-math" = "false" "no-jump-tables" = "false" "no-nans-fp-math" = "false" "no-signed-zeros-fp-math" = "false" "no-trapping-math" = "false" "stack-protector-buffer-size" = "8" "target-features" = "+cx8,+mmx,+sse,+sse2,+x87" "unsafe-fp-math" = "false" "use-soft-float" = "false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math" = "false" "disable-tail-calls" = "false" "frame-pointer" = "none" "less-precise-fpmad" = "false" "no-infs-fp-math" = "false" "no-nans-fp-math" = "false" "no-signed-zeros-fp-math" = "false" "no-trapping-math" = "false" "stack-protector-buffer-size" = "8" "target-features" = "+cx8,+mmx,+sse,+sse2,+x87" "unsafe-fp-math" = "false" "use-soft-float" = "false" }
attributes #2 = { nounwind readnone s p e c u l a t a b l e w i l l r e t u r n }
attributes #3 = { nounwind }
2019-04-25 07:02:48 +08:00
!llvm.dbg.cu = ! { !0 }
2019-08-08 06:49:40 +08:00
!llvm.module.flags = ! { !3 , !4 , !5 }
!llvm.ident = ! { !6 }
2019-04-25 07:02:48 +08:00
2019-08-08 06:49:40 +08:00
!0 = distinct !DICompileUnit ( language: D W _ L A N G _ C _ p l u s _ p l u s , file: !1 , producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git fa686ea7650235c6dff988cc8cba49e130b3d5f8)" , isOptimized: true , runtimeVersion: 0 , emissionKind: F u l l D e b u g , enums: !2 , nameTableKind: N one )
!1 = !DIFile ( filename: "<stdin>" , directory: "/usr/local/google/home/akhuang/testing/heapallocsite" , checksumkind: C S K _ M D 5 , checksum: "e0a04508b4229fc4aee0baa364e25987" )
2019-04-25 07:02:48 +08:00
!2 = ! { }
!3 = ! { i32 2 , !"CodeView" , i32 1 }
!4 = ! { i32 2 , !"Debug Info Version" , i32 3 }
!5 = ! { i32 1 , !"wchar_size" , i32 2 }
2019-08-08 06:49:40 +08:00
!6 = ! { !"clang version 10.0.0 (https://github.com/llvm/llvm-project.git fa686ea7650235c6dff988cc8cba49e130b3d5f8)" }
!7 = distinct !DISubprogram ( name: "call_tail" , scope: !8 , file: !8 , line: 6 , type: !9 , scopeLine: 6 , flags: D I F l a g P r o t o t y p e d , spFlags: D I S P F l a g D e f i n i t i o n | D I S P F l a g O p t i m i z e d , unit: !0 , retainedNodes: !2 )
!8 = !DIFile ( filename: "t.cpp" , directory: "/usr/local/google/home/akhuang/testing/heapallocsite" , checksumkind: C S K _ M D 5 , checksum: "e0a04508b4229fc4aee0baa364e25987" )
2019-04-25 07:02:48 +08:00
!9 = !DISubroutineType ( types: !10 )
2019-08-08 06:49:40 +08:00
!10 = ! { !11 }
2019-08-01 07:59:31 +08:00
!11 = !DIDerivedType ( tag: D W _ T A G _ p o i n t e r _ type , baseType: !12 , size: 64 )
2019-08-08 06:49:40 +08:00
!12 = !DICompositeType ( tag: D W _ T A G _ s t r u c t u r e _ type , name: "Foo" , file: !8 , line: 1 , flags: D I F l a g F w d D e c l , identifier: ".?AUFoo@@" )
!13 = !DILocation ( line: 7 , scope: !7 )
!14 = distinct !DISubprogram ( name: "call_virtual" , scope: !8 , file: !8 , line: 9 , type: !15 , scopeLine: 9 , flags: D I F l a g P r o t o t y p e d , spFlags: D I S P F l a g D e f i n i t i o n | D I S P F l a g O p t i m i z e d , unit: !0 , retainedNodes: !18 )
!15 = !DISubroutineType ( types: !16 )
!16 = ! { !17 , !11 }
!17 = !DIBasicType ( name: "int" , size: 32 , encoding: D W _ A T E _ s i g n e d )
!18 = ! { !19 }
!19 = !DILocalVariable ( name: "p" , arg: 1 , scope: !14 , file: !8 , line: 9 , type: !11 )
!20 = !DILocation ( line: 0 , scope: !14 )
!21 = !DILocation ( line: 10 , scope: !14 )
!22 = ! { !23 , !23 , i64 0 }
!23 = ! { !"vtable pointer" , !24 , i64 0 }
!24 = ! { !"Simple C++ TBAA" }
!25 = !DILocation ( line: 11 , scope: !14 )
!26 = distinct !DISubprogram ( name: "call_multiple" , scope: !8 , file: !8 , line: 13 , type: !27 , scopeLine: 13 , flags: D I F l a g P r o t o t y p e d , spFlags: D I S P F l a g D e f i n i t i o n | D I S P F l a g O p t i m i z e d , unit: !0 , retainedNodes: !2 )
!27 = !DISubroutineType ( types: !28 )
!28 = ! { !17 }
!29 = !DILocation ( line: 14 , scope: !26 )
!30 = !DILocation ( line: 15 , scope: !26 )
!31 = !DILocation ( line: 16 , scope: !26 )