Home | History | Annotate | Download | only in MemorySanitizer
      1 ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s
      2 ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s
      3 ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s
      4 
      5 target 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"
      6 target triple = "x86_64-unknown-linux-gnu"
      7 
      8 ; atomicrmw xchg: store clean shadow, return clean shadow
      9 
     10 define i32 @AtomicRmwXchg(i32* %p, i32 %x) sanitize_memory {
     11 entry:
     12   %0 = atomicrmw xchg i32* %p, i32 %x seq_cst
     13   ret i32 %0
     14 }
     15 
     16 ; CHECK-LABEL: @AtomicRmwXchg
     17 ; CHECK: store i32 0,
     18 ; CHECK: atomicrmw xchg {{.*}} seq_cst
     19 ; CHECK: store i32 0, {{.*}} @__msan_retval_tls
     20 ; CHECK: ret i32
     21 
     22 
     23 ; atomicrmw max: exactly the same as above
     24 
     25 define i32 @AtomicRmwMax(i32* %p, i32 %x) sanitize_memory {
     26 entry:
     27   %0 = atomicrmw max i32* %p, i32 %x seq_cst
     28   ret i32 %0
     29 }
     30 
     31 ; CHECK-LABEL: @AtomicRmwMax
     32 ; CHECK: store i32 0,
     33 ; CHECK: atomicrmw max {{.*}} seq_cst
     34 ; CHECK: store i32 0, {{.*}} @__msan_retval_tls
     35 ; CHECK: ret i32
     36 
     37 
     38 ; cmpxchg: the same as above, but also check %a shadow
     39 
     40 define i32 @Cmpxchg(i32* %p, i32 %a, i32 %b) sanitize_memory {
     41 entry:
     42   %pair = cmpxchg i32* %p, i32 %a, i32 %b seq_cst seq_cst
     43   %0 = extractvalue { i32, i1 } %pair, 0
     44   ret i32 %0
     45 }
     46 
     47 ; CHECK-LABEL: @Cmpxchg
     48 ; CHECK: store { i32, i1 } zeroinitializer,
     49 ; CHECK: icmp
     50 ; CHECK: br
     51 ; CHECK: @__msan_warning
     52 ; CHECK: cmpxchg {{.*}} seq_cst seq_cst
     53 ; CHECK: store i32 0, {{.*}} @__msan_retval_tls
     54 ; CHECK: ret i32
     55 
     56 
     57 ; relaxed cmpxchg: bump up to "release monotonic"
     58 
     59 define i32 @CmpxchgMonotonic(i32* %p, i32 %a, i32 %b) sanitize_memory {
     60 entry:
     61   %pair = cmpxchg i32* %p, i32 %a, i32 %b monotonic monotonic
     62   %0 = extractvalue { i32, i1 } %pair, 0
     63   ret i32 %0
     64 }
     65 
     66 ; CHECK-LABEL: @CmpxchgMonotonic
     67 ; CHECK: store { i32, i1 } zeroinitializer,
     68 ; CHECK: icmp
     69 ; CHECK: br
     70 ; CHECK: @__msan_warning
     71 ; CHECK: cmpxchg {{.*}} release monotonic
     72 ; CHECK: store i32 0, {{.*}} @__msan_retval_tls
     73 ; CHECK: ret i32
     74 
     75 
     76 ; atomic load: preserve alignment, load shadow value after app value
     77 
     78 define i32 @AtomicLoad(i32* %p) sanitize_memory {
     79 entry:
     80   %0 = load atomic i32, i32* %p seq_cst, align 16
     81   ret i32 %0
     82 }
     83 
     84 ; CHECK-LABEL: @AtomicLoad
     85 ; CHECK: load atomic i32, i32* {{.*}} seq_cst, align 16
     86 ; CHECK: [[SHADOW:%[01-9a-z_]+]] = load i32, i32* {{.*}}, align 16
     87 ; CHECK: store i32 {{.*}}[[SHADOW]], {{.*}} @__msan_retval_tls
     88 ; CHECK: ret i32
     89 
     90 
     91 ; atomic load: preserve alignment, load shadow value after app value
     92 
     93 define i32 @AtomicLoadAcquire(i32* %p) sanitize_memory {
     94 entry:
     95   %0 = load atomic i32, i32* %p acquire, align 16
     96   ret i32 %0
     97 }
     98 
     99 ; CHECK-LABEL: @AtomicLoadAcquire
    100 ; CHECK: load atomic i32, i32* {{.*}} acquire, align 16
    101 ; CHECK: [[SHADOW:%[01-9a-z_]+]] = load i32, i32* {{.*}}, align 16
    102 ; CHECK: store i32 {{.*}}[[SHADOW]], {{.*}} @__msan_retval_tls
    103 ; CHECK: ret i32
    104 
    105 
    106 ; atomic load monotonic: bump up to load acquire
    107 
    108 define i32 @AtomicLoadMonotonic(i32* %p) sanitize_memory {
    109 entry:
    110   %0 = load atomic i32, i32* %p monotonic, align 16
    111   ret i32 %0
    112 }
    113 
    114 ; CHECK-LABEL: @AtomicLoadMonotonic
    115 ; CHECK: load atomic i32, i32* {{.*}} acquire, align 16
    116 ; CHECK: [[SHADOW:%[01-9a-z_]+]] = load i32, i32* {{.*}}, align 16
    117 ; CHECK: store i32 {{.*}}[[SHADOW]], {{.*}} @__msan_retval_tls
    118 ; CHECK: ret i32
    119 
    120 
    121 ; atomic load unordered: bump up to load acquire
    122 
    123 define i32 @AtomicLoadUnordered(i32* %p) sanitize_memory {
    124 entry:
    125   %0 = load atomic i32, i32* %p unordered, align 16
    126   ret i32 %0
    127 }
    128 
    129 ; CHECK-LABEL: @AtomicLoadUnordered
    130 ; CHECK: load atomic i32, i32* {{.*}} acquire, align 16
    131 ; CHECK: [[SHADOW:%[01-9a-z_]+]] = load i32, i32* {{.*}}, align 16
    132 ; CHECK: store i32 {{.*}}[[SHADOW]], {{.*}} @__msan_retval_tls
    133 ; CHECK: ret i32
    134 
    135 
    136 ; atomic store: preserve alignment, store clean shadow value before app value
    137 
    138 define void @AtomicStore(i32* %p, i32 %x) sanitize_memory {
    139 entry:
    140   store atomic i32 %x, i32* %p seq_cst, align 16
    141   ret void
    142 }
    143 
    144 ; CHECK-LABEL: @AtomicStore
    145 ; CHECK-NOT: @__msan_param_tls
    146 ; CHECK: store i32 0, i32* {{.*}}, align 16
    147 ; CHECK: store atomic i32 %x, i32* %p seq_cst, align 16
    148 ; CHECK: ret void
    149 
    150 
    151 ; atomic store: preserve alignment, store clean shadow value before app value
    152 
    153 define void @AtomicStoreRelease(i32* %p, i32 %x) sanitize_memory {
    154 entry:
    155   store atomic i32 %x, i32* %p release, align 16
    156   ret void
    157 }
    158 
    159 ; CHECK-LABEL: @AtomicStoreRelease
    160 ; CHECK-NOT: @__msan_param_tls
    161 ; CHECK: store i32 0, i32* {{.*}}, align 16
    162 ; CHECK: store atomic i32 %x, i32* %p release, align 16
    163 ; CHECK: ret void
    164 
    165 
    166 ; atomic store monotonic: bumped up to store release
    167 
    168 define void @AtomicStoreMonotonic(i32* %p, i32 %x) sanitize_memory {
    169 entry:
    170   store atomic i32 %x, i32* %p monotonic, align 16
    171   ret void
    172 }
    173 
    174 ; CHECK-LABEL: @AtomicStoreMonotonic
    175 ; CHECK-NOT: @__msan_param_tls
    176 ; CHECK: store i32 0, i32* {{.*}}, align 16
    177 ; CHECK: store atomic i32 %x, i32* %p release, align 16
    178 ; CHECK: ret void
    179 
    180 
    181 ; atomic store unordered: bumped up to store release
    182 
    183 define void @AtomicStoreUnordered(i32* %p, i32 %x) sanitize_memory {
    184 entry:
    185   store atomic i32 %x, i32* %p unordered, align 16
    186   ret void
    187 }
    188 
    189 ; CHECK-LABEL: @AtomicStoreUnordered
    190 ; CHECK-NOT: @__msan_param_tls
    191 ; CHECK: store i32 0, i32* {{.*}}, align 16
    192 ; CHECK: store atomic i32 %x, i32* %p release, align 16
    193 ; CHECK: ret void
    194