1; Test basic EfficiencySanitizer working set instrumentation. 2; 3; RUN: opt < %s -esan -esan-working-set -S | FileCheck %s 4 5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6; Intra-cache-line 7 8define i8 @aligned1(i8* %a) { 9entry: 10 %tmp1 = load i8, i8* %a, align 1 11 ret i8 %tmp1 12; CHECK: @llvm.global_ctors = {{.*}}@esan.module_ctor 13; CHECK: %0 = ptrtoint i8* %a to i64 14; CHECK-NEXT: %1 = and i64 %0, 17592186044415 15; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 16; CHECK-NEXT: %3 = lshr i64 %2, 6 17; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 18; CHECK-NEXT: %5 = load i8, i8* %4 19; CHECK-NEXT: %6 = and i8 %5, -127 20; CHECK-NEXT: %7 = icmp ne i8 %6, -127 21; CHECK-NEXT: br i1 %7, label %8, label %11 22; CHECK: %9 = or i8 %5, -127 23; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 24; CHECK-NEXT: store i8 %9, i8* %10 25; CHECK-NEXT: br label %11 26; CHECK: %tmp1 = load i8, i8* %a, align 1 27; CHECK-NEXT: ret i8 %tmp1 28} 29 30define i16 @aligned2(i16* %a) { 31entry: 32 %tmp1 = load i16, i16* %a, align 2 33 ret i16 %tmp1 34; CHECK: %0 = ptrtoint i16* %a to i64 35; CHECK-NEXT: %1 = and i64 %0, 17592186044415 36; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 37; CHECK-NEXT: %3 = lshr i64 %2, 6 38; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 39; CHECK-NEXT: %5 = load i8, i8* %4 40; CHECK-NEXT: %6 = and i8 %5, -127 41; CHECK-NEXT: %7 = icmp ne i8 %6, -127 42; CHECK-NEXT: br i1 %7, label %8, label %11 43; CHECK: %9 = or i8 %5, -127 44; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 45; CHECK-NEXT: store i8 %9, i8* %10 46; CHECK-NEXT: br label %11 47; CHECK: %tmp1 = load i16, i16* %a, align 2 48; CHECK-NEXT: ret i16 %tmp1 49} 50 51define i32 @aligned4(i32* %a) { 52entry: 53 %tmp1 = load i32, i32* %a, align 4 54 ret i32 %tmp1 55; CHECK: %0 = ptrtoint i32* %a to i64 56; CHECK-NEXT: %1 = and i64 %0, 17592186044415 57; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 58; CHECK-NEXT: %3 = lshr i64 %2, 6 59; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 60; CHECK-NEXT: %5 = load i8, i8* %4 61; CHECK-NEXT: %6 = and i8 %5, -127 62; CHECK-NEXT: %7 = icmp ne i8 %6, -127 63; CHECK-NEXT: br i1 %7, label %8, label %11 64; CHECK: %9 = or i8 %5, -127 65; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 66; CHECK-NEXT: store i8 %9, i8* %10 67; CHECK-NEXT: br label %11 68; CHECK: %tmp1 = load i32, i32* %a, align 4 69; CHECK-NEXT: ret i32 %tmp1 70} 71 72define i64 @aligned8(i64* %a) { 73entry: 74 %tmp1 = load i64, i64* %a, align 8 75 ret i64 %tmp1 76; CHECK: %0 = ptrtoint i64* %a to i64 77; CHECK-NEXT: %1 = and i64 %0, 17592186044415 78; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 79; CHECK-NEXT: %3 = lshr i64 %2, 6 80; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 81; CHECK-NEXT: %5 = load i8, i8* %4 82; CHECK-NEXT: %6 = and i8 %5, -127 83; CHECK-NEXT: %7 = icmp ne i8 %6, -127 84; CHECK-NEXT: br i1 %7, label %8, label %11 85; CHECK: %9 = or i8 %5, -127 86; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 87; CHECK-NEXT: store i8 %9, i8* %10 88; CHECK-NEXT: br label %11 89; CHECK: %tmp1 = load i64, i64* %a, align 8 90; CHECK-NEXT: ret i64 %tmp1 91} 92 93define i128 @aligned16(i128* %a) { 94entry: 95 %tmp1 = load i128, i128* %a, align 16 96 ret i128 %tmp1 97; CHECK: %0 = ptrtoint i128* %a to i64 98; CHECK-NEXT: %1 = and i64 %0, 17592186044415 99; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 100; CHECK-NEXT: %3 = lshr i64 %2, 6 101; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 102; CHECK-NEXT: %5 = load i8, i8* %4 103; CHECK-NEXT: %6 = and i8 %5, -127 104; CHECK-NEXT: %7 = icmp ne i8 %6, -127 105; CHECK-NEXT: br i1 %7, label %8, label %11 106; CHECK: %9 = or i8 %5, -127 107; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 108; CHECK-NEXT: store i8 %9, i8* %10 109; CHECK-NEXT: br label %11 110; CHECK: %tmp1 = load i128, i128* %a, align 16 111; CHECK-NEXT: ret i128 %tmp1 112} 113 114;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 115; Not guaranteed to be intra-cache-line, but our defaults are to 116; assume they are: 117 118define i16 @unaligned2(i16* %a) { 119entry: 120 %tmp1 = load i16, i16* %a, align 1 121 ret i16 %tmp1 122; CHECK: %0 = ptrtoint i16* %a to i64 123; CHECK-NEXT: %1 = and i64 %0, 17592186044415 124; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 125; CHECK-NEXT: %3 = lshr i64 %2, 6 126; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 127; CHECK-NEXT: %5 = load i8, i8* %4 128; CHECK-NEXT: %6 = and i8 %5, -127 129; CHECK-NEXT: %7 = icmp ne i8 %6, -127 130; CHECK-NEXT: br i1 %7, label %8, label %11 131; CHECK: %9 = or i8 %5, -127 132; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 133; CHECK-NEXT: store i8 %9, i8* %10 134; CHECK-NEXT: br label %11 135; CHECK: %tmp1 = load i16, i16* %a, align 1 136; CHECK-NEXT: ret i16 %tmp1 137} 138 139define i32 @unaligned4(i32* %a) { 140entry: 141 %tmp1 = load i32, i32* %a, align 2 142 ret i32 %tmp1 143; CHECK: %0 = ptrtoint i32* %a to i64 144; CHECK-NEXT: %1 = and i64 %0, 17592186044415 145; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 146; CHECK-NEXT: %3 = lshr i64 %2, 6 147; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 148; CHECK-NEXT: %5 = load i8, i8* %4 149; CHECK-NEXT: %6 = and i8 %5, -127 150; CHECK-NEXT: %7 = icmp ne i8 %6, -127 151; CHECK-NEXT: br i1 %7, label %8, label %11 152; CHECK: %9 = or i8 %5, -127 153; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 154; CHECK-NEXT: store i8 %9, i8* %10 155; CHECK-NEXT: br label %11 156; CHECK: %tmp1 = load i32, i32* %a, align 2 157; CHECK-NEXT: ret i32 %tmp1 158} 159 160define i64 @unaligned8(i64* %a) { 161entry: 162 %tmp1 = load i64, i64* %a, align 4 163 ret i64 %tmp1 164; CHECK: %0 = ptrtoint i64* %a to i64 165; CHECK-NEXT: %1 = and i64 %0, 17592186044415 166; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 167; CHECK-NEXT: %3 = lshr i64 %2, 6 168; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 169; CHECK-NEXT: %5 = load i8, i8* %4 170; CHECK-NEXT: %6 = and i8 %5, -127 171; CHECK-NEXT: %7 = icmp ne i8 %6, -127 172; CHECK-NEXT: br i1 %7, label %8, label %11 173; CHECK: %9 = or i8 %5, -127 174; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 175; CHECK-NEXT: store i8 %9, i8* %10 176; CHECK-NEXT: br label %11 177; CHECK: %tmp1 = load i64, i64* %a, align 4 178; CHECK-NEXT: ret i64 %tmp1 179} 180 181define i128 @unaligned16(i128* %a) { 182entry: 183 %tmp1 = load i128, i128* %a, align 8 184 ret i128 %tmp1 185; CHECK: %0 = ptrtoint i128* %a to i64 186; CHECK-NEXT: %1 = and i64 %0, 17592186044415 187; CHECK-NEXT: %2 = add i64 %1, 1337006139375616 188; CHECK-NEXT: %3 = lshr i64 %2, 6 189; CHECK-NEXT: %4 = inttoptr i64 %3 to i8* 190; CHECK-NEXT: %5 = load i8, i8* %4 191; CHECK-NEXT: %6 = and i8 %5, -127 192; CHECK-NEXT: %7 = icmp ne i8 %6, -127 193; CHECK-NEXT: br i1 %7, label %8, label %11 194; CHECK: %9 = or i8 %5, -127 195; CHECK-NEXT: %10 = inttoptr i64 %3 to i8* 196; CHECK-NEXT: store i8 %9, i8* %10 197; CHECK-NEXT: br label %11 198; CHECK: %tmp1 = load i128, i128* %a, align 8 199; CHECK-NEXT: ret i128 %tmp1 200} 201 202;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 203; Ensure that esan converts intrinsics to calls: 204 205declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) 206declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) 207declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) 208 209define void @memCpyTest(i8* nocapture %x, i8* nocapture %y) { 210entry: 211 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x, i8* %y, i64 16, i32 4, i1 false) 212 ret void 213; CHECK: define void @memCpyTest 214; CHECK: call i8* @memcpy 215; CHECK: ret void 216} 217 218define void @memMoveTest(i8* nocapture %x, i8* nocapture %y) { 219entry: 220 tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %x, i8* %y, i64 16, i32 4, i1 false) 221 ret void 222; CHECK: define void @memMoveTest 223; CHECK: call i8* @memmove 224; CHECK: ret void 225} 226 227define void @memSetTest(i8* nocapture %x) { 228entry: 229 tail call void @llvm.memset.p0i8.i64(i8* %x, i8 77, i64 16, i32 4, i1 false) 230 ret void 231; CHECK: define void @memSetTest 232; CHECK: call i8* @memset 233; CHECK: ret void 234} 235 236;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 237; Top-level: 238 239; CHECK: define internal void @esan.module_ctor() 240; CHECK: call void @__esan_init(i32 2, i8* null) 241; CHECK: define internal void @esan.module_dtor() 242; CHECK: call void @__esan_exit(i8* null) 243