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 8 define i8 @aligned1(i8* %a) { 9 entry: 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 30 define i16 @aligned2(i16* %a) { 31 entry: 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 51 define i32 @aligned4(i32* %a) { 52 entry: 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 72 define i64 @aligned8(i64* %a) { 73 entry: 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 93 define i128 @aligned16(i128* %a) { 94 entry: 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 118 define i16 @unaligned2(i16* %a) { 119 entry: 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 139 define i32 @unaligned4(i32* %a) { 140 entry: 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 160 define i64 @unaligned8(i64* %a) { 161 entry: 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 181 define i128 @unaligned16(i128* %a) { 182 entry: 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 205 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) 206 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) 207 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) 208 209 define void @memCpyTest(i8* nocapture %x, i8* nocapture %y) { 210 entry: 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 218 define void @memMoveTest(i8* nocapture %x, i8* nocapture %y) { 219 entry: 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 227 define void @memSetTest(i8* nocapture %x) { 228 entry: 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