1 ; RUN: llc < %s -O0 -march=x86-64 -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X64 2 ; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X32 3 ; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 -mattr=-cmov -verify-machineinstrs | FileCheck %s --check-prefix NOCMOV 4 5 ; XFAIL: cygwin,mingw32,win32 6 7 @sc32 = external global i32 8 9 define void @atomic_fetch_add32() nounwind { 10 ; X64: atomic_fetch_add32 11 ; X32: atomic_fetch_add32 12 entry: 13 ; 32-bit 14 %t1 = atomicrmw add i32* @sc32, i32 1 acquire 15 ; X64: lock 16 ; X64: incl 17 ; X32: lock 18 ; X32: incl 19 %t2 = atomicrmw add i32* @sc32, i32 3 acquire 20 ; X64: lock 21 ; X64: addl $3 22 ; X32: lock 23 ; X32: addl $3 24 %t3 = atomicrmw add i32* @sc32, i32 5 acquire 25 ; X64: lock 26 ; X64: xaddl 27 ; X32: lock 28 ; X32: xaddl 29 %t4 = atomicrmw add i32* @sc32, i32 %t3 acquire 30 ; X64: lock 31 ; X64: addl 32 ; X32: lock 33 ; X32: addl 34 ret void 35 ; X64: ret 36 ; X32: ret 37 } 38 39 define void @atomic_fetch_sub32() nounwind { 40 ; X64: atomic_fetch_sub32 41 ; X32: atomic_fetch_sub32 42 %t1 = atomicrmw sub i32* @sc32, i32 1 acquire 43 ; X64: lock 44 ; X64: decl 45 ; X32: lock 46 ; X32: decl 47 %t2 = atomicrmw sub i32* @sc32, i32 3 acquire 48 ; X64: lock 49 ; X64: subl $3 50 ; X32: lock 51 ; X32: subl $3 52 %t3 = atomicrmw sub i32* @sc32, i32 5 acquire 53 ; X64: lock 54 ; X64: xaddl 55 ; X32: lock 56 ; X32: xaddl 57 %t4 = atomicrmw sub i32* @sc32, i32 %t3 acquire 58 ; X64: lock 59 ; X64: subl 60 ; X32: lock 61 ; X32: subl 62 ret void 63 ; X64: ret 64 ; X32: ret 65 } 66 67 define void @atomic_fetch_and32() nounwind { 68 ; X64: atomic_fetch_and32 69 ; X32: atomic_fetch_and32 70 %t1 = atomicrmw and i32* @sc32, i32 3 acquire 71 ; X64: lock 72 ; X64: andl $3 73 ; X32: lock 74 ; X32: andl $3 75 %t2 = atomicrmw and i32* @sc32, i32 5 acquire 76 ; X64: andl 77 ; X64: lock 78 ; X64: cmpxchgl 79 ; X32: andl 80 ; X32: lock 81 ; X32: cmpxchgl 82 %t3 = atomicrmw and i32* @sc32, i32 %t2 acquire 83 ; X64: lock 84 ; X64: andl 85 ; X32: lock 86 ; X32: andl 87 ret void 88 ; X64: ret 89 ; X32: ret 90 } 91 92 define void @atomic_fetch_or32() nounwind { 93 ; X64: atomic_fetch_or32 94 ; X32: atomic_fetch_or32 95 %t1 = atomicrmw or i32* @sc32, i32 3 acquire 96 ; X64: lock 97 ; X64: orl $3 98 ; X32: lock 99 ; X32: orl $3 100 %t2 = atomicrmw or i32* @sc32, i32 5 acquire 101 ; X64: orl 102 ; X64: lock 103 ; X64: cmpxchgl 104 ; X32: orl 105 ; X32: lock 106 ; X32: cmpxchgl 107 %t3 = atomicrmw or i32* @sc32, i32 %t2 acquire 108 ; X64: lock 109 ; X64: orl 110 ; X32: lock 111 ; X32: orl 112 ret void 113 ; X64: ret 114 ; X32: ret 115 } 116 117 define void @atomic_fetch_xor32() nounwind { 118 ; X64: atomic_fetch_xor32 119 ; X32: atomic_fetch_xor32 120 %t1 = atomicrmw xor i32* @sc32, i32 3 acquire 121 ; X64: lock 122 ; X64: xorl $3 123 ; X32: lock 124 ; X32: xorl $3 125 %t2 = atomicrmw xor i32* @sc32, i32 5 acquire 126 ; X64: xorl 127 ; X64: lock 128 ; X64: cmpxchgl 129 ; X32: xorl 130 ; X32: lock 131 ; X32: cmpxchgl 132 %t3 = atomicrmw xor i32* @sc32, i32 %t2 acquire 133 ; X64: lock 134 ; X64: xorl 135 ; X32: lock 136 ; X32: xorl 137 ret void 138 ; X64: ret 139 ; X32: ret 140 } 141 142 define void @atomic_fetch_nand32(i32 %x) nounwind { 143 ; X64: atomic_fetch_nand32 144 ; X32: atomic_fetch_nand32 145 %t1 = atomicrmw nand i32* @sc32, i32 %x acquire 146 ; X64: andl 147 ; X64: notl 148 ; X64: lock 149 ; X64: cmpxchgl 150 ; X32: andl 151 ; X32: notl 152 ; X32: lock 153 ; X32: cmpxchgl 154 ret void 155 ; X64: ret 156 ; X32: ret 157 } 158 159 define void @atomic_fetch_max32(i32 %x) nounwind { 160 %t1 = atomicrmw max i32* @sc32, i32 %x acquire 161 ; X64: cmpl 162 ; X64: cmov 163 ; X64: lock 164 ; X64: cmpxchgl 165 166 ; X32: cmpl 167 ; X32: cmov 168 ; X32: lock 169 ; X32: cmpxchgl 170 171 ; NOCMOV: cmpl 172 ; NOCMOV: jl 173 ; NOCMOV: lock 174 ; NOCMOV: cmpxchgl 175 ret void 176 ; X64: ret 177 ; X32: ret 178 ; NOCMOV: ret 179 } 180 181 define void @atomic_fetch_min32(i32 %x) nounwind { 182 %t1 = atomicrmw min i32* @sc32, i32 %x acquire 183 ; X64: cmpl 184 ; X64: cmov 185 ; X64: lock 186 ; X64: cmpxchgl 187 188 ; X32: cmpl 189 ; X32: cmov 190 ; X32: lock 191 ; X32: cmpxchgl 192 193 ; NOCMOV: cmpl 194 ; NOCMOV: jg 195 ; NOCMOV: lock 196 ; NOCMOV: cmpxchgl 197 ret void 198 ; X64: ret 199 ; X32: ret 200 ; NOCMOV: ret 201 } 202 203 define void @atomic_fetch_umax32(i32 %x) nounwind { 204 %t1 = atomicrmw umax i32* @sc32, i32 %x acquire 205 ; X64: cmpl 206 ; X64: cmov 207 ; X64: lock 208 ; X64: cmpxchgl 209 210 ; X32: cmpl 211 ; X32: cmov 212 ; X32: lock 213 ; X32: cmpxchgl 214 215 ; NOCMOV: cmpl 216 ; NOCMOV: jb 217 ; NOCMOV: lock 218 ; NOCMOV: cmpxchgl 219 ret void 220 ; X64: ret 221 ; X32: ret 222 ; NOCMOV: ret 223 } 224 225 define void @atomic_fetch_umin32(i32 %x) nounwind { 226 %t1 = atomicrmw umin i32* @sc32, i32 %x acquire 227 ; X64: cmpl 228 ; X64: cmov 229 ; X64: lock 230 ; X64: cmpxchgl 231 232 ; X32: cmpl 233 ; X32: cmov 234 ; X32: lock 235 ; X32: cmpxchgl 236 237 ; NOCMOV: cmpl 238 ; NOCMOV: ja 239 ; NOCMOV: lock 240 ; NOCMOV: cmpxchgl 241 ret void 242 ; X64: ret 243 ; X32: ret 244 ; NOCMOV: ret 245 } 246 247 define void @atomic_fetch_cmpxchg32() nounwind { 248 %t1 = cmpxchg i32* @sc32, i32 0, i32 1 acquire 249 ; X64: lock 250 ; X64: cmpxchgl 251 ; X32: lock 252 ; X32: cmpxchgl 253 ret void 254 ; X64: ret 255 ; X32: ret 256 } 257 258 define void @atomic_fetch_store32(i32 %x) nounwind { 259 store atomic i32 %x, i32* @sc32 release, align 4 260 ; X64-NOT: lock 261 ; X64: movl 262 ; X32-NOT: lock 263 ; X32: movl 264 ret void 265 ; X64: ret 266 ; X32: ret 267 } 268 269 define void @atomic_fetch_swap32(i32 %x) nounwind { 270 %t1 = atomicrmw xchg i32* @sc32, i32 %x acquire 271 ; X64-NOT: lock 272 ; X64: xchgl 273 ; X32-NOT: lock 274 ; X32: xchgl 275 ret void 276 ; X64: ret 277 ; X32: ret 278 } 279