1 ; Test basic EfficiencySanitizer slowpath instrumentation. 2 ; 3 ; RUN: opt < %s -esan -esan-working-set -esan-instrument-fastpath=false -S | FileCheck %s 4 5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 ; Aligned loads: 7 8 define i8 @loadAligned1(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: call void @__esan_aligned_load1(i8* %a) 14 ; CHECK-NEXT: %tmp1 = load i8, i8* %a, align 1 15 ; CHECK-NEXT: ret i8 %tmp1 16 } 17 18 define i16 @loadAligned2(i16* %a) { 19 entry: 20 %tmp1 = load i16, i16* %a, align 2 21 ret i16 %tmp1 22 ; CHECK: %0 = bitcast i16* %a to i8* 23 ; CHECK-NEXT: call void @__esan_aligned_load2(i8* %0) 24 ; CHECK-NEXT: %tmp1 = load i16, i16* %a, align 2 25 ; CHECK-NEXT: ret i16 %tmp1 26 } 27 28 define i32 @loadAligned4(i32* %a) { 29 entry: 30 %tmp1 = load i32, i32* %a, align 4 31 ret i32 %tmp1 32 ; CHECK: %0 = bitcast i32* %a to i8* 33 ; CHECK-NEXT: call void @__esan_aligned_load4(i8* %0) 34 ; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 4 35 ; CHECK-NEXT: ret i32 %tmp1 36 } 37 38 define i64 @loadAligned8(i64* %a) { 39 entry: 40 %tmp1 = load i64, i64* %a, align 8 41 ret i64 %tmp1 42 ; CHECK: %0 = bitcast i64* %a to i8* 43 ; CHECK-NEXT: call void @__esan_aligned_load8(i8* %0) 44 ; CHECK-NEXT: %tmp1 = load i64, i64* %a, align 8 45 ; CHECK-NEXT: ret i64 %tmp1 46 } 47 48 define i128 @loadAligned16(i128* %a) { 49 entry: 50 %tmp1 = load i128, i128* %a, align 16 51 ret i128 %tmp1 52 ; CHECK: %0 = bitcast i128* %a to i8* 53 ; CHECK-NEXT: call void @__esan_aligned_load16(i8* %0) 54 ; CHECK-NEXT: %tmp1 = load i128, i128* %a, align 16 55 ; CHECK-NEXT: ret i128 %tmp1 56 } 57 58 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 59 ; Aligned stores: 60 61 define void @storeAligned1(i8* %a) { 62 entry: 63 store i8 1, i8* %a, align 1 64 ret void 65 ; CHECK: call void @__esan_aligned_store1(i8* %a) 66 ; CHECK-NEXT: store i8 1, i8* %a, align 1 67 ; CHECK-NEXT: ret void 68 } 69 70 define void @storeAligned2(i16* %a) { 71 entry: 72 store i16 1, i16* %a, align 2 73 ret void 74 ; CHECK: %0 = bitcast i16* %a to i8* 75 ; CHECK-NEXT: call void @__esan_aligned_store2(i8* %0) 76 ; CHECK-NEXT: store i16 1, i16* %a, align 2 77 ; CHECK-NEXT: ret void 78 } 79 80 define void @storeAligned4(i32* %a) { 81 entry: 82 store i32 1, i32* %a, align 4 83 ret void 84 ; CHECK: %0 = bitcast i32* %a to i8* 85 ; CHECK-NEXT: call void @__esan_aligned_store4(i8* %0) 86 ; CHECK-NEXT: store i32 1, i32* %a, align 4 87 ; CHECK-NEXT: ret void 88 } 89 90 define void @storeAligned8(i64* %a) { 91 entry: 92 store i64 1, i64* %a, align 8 93 ret void 94 ; CHECK: %0 = bitcast i64* %a to i8* 95 ; CHECK-NEXT: call void @__esan_aligned_store8(i8* %0) 96 ; CHECK-NEXT: store i64 1, i64* %a, align 8 97 ; CHECK-NEXT: ret void 98 } 99 100 define void @storeAligned16(i128* %a) { 101 entry: 102 store i128 1, i128* %a, align 16 103 ret void 104 ; CHECK: %0 = bitcast i128* %a to i8* 105 ; CHECK-NEXT: call void @__esan_aligned_store16(i8* %0) 106 ; CHECK-NEXT: store i128 1, i128* %a, align 16 107 ; CHECK-NEXT: ret void 108 } 109 110 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 111 ; Unaligned loads: 112 113 define i16 @loadUnaligned2(i16* %a) { 114 entry: 115 %tmp1 = load i16, i16* %a, align 1 116 ret i16 %tmp1 117 ; CHECK: %0 = bitcast i16* %a to i8* 118 ; CHECK-NEXT: call void @__esan_unaligned_load2(i8* %0) 119 ; CHECK-NEXT: %tmp1 = load i16, i16* %a, align 1 120 ; CHECK-NEXT: ret i16 %tmp1 121 } 122 123 define i32 @loadUnaligned4(i32* %a) { 124 entry: 125 %tmp1 = load i32, i32* %a, align 1 126 ret i32 %tmp1 127 ; CHECK: %0 = bitcast i32* %a to i8* 128 ; CHECK-NEXT: call void @__esan_unaligned_load4(i8* %0) 129 ; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 1 130 ; CHECK-NEXT: ret i32 %tmp1 131 } 132 133 define i64 @loadUnaligned8(i64* %a) { 134 entry: 135 %tmp1 = load i64, i64* %a, align 1 136 ret i64 %tmp1 137 ; CHECK: %0 = bitcast i64* %a to i8* 138 ; CHECK-NEXT: call void @__esan_unaligned_load8(i8* %0) 139 ; CHECK-NEXT: %tmp1 = load i64, i64* %a, align 1 140 ; CHECK-NEXT: ret i64 %tmp1 141 } 142 143 define i128 @loadUnaligned16(i128* %a) { 144 entry: 145 %tmp1 = load i128, i128* %a, align 1 146 ret i128 %tmp1 147 ; CHECK: %0 = bitcast i128* %a to i8* 148 ; CHECK-NEXT: call void @__esan_unaligned_load16(i8* %0) 149 ; CHECK-NEXT: %tmp1 = load i128, i128* %a, align 1 150 ; CHECK-NEXT: ret i128 %tmp1 151 } 152 153 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 154 ; Unaligned stores: 155 156 define void @storeUnaligned2(i16* %a) { 157 entry: 158 store i16 1, i16* %a, align 1 159 ret void 160 ; CHECK: %0 = bitcast i16* %a to i8* 161 ; CHECK-NEXT: call void @__esan_unaligned_store2(i8* %0) 162 ; CHECK-NEXT: store i16 1, i16* %a, align 1 163 ; CHECK-NEXT: ret void 164 } 165 166 define void @storeUnaligned4(i32* %a) { 167 entry: 168 store i32 1, i32* %a, align 1 169 ret void 170 ; CHECK: %0 = bitcast i32* %a to i8* 171 ; CHECK-NEXT: call void @__esan_unaligned_store4(i8* %0) 172 ; CHECK-NEXT: store i32 1, i32* %a, align 1 173 ; CHECK-NEXT: ret void 174 } 175 176 define void @storeUnaligned8(i64* %a) { 177 entry: 178 store i64 1, i64* %a, align 1 179 ret void 180 ; CHECK: %0 = bitcast i64* %a to i8* 181 ; CHECK-NEXT: call void @__esan_unaligned_store8(i8* %0) 182 ; CHECK-NEXT: store i64 1, i64* %a, align 1 183 ; CHECK-NEXT: ret void 184 } 185 186 define void @storeUnaligned16(i128* %a) { 187 entry: 188 store i128 1, i128* %a, align 1 189 ret void 190 ; CHECK: %0 = bitcast i128* %a to i8* 191 ; CHECK-NEXT: call void @__esan_unaligned_store16(i8* %0) 192 ; CHECK-NEXT: store i128 1, i128* %a, align 1 193 ; CHECK-NEXT: ret void 194 } 195 196 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 197 ; Unusual loads and stores: 198 199 define x86_fp80 @loadUnalignedFP(x86_fp80* %a) { 200 entry: 201 %tmp1 = load x86_fp80, x86_fp80* %a, align 1 202 ret x86_fp80 %tmp1 203 ; CHECK: %0 = bitcast x86_fp80* %a to i8* 204 ; CHECK-NEXT: call void @__esan_unaligned_loadN(i8* %0, i64 10) 205 ; CHECK-NEXT: %tmp1 = load x86_fp80, x86_fp80* %a, align 1 206 ; CHECK-NEXT: ret x86_fp80 %tmp1 207 } 208 209 define void @storeUnalignedFP(x86_fp80* %a) { 210 entry: 211 store x86_fp80 0xK00000000000000000000, x86_fp80* %a, align 1 212 ret void 213 ; CHECK: %0 = bitcast x86_fp80* %a to i8* 214 ; CHECK-NEXT: call void @__esan_unaligned_storeN(i8* %0, i64 10) 215 ; CHECK-NEXT: store x86_fp80 0xK00000000000000000000, x86_fp80* %a, align 1 216 ; CHECK-NEXT: ret void 217 } 218 219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 220 ; Ensure that esan converts memcpy intrinsics to calls: 221 222 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) 223 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) 224 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) 225 226 define void @memCpyTest(i8* nocapture %x, i8* nocapture %y) { 227 entry: 228 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x, i8* %y, i64 16, i32 4, i1 false) 229 ret void 230 ; CHECK: define void @memCpyTest 231 ; CHECK: call i8* @memcpy 232 ; CHECK: ret void 233 } 234 235 define void @memMoveTest(i8* nocapture %x, i8* nocapture %y) { 236 entry: 237 tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %x, i8* %y, i64 16, i32 4, i1 false) 238 ret void 239 ; CHECK: define void @memMoveTest 240 ; CHECK: call i8* @memmove 241 ; CHECK: ret void 242 } 243 244 define void @memSetTest(i8* nocapture %x) { 245 entry: 246 tail call void @llvm.memset.p0i8.i64(i8* %x, i8 77, i64 16, i32 4, i1 false) 247 ret void 248 ; CHECK: define void @memSetTest 249 ; CHECK: call i8* @memset 250 ; CHECK: ret void 251 } 252 253 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 254 ; Top-level: 255 256 ; CHECK: define internal void @esan.module_ctor() 257 ; CHECK: call void @__esan_init(i32 2, i8* null) 258 ; CHECK: define internal void @esan.module_dtor() 259 ; CHECK: call void @__esan_exit(i8* null) 260