1; RUN: opt < %s -passes=tsan -tsan-distinguish-volatile -S | FileCheck %s 2 3target 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" 4 5define i16 @test_volatile_read2(ptr %a) sanitize_thread { 6entry: 7 %tmp1 = load volatile i16, ptr %a, align 2 8 ret i16 %tmp1 9} 10 11; CHECK-LABEL: define i16 @test_volatile_read2(ptr %a) 12; CHECK: call void @__tsan_func_entry(ptr %0) 13; CHECK-NEXT: call void @__tsan_volatile_read2(ptr %a) 14; CHECK-NEXT: %tmp1 = load volatile i16, ptr %a, align 2 15; CHECK-NEXT: call void @__tsan_func_exit() 16; CHECK: ret i16 17 18define i32 @test_volatile_read4(ptr %a) sanitize_thread { 19entry: 20 %tmp1 = load volatile i32, ptr %a, align 4 21 ret i32 %tmp1 22} 23 24; CHECK-LABEL: define i32 @test_volatile_read4(ptr %a) 25; CHECK: call void @__tsan_func_entry(ptr %0) 26; CHECK-NEXT: call void @__tsan_volatile_read4(ptr %a) 27; CHECK-NEXT: %tmp1 = load volatile i32, ptr %a, align 4 28; CHECK-NEXT: call void @__tsan_func_exit() 29; CHECK: ret i32 30 31define i64 @test_volatile_read8(ptr %a) sanitize_thread { 32entry: 33 %tmp1 = load volatile i64, ptr %a, align 8 34 ret i64 %tmp1 35} 36 37; CHECK-LABEL: define i64 @test_volatile_read8(ptr %a) 38; CHECK: call void @__tsan_func_entry(ptr %0) 39; CHECK-NEXT: call void @__tsan_volatile_read8(ptr %a) 40; CHECK-NEXT: %tmp1 = load volatile i64, ptr %a, align 8 41; CHECK-NEXT: call void @__tsan_func_exit() 42; CHECK: ret i64 43 44define i128 @test_volatile_read16(ptr %a) sanitize_thread { 45entry: 46 %tmp1 = load volatile i128, ptr %a, align 16 47 ret i128 %tmp1 48} 49 50; CHECK-LABEL: define i128 @test_volatile_read16(ptr %a) 51; CHECK: call void @__tsan_func_entry(ptr %0) 52; CHECK-NEXT: call void @__tsan_volatile_read16(ptr %a) 53; CHECK-NEXT: %tmp1 = load volatile i128, ptr %a, align 16 54; CHECK-NEXT: call void @__tsan_func_exit() 55; CHECK: ret i128 56 57define void @test_volatile_write2(ptr %a) sanitize_thread { 58entry: 59 store volatile i16 1, ptr %a, align 2 60 ret void 61} 62 63; CHECK-LABEL: define void @test_volatile_write2(ptr %a) 64; CHECK: call void @__tsan_func_entry(ptr %0) 65; CHECK-NEXT: call void @__tsan_volatile_write2(ptr %a) 66; CHECK-NEXT: store volatile i16 1, ptr %a, align 2 67; CHECK-NEXT: call void @__tsan_func_exit() 68; CHECK: ret void 69 70define void @test_volatile_write4(ptr %a) sanitize_thread { 71entry: 72 store volatile i32 1, ptr %a, align 4 73 ret void 74} 75 76; CHECK-LABEL: define void @test_volatile_write4(ptr %a) 77; CHECK: call void @__tsan_func_entry(ptr %0) 78; CHECK-NEXT: call void @__tsan_volatile_write4(ptr %a) 79; CHECK-NEXT: store volatile i32 1, ptr %a, align 4 80; CHECK-NEXT: call void @__tsan_func_exit() 81; CHECK: ret void 82 83define void @test_volatile_write8(ptr %a) sanitize_thread { 84entry: 85 store volatile i64 1, ptr %a, align 8 86 ret void 87} 88 89; CHECK-LABEL: define void @test_volatile_write8(ptr %a) 90; CHECK: call void @__tsan_func_entry(ptr %0) 91; CHECK-NEXT: call void @__tsan_volatile_write8(ptr %a) 92; CHECK-NEXT: store volatile i64 1, ptr %a, align 8 93; CHECK-NEXT: call void @__tsan_func_exit() 94; CHECK: ret void 95 96define void @test_volatile_write16(ptr %a) sanitize_thread { 97entry: 98 store volatile i128 1, ptr %a, align 16 99 ret void 100} 101 102; CHECK-LABEL: define void @test_volatile_write16(ptr %a) 103; CHECK: call void @__tsan_func_entry(ptr %0) 104; CHECK-NEXT: call void @__tsan_volatile_write16(ptr %a) 105; CHECK-NEXT: store volatile i128 1, ptr %a, align 16 106; CHECK-NEXT: call void @__tsan_func_exit() 107; CHECK: ret void 108 109; Check unaligned volatile accesses 110 111define i32 @test_unaligned_read4(ptr %a) sanitize_thread { 112entry: 113 %tmp1 = load volatile i32, ptr %a, align 2 114 ret i32 %tmp1 115} 116 117; CHECK-LABEL: define i32 @test_unaligned_read4(ptr %a) 118; CHECK: call void @__tsan_func_entry(ptr %0) 119; CHECK-NEXT: call void @__tsan_unaligned_volatile_read4(ptr %a) 120; CHECK-NEXT: %tmp1 = load volatile i32, ptr %a, align 2 121; CHECK-NEXT: call void @__tsan_func_exit() 122; CHECK: ret i32 123 124define void @test_unaligned_write4(ptr %a) sanitize_thread { 125entry: 126 store volatile i32 1, ptr %a, align 1 127 ret void 128} 129 130; CHECK-LABEL: define void @test_unaligned_write4(ptr %a) 131; CHECK: call void @__tsan_func_entry(ptr %0) 132; CHECK-NEXT: call void @__tsan_unaligned_volatile_write4(ptr %a) 133; CHECK-NEXT: store volatile i32 1, ptr %a, align 1 134; CHECK-NEXT: call void @__tsan_func_exit() 135; CHECK: ret void 136 137; Check that regular aligned accesses are unaffected 138 139define i32 @test_read4(ptr %a) sanitize_thread { 140entry: 141 %tmp1 = load i32, ptr %a, align 4 142 ret i32 %tmp1 143} 144 145; CHECK-LABEL: define i32 @test_read4(ptr %a) 146; CHECK: call void @__tsan_func_entry(ptr %0) 147; CHECK-NEXT: call void @__tsan_read4(ptr %a) 148; CHECK-NEXT: %tmp1 = load i32, ptr %a, align 4 149; CHECK-NEXT: call void @__tsan_func_exit() 150; CHECK: ret i32 151 152define void @test_write4(ptr %a) sanitize_thread { 153entry: 154 store i32 1, ptr %a, align 4 155 ret void 156} 157 158; CHECK-LABEL: define void @test_write4(ptr %a) 159; CHECK: call void @__tsan_func_entry(ptr %0) 160; CHECK-NEXT: call void @__tsan_write4(ptr %a) 161; CHECK-NEXT: store i32 1, ptr %a, align 4 162; CHECK-NEXT: call void @__tsan_func_exit() 163; CHECK: ret void 164