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: atomic_fetch_add32 9 ; X32: 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: atomic_fetch_sub32 39 ; X32: 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: atomic_fetch_and32 67 ; X32: 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: atomic_fetch_or32 92 ; X32: 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: atomic_fetch_xor32 117 ; X32: 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: atomic_fetch_nand32 142 ; X32: 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 %t1 = atomicrmw max i32* @sc32, i32 %x acquire 159 ; X64: cmpl 160 ; X64: cmov 161 ; X64: lock 162 ; X64: cmpxchgl 163 164 ; X32: cmpl 165 ; X32: cmov 166 ; X32: lock 167 ; X32: cmpxchgl 168 169 ; NOCMOV: cmpl 170 ; NOCMOV: jl 171 ; NOCMOV: lock 172 ; NOCMOV: cmpxchgl 173 ret void 174 ; X64: ret 175 ; X32: ret 176 ; NOCMOV: ret 177 } 178 179 define void @atomic_fetch_min32(i32 %x) nounwind { 180 %t1 = atomicrmw min i32* @sc32, i32 %x acquire 181 ; X64: cmpl 182 ; X64: cmov 183 ; X64: lock 184 ; X64: cmpxchgl 185 186 ; X32: cmpl 187 ; X32: cmov 188 ; X32: lock 189 ; X32: cmpxchgl 190 191 ; NOCMOV: cmpl 192 ; NOCMOV: jg 193 ; NOCMOV: lock 194 ; NOCMOV: cmpxchgl 195 ret void 196 ; X64: ret 197 ; X32: ret 198 ; NOCMOV: ret 199 } 200 201 define void @atomic_fetch_umax32(i32 %x) nounwind { 202 %t1 = atomicrmw umax i32* @sc32, i32 %x acquire 203 ; X64: cmpl 204 ; X64: cmov 205 ; X64: lock 206 ; X64: cmpxchgl 207 208 ; X32: cmpl 209 ; X32: cmov 210 ; X32: lock 211 ; X32: cmpxchgl 212 213 ; NOCMOV: cmpl 214 ; NOCMOV: jb 215 ; NOCMOV: lock 216 ; NOCMOV: cmpxchgl 217 ret void 218 ; X64: ret 219 ; X32: ret 220 ; NOCMOV: ret 221 } 222 223 define void @atomic_fetch_umin32(i32 %x) nounwind { 224 %t1 = atomicrmw umin i32* @sc32, i32 %x acquire 225 ; X64: cmpl 226 ; X64: cmov 227 ; X64: lock 228 ; X64: cmpxchgl 229 230 ; X32: cmpl 231 ; X32: cmov 232 ; X32: lock 233 ; X32: cmpxchgl 234 235 ; NOCMOV: cmpl 236 ; NOCMOV: ja 237 ; NOCMOV: lock 238 ; NOCMOV: cmpxchgl 239 ret void 240 ; X64: ret 241 ; X32: ret 242 ; NOCMOV: ret 243 } 244 245 define void @atomic_fetch_cmpxchg32() nounwind { 246 %t1 = cmpxchg i32* @sc32, i32 0, i32 1 acquire 247 ; X64: lock 248 ; X64: cmpxchgl 249 ; X32: lock 250 ; X32: cmpxchgl 251 ret void 252 ; X64: ret 253 ; X32: ret 254 } 255 256 define void @atomic_fetch_store32(i32 %x) nounwind { 257 store atomic i32 %x, i32* @sc32 release, align 4 258 ; X64-NOT: lock 259 ; X64: movl 260 ; X32-NOT: lock 261 ; X32: movl 262 ret void 263 ; X64: ret 264 ; X32: ret 265 } 266 267 define void @atomic_fetch_swap32(i32 %x) nounwind { 268 %t1 = atomicrmw xchg i32* @sc32, i32 %x acquire 269 ; X64-NOT: lock 270 ; X64: xchgl 271 ; X32-NOT: lock 272 ; X32: xchgl 273 ret void 274 ; X64: ret 275 ; X32: ret 276 } 277