1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt < %s -passes=tsan -S | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-EXC 3; RUN: opt < %s -passes=tsan -S -tsan-handle-cxx-exceptions=0 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOEXC 4 5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 6 7declare void @can_throw() 8declare void @cannot_throw() nounwind 9 10define i32 @func1() sanitize_thread { 11; CHECK-EXC-LABEL: define i32 @func1 12; CHECK-EXC-SAME: () #[[ATTR1:[0-9]+]] personality ptr @__gcc_personality_v0 { 13; CHECK-EXC-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0) 14; CHECK-EXC-NEXT: call void @__tsan_func_entry(ptr [[TMP1]]) 15; CHECK-EXC-NEXT: invoke void @can_throw() 16; CHECK-EXC-NEXT: to label [[DOTNOEXC:%.*]] unwind label [[TSAN_CLEANUP:%.*]] 17; CHECK-EXC: .noexc: 18; CHECK-EXC-NEXT: call void @__tsan_func_exit() 19; CHECK-EXC-NEXT: ret i32 0 20; CHECK-EXC: tsan_cleanup: 21; CHECK-EXC-NEXT: [[CLEANUP_LPAD:%.*]] = landingpad { ptr, i32 } 22; CHECK-EXC-NEXT: cleanup 23; CHECK-EXC-NEXT: call void @__tsan_func_exit() 24; CHECK-EXC-NEXT: resume { ptr, i32 } [[CLEANUP_LPAD]] 25; 26; CHECK-NOEXC-LABEL: define i32 @func1 27; CHECK-NOEXC-SAME: () #[[ATTR1:[0-9]+]] { 28; CHECK-NOEXC-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0) 29; CHECK-NOEXC-NEXT: call void @__tsan_func_entry(ptr [[TMP1]]) 30; CHECK-NOEXC-NEXT: call void @can_throw() 31; CHECK-NOEXC-NEXT: call void @__tsan_func_exit() 32; CHECK-NOEXC-NEXT: ret i32 0 33; 34 call void @can_throw() 35 ret i32 0 36} 37 38define i32 @func2() sanitize_thread { 39; CHECK-LABEL: define i32 @func2 40; CHECK-SAME: () #[[ATTR1:[0-9]+]] { 41; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0) 42; CHECK-NEXT: call void @__tsan_func_entry(ptr [[TMP1]]) 43; CHECK-NEXT: call void @cannot_throw() 44; CHECK-NEXT: call void @__tsan_func_exit() 45; CHECK-NEXT: ret i32 0 46; 47 call void @cannot_throw() 48 ret i32 0 49} 50 51define i32 @func3(ptr %p) sanitize_thread { 52; CHECK-LABEL: define i32 @func3 53; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR1]] { 54; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0) 55; CHECK-NEXT: call void @__tsan_func_entry(ptr [[TMP1]]) 56; CHECK-NEXT: call void @__tsan_read4(ptr [[P]]) 57; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 58; CHECK-NEXT: call void @__tsan_func_exit() 59; CHECK-NEXT: ret i32 [[A]] 60; 61 %a = load i32, ptr %p 62 ret i32 %a 63} 64 65define i32 @func4() sanitize_thread nounwind { 66; CHECK-LABEL: define i32 @func4 67; CHECK-SAME: () #[[ATTR2:[0-9]+]] { 68; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0) 69; CHECK-NEXT: call void @__tsan_func_entry(ptr [[TMP1]]) 70; CHECK-NEXT: call void @can_throw() 71; CHECK-NEXT: call void @__tsan_func_exit() 72; CHECK-NEXT: ret i32 0 73; 74 call void @can_throw() 75 ret i32 0 76} 77