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 7define void @atomic_fetch_add32() nounwind { 8; X64: atomic_fetch_add32 9; X32: atomic_fetch_add32 10entry: 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 37define 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 65define 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 90define 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 115define 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 140define 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 157define 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 179define 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 201define 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 223define 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 245define 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 256define 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 267define 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