1; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=x86_64 -S | FileCheck %s --check-prefixes=CHECK,COMDAT,ELF 2 3; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=aarch64-apple-darwin -S | FileCheck %s --check-prefixes=CHECK,MACHO 4 5; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=x86_64-windows -S | FileCheck %s --check-prefixes=CHECK,COMDAT,WIN 6 7; COMDAT: $foo = comdat nodeduplicate 8; COMDAT: $CallViaVptr = comdat nodeduplicate 9; COMDAT: $DirectBitcastCall = comdat nodeduplicate 10 11; ELF: @__sancov_gen_ = private global [3 x i32] zeroinitializer, section "__sancov_guards", comdat($foo), align 4{{$}} 12; ELF-NEXT: @__sancov_gen_.1 = private global [1 x i32] zeroinitializer, section "__sancov_guards", comdat($CallViaVptr), align 4{{$}} 13; ELF-NEXT: @__sancov_gen_.2 = private global [1 x i32] zeroinitializer, section "__sancov_guards", comdat($DirectBitcastCall), align 4{{$}} 14 15; MACHO: @__sancov_gen_ = private global [3 x i32] zeroinitializer, section "__DATA,__sancov_guards", align 4{{$}} 16; MACHO-NEXT: @__sancov_gen_.1 = private global [1 x i32] zeroinitializer, section "__DATA,__sancov_guards", align 4{{$}} 17; MACHO-NEXT: @__sancov_gen_.2 = private global [1 x i32] zeroinitializer, section "__DATA,__sancov_guards", align 4{{$}} 18 19; WIN: @__sancov_gen_ = private global [3 x i32] zeroinitializer, section ".SCOV$GM", comdat($foo), align 4{{$}} 20; WIN-NEXT: @__sancov_gen_.1 = private global [1 x i32] zeroinitializer, section ".SCOV$GM", comdat($CallViaVptr), align 4{{$}} 21; WIN-NEXT: @__sancov_gen_.2 = private global [1 x i32] zeroinitializer, section ".SCOV$GM", comdat($DirectBitcastCall), align 4{{$}} 22 23; ELF: @llvm.used = appending global [1 x ptr] [ptr @sancov.module_ctor_trace_pc_guard] 24; ELF: @llvm.compiler.used = appending global [3 x ptr] [ptr @__sancov_gen_, ptr @__sancov_gen_.1, ptr @__sancov_gen_.2], section "llvm.metadata" 25; MACHO: @llvm.used = appending global [4 x ptr] [ptr @sancov.module_ctor_trace_pc_guard, ptr @__sancov_gen_, ptr @__sancov_gen_.1, ptr @__sancov_gen_.2] 26; MACHO-NOT: @llvm.compiler.used = 27; WIN: @llvm.used = appending global [1 x ptr] [ptr @sancov.module_ctor_trace_pc_guard], section "llvm.metadata" 28; WIN-NEXT: @llvm.compiler.used = appending global [3 x ptr] [ptr @__sancov_gen_, ptr @__sancov_gen_.1, ptr @__sancov_gen_.2], section "llvm.metadata" 29 30; CHECK-LABEL: define void @foo 31; CHECK: call void @__sanitizer_cov_trace_pc 32; CHECK: ret void 33 34define void @foo(ptr %a) sanitize_address { 35entry: 36 %tobool = icmp eq ptr %a, null 37 br i1 %tobool, label %if.end, label %if.then 38 39 if.then: ; preds = %entry 40 store i32 0, ptr %a, align 4 41 br label %if.end 42 43 if.end: ; preds = %entry, %if.then 44 ret void 45} 46 47; CHECK-LABEL: define void @CallViaVptr 48; CHECK: call void @__sanitizer_cov_trace_pc_indir 49; CHECK: call void @__sanitizer_cov_trace_pc_indir 50; CHECK: ret void 51 52%struct.StructWithVptr = type { ptr } 53 54define void @CallViaVptr(ptr %foo) uwtable sanitize_address { 55entry: 56 %vtable = load ptr, ptr %foo, align 8 57 %0 = load ptr, ptr %vtable, align 8 58 tail call void %0(ptr %foo) 59 tail call void %0(ptr %foo) 60 tail call void asm sideeffect "", ""() 61 ret void 62} 63 64; CHECK-LABEL: define void @DirectBitcastCall 65; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard 66; CHECK-NEXT: call void @direct_callee() 67; CHECK-NEXT: ret void 68 69declare i32 @direct_callee() 70 71define void @DirectBitcastCall() sanitize_address { 72 call void @direct_callee() 73 ret void 74} 75 76; ELF-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 comdat { 77; MACHO-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 { 78 79; CHECK: attributes #2 = { nounwind } 80