264 lines · plain
1; RUN: opt < %s -passes=dfsan -S | FileCheck %s2; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN3; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -dfsan-instrument-with-call-threshold=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN4target 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"5target triple = "x86_64-unknown-linux-gnu"6 7; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]8; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]9define i32 @AtomicRmwXchg(ptr %p, i32 %x) {10entry:11 ; COMM: atomicrmw xchg: store clean shadow/origin, return clean shadow/origin12 13 ; CHECK-LABEL: @AtomicRmwXchg.dfsan14 ; CHECK-NOT: @__dfsan_arg_origin_tls15 ; CHECK-NOT: @__dfsan_arg_tls16 ; CHECK: %[[#INTP:]] = ptrtoint ptr %p to i6417 ; CHECK-NEXT: %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]18 ; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr19 ; CHECK-NEXT: store i[[#NUM_BITS:32]] 0, ptr %[[#SHADOW_PTR]], align 120 ; CHECK-NEXT: atomicrmw xchg ptr %p, i32 %x seq_cst21 ; CHECK-NEXT: store i8 0, ptr @__dfsan_retval_tls, align 222 ; CHECK_ORIGIN-NEXT: store i32 0, ptr @__dfsan_retval_origin_tls, align 423 ; CHECK-NEXT: ret i3224 25 %0 = atomicrmw xchg ptr %p, i32 %x seq_cst26 ret i32 %027}28 29define i32 @AtomicRmwMax(ptr %p, i32 %x) {30 ; COMM: atomicrmw max: exactly the same as above31 32 ; CHECK-LABEL: @AtomicRmwMax.dfsan33 ; CHECK-NOT: @__dfsan_arg_origin_tls34 ; CHECK-NOT: @__dfsan_arg_tls35 ; CHECK: %[[#INTP:]] = ptrtoint ptr %p to i6436 ; CHECK-NEXT: %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]37 ; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr38 ; CHECK-NEXT: store i[[#NUM_BITS]] 0, ptr %[[#SHADOW_PTR]], align 139 ; CHECK-NEXT: atomicrmw max ptr %p, i32 %x seq_cst40 ; CHECK-NEXT: store i8 0, ptr @__dfsan_retval_tls, align 241 ; CHECK_ORIGIN-NEXT: store i32 0, ptr @__dfsan_retval_origin_tls, align 442 ; CHECK-NEXT: ret i3243 44entry:45 %0 = atomicrmw max ptr %p, i32 %x seq_cst46 ret i32 %047}48 49 50define i32 @Cmpxchg(ptr %p, i32 %a, i32 %b) {51 ; COMM: cmpxchg: store clean shadow/origin, return clean shadow/origin52 53 ; CHECK-LABEL: @Cmpxchg.dfsan54 ; CHECK-NOT: @__dfsan_arg_origin_tls55 ; CHECK-NOT: @__dfsan_arg_tls56 ; CHECK: %[[#INTP:]] = ptrtoint ptr %p to i6457 ; CHECK-NEXT: %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]58 ; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr59 ; CHECK-NEXT: store i[[#NUM_BITS]] 0, ptr %[[#SHADOW_PTR]], align 160 ; CHECK-NEXT: %pair = cmpxchg ptr %p, i32 %a, i32 %b seq_cst seq_cst61 ; CHECK: store i8 0, ptr @__dfsan_retval_tls, align 262 ; CHECK_ORIGIN-NEXT: store i32 0, ptr @__dfsan_retval_origin_tls, align 463 ; CHECK-NEXT: ret i3264 65entry:66 %pair = cmpxchg ptr %p, i32 %a, i32 %b seq_cst seq_cst67 %0 = extractvalue { i32, i1 } %pair, 068 ret i32 %069}70 71 72define i32 @CmpxchgMonotonic(ptr %p, i32 %a, i32 %b) {73 ; COMM: relaxed cmpxchg: bump up to "release monotonic"74 75 ; CHECK-LABEL: @CmpxchgMonotonic.dfsan76 ; CHECK-NOT: @__dfsan_arg_origin_tls77 ; CHECK-NOT: @__dfsan_arg_tls78 ; CHECK: %[[#INTP:]] = ptrtoint ptr %p to i6479 ; CHECK-NEXT: %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]80 ; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr81 ; CHECK-NEXT: store i[[#NUM_BITS]] 0, ptr %[[#SHADOW_PTR]], align 182 ; CHECK-NEXT: %pair = cmpxchg ptr %p, i32 %a, i32 %b release monotonic83 ; CHECK: store i8 0, ptr @__dfsan_retval_tls, align 284 ; CHECK_ORIGIN-NEXT: store i32 0, ptr @__dfsan_retval_origin_tls, align 485 ; CHECK-NEXT: ret i3286 87entry:88 %pair = cmpxchg ptr %p, i32 %a, i32 %b monotonic monotonic89 %0 = extractvalue { i32, i1 } %pair, 090 ret i32 %091}92 93 94 95define i32 @AtomicLoad(ptr %p) {96 ; COMM: atomic load: load shadow value after app value97 98 ; CHECK-LABEL: @AtomicLoad.dfsan99 ; CHECK_ORIGIN: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4100 ; CHECK: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align 2101 ; CHECK: %a = load atomic i32, ptr %p seq_cst, align 16102 ; CHECK: %[[#SHADOW_PTR:]] = inttoptr i64 {{.*}} to ptr103 ; CHECK_ORIGIN: %[[#ORIGIN_PTR:]] = inttoptr i64 {{.*}} to ptr104 ; CHECK_ORIGIN: %[[#AO:]] = load i32, ptr %[[#ORIGIN_PTR]], align 16105 ; CHECK: load i[[#NUM_BITS]], ptr %[[#SHADOW_PTR]], align 1106 ; CHECK: %[[#AP_S:]] = or i8 {{.*}}, %[[#PS]]107 ; CHECK_ORIGIN: %[[#PS_NZ:]] = icmp ne i8 %[[#PS]], 0108 ; CHECK_ORIGIN: %[[#AP_O:]] = select i1 %[[#PS_NZ]], i32 %[[#PO]], i32 %[[#AO]]109 ; CHECK: store i8 %[[#AP_S]], ptr @__dfsan_retval_tls, align 2110 ; CHECK_ORIGIN: store i32 %[[#AP_O]], ptr @__dfsan_retval_origin_tls, align 4111 ; CHECK: ret i32 %a112 113entry:114 %a = load atomic i32, ptr %p seq_cst, align 16115 ret i32 %a116}117 118 119define i32 @AtomicLoadAcquire(ptr %p) {120 ; COMM: atomic load: load shadow value after app value121 122 ; CHECK-LABEL: @AtomicLoadAcquire.dfsan123 ; CHECK_ORIGIN: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4124 ; CHECK: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align 2125 ; CHECK: %a = load atomic i32, ptr %p acquire, align 16126 ; CHECK: %[[#SHADOW_PTR:]] = inttoptr i64 {{.*}} to ptr127 ; CHECK_ORIGIN: %[[#ORIGIN_PTR:]] = inttoptr i64 {{.*}} to ptr128 ; CHECK_ORIGIN: %[[#AO:]] = load i32, ptr %[[#ORIGIN_PTR]], align 16129 ; CHECK: load i[[#NUM_BITS]], ptr %[[#SHADOW_PTR]], align 1130 ; CHECK: %[[#AP_S:]] = or i8 {{.*}}, %[[#PS]]131 ; CHECK_ORIGIN: %[[#PS_NZ:]] = icmp ne i8 %[[#PS]], 0132 ; CHECK_ORIGIN: %[[#AP_O:]] = select i1 %[[#PS_NZ]], i32 %[[#PO]], i32 %[[#AO]]133 ; CHECK: store i8 %[[#AP_S]], ptr @__dfsan_retval_tls, align 2134 ; CHECK_ORIGIN: store i32 %[[#AP_O]], ptr @__dfsan_retval_origin_tls, align 4135 ; CHECK: ret i32 %a136 137entry:138 %a = load atomic i32, ptr %p acquire, align 16139 ret i32 %a140}141 142 143define i32 @AtomicLoadMonotonic(ptr %p) {144 ; COMM: atomic load monotonic: bump up to load acquire145 146 ; CHECK-LABEL: @AtomicLoadMonotonic.dfsan147 ; CHECK_ORIGIN: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4148 ; CHECK: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align 2149 ; CHECK: %a = load atomic i32, ptr %p acquire, align 16150 ; CHECK: %[[#SHADOW_PTR:]] = inttoptr i64 {{.*}} to ptr151 ; CHECK_ORIGIN: %[[#ORIGIN_PTR:]] = inttoptr i64 {{.*}} to ptr152 ; CHECK_ORIGIN: %[[#AO:]] = load i32, ptr %[[#ORIGIN_PTR]], align 16153 ; CHECK: load i[[#NUM_BITS]], ptr %[[#SHADOW_PTR]], align 1154 ; CHECK: %[[#AP_S:]] = or i8 {{.*}}, %[[#PS]]155 ; CHECK_ORIGIN: %[[#PS_NZ:]] = icmp ne i8 %[[#PS]], 0156 ; CHECK_ORIGIN: %[[#AP_O:]] = select i1 %[[#PS_NZ]], i32 %[[#PO]], i32 %[[#AO]]157 ; CHECK: store i8 %[[#AP_S]], ptr @__dfsan_retval_tls, align 2158 ; CHECK_ORIGIN: store i32 %[[#AP_O]], ptr @__dfsan_retval_origin_tls, align 4159 ; CHECK: ret i32 %a160 161entry:162 %a = load atomic i32, ptr %p monotonic, align 16163 ret i32 %a164}165 166define i32 @AtomicLoadUnordered(ptr %p) {167 ; COMM: atomic load unordered: bump up to load acquire168 169 ; CHECK-LABEL: @AtomicLoadUnordered.dfsan170 ; CHECK_ORIGIN: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4171 ; CHECK: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align 2172 ; CHECK: %a = load atomic i32, ptr %p acquire, align 16173 ; CHECK: %[[#SHADOW_PTR:]] = inttoptr i64 {{.*}} to ptr174 ; CHECK_ORIGIN: %[[#ORIGIN_PTR:]] = inttoptr i64 {{.*}} to ptr175 ; CHECK_ORIGIN: %[[#AO:]] = load i32, ptr %[[#ORIGIN_PTR]], align 16176 ; CHECK: load i[[#NUM_BITS]], ptr %[[#SHADOW_PTR]], align 1177 ; CHECK: %[[#AP_S:]] = or i8 {{.*}}, %[[#PS]]178 ; CHECK_ORIGIN: %[[#PS_NZ:]] = icmp ne i8 %[[#PS]], 0179 ; CHECK_ORIGIN: %[[#AP_O:]] = select i1 %[[#PS_NZ]], i32 %[[#PO]], i32 %[[#AO]]180 ; CHECK: store i8 %[[#AP_S]], ptr @__dfsan_retval_tls, align 2181 ; CHECK_ORIGIN: store i32 %[[#AP_O]], ptr @__dfsan_retval_origin_tls, align 4182 ; CHECK: ret i32 %a183 184entry:185 %a = load atomic i32, ptr %p unordered, align 16186 ret i32 %a187}188 189define void @AtomicStore(ptr %p, i32 %x) {190 ; COMM: atomic store: store clean shadow value before app value191 192 ; CHECK-LABEL: @AtomicStore.dfsan193 ; CHECK-NOT: @__dfsan_arg_origin_tls194 ; CHECK-NOT: @__dfsan_arg_tls195 ; CHECK_ORIGIN-NOT: 35184372088832196 ; CHECK: %[[#INTP:]] = ptrtoint ptr %p to i64197 ; CHECK-NEXT: %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]198 ; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr199 ; CHECK-NEXT: store i[[#NUM_BITS]] 0, ptr %[[#SHADOW_PTR]], align 1200 ; CHECK: store atomic i32 %x, ptr %p seq_cst, align 16201 ; CHECK: ret void202 203entry:204 store atomic i32 %x, ptr %p seq_cst, align 16205 ret void206}207 208define void @AtomicStoreRelease(ptr %p, i32 %x) {209 ; COMM: atomic store: store clean shadow value before app value210 211 ; CHECK-LABEL: @AtomicStoreRelease.dfsan212 ; CHECK-NOT: @__dfsan_arg_origin_tls213 ; CHECK-NOT: @__dfsan_arg_tls214 ; CHECK_ORIGIN-NOT: 35184372088832215 ; CHECK: %[[#INTP:]] = ptrtoint ptr %p to i64216 ; CHECK-NEXT: %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]217 ; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr218 ; CHECK-NEXT: store i[[#NUM_BITS]] 0, ptr %[[#SHADOW_PTR]], align 1219 ; CHECK: store atomic i32 %x, ptr %p release, align 16220 ; CHECK: ret void221 222entry:223 store atomic i32 %x, ptr %p release, align 16224 ret void225}226 227define void @AtomicStoreMonotonic(ptr %p, i32 %x) {228 ; COMM: atomic store monotonic: bumped up to store release229 230 ; CHECK-LABEL: @AtomicStoreMonotonic.dfsan231 ; CHECK-NOT: @__dfsan_arg_origin_tls232 ; CHECK-NOT: @__dfsan_arg_tls233 ; CHECK_ORIGIN-NOT: 35184372088832234 ; CHECK: %[[#INTP:]] = ptrtoint ptr %p to i64235 ; CHECK-NEXT: %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]236 ; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr237 ; CHECK-NEXT: store i[[#NUM_BITS]] 0, ptr %[[#SHADOW_PTR]], align 1238 ; CHECK: store atomic i32 %x, ptr %p release, align 16239 ; CHECK: ret void240 241entry:242 store atomic i32 %x, ptr %p monotonic, align 16243 ret void244}245 246define void @AtomicStoreUnordered(ptr %p, i32 %x) {247 ; COMM: atomic store unordered: bumped up to store release248 249 ; CHECK-LABEL: @AtomicStoreUnordered.dfsan250 ; CHECK-NOT: @__dfsan_arg_origin_tls251 ; CHECK-NOT: @__dfsan_arg_tls252 ; CHECK_ORIGIN-NOT: 35184372088832253 ; CHECK: %[[#INTP:]] = ptrtoint ptr %p to i64254 ; CHECK-NEXT: %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]255 ; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr256 ; CHECK-NEXT: store i[[#NUM_BITS]] 0, ptr %[[#SHADOW_PTR]], align 1257 ; CHECK: store atomic i32 %x, ptr %p release, align 16258 ; CHECK: ret void259 260entry:261 store atomic i32 %x, ptr %p unordered, align 16262 ret void263}264