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