1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefix=X64 3; RUN: llc < %s -mtriple=i686-- -verify-machineinstrs -mattr=+sse2 | FileCheck %s --check-prefixes=X86,X86-GENERIC,X86-SSE2 4; RUN: llc < %s -mtriple=i686-- -verify-machineinstrs -mcpu=slm -mattr=-sse2 | FileCheck %s --check-prefixes=X86,X86-GENERIC,X86-SLM 5; RUN: llc < %s -mtriple=i686-- -verify-machineinstrs -mcpu=goldmont -mattr=-sse2 | FileCheck %s --check-prefixes=X86,X86-GENERIC,X86-SLM 6; RUN: llc < %s -mtriple=i686-- -verify-machineinstrs -mcpu=knl -mattr=-sse2 | FileCheck %s --check-prefixes=X86,X86-GENERIC,X86-SLM 7; RUN: llc < %s -mtriple=i686-- -verify-machineinstrs -mcpu=atom -mattr=-sse2 | FileCheck %s --check-prefixes=X86,X86-ATOM 8 9; On x86, an atomic rmw operation that does not modify the value in memory 10; (such as atomic add 0) can be replaced by an mfence followed by a mov. 11; This is explained (with the motivation for such an optimization) in 12; http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf 13 14define i8 @add8(ptr %p) { 15; X64-LABEL: add8: 16; X64: # %bb.0: 17; X64-NEXT: mfence 18; X64-NEXT: movzbl (%rdi), %eax 19; X64-NEXT: retq 20; 21; X86-SSE2-LABEL: add8: 22; X86-SSE2: # %bb.0: 23; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 24; X86-SSE2-NEXT: mfence 25; X86-SSE2-NEXT: movzbl (%eax), %eax 26; X86-SSE2-NEXT: retl 27; 28; X86-SLM-LABEL: add8: 29; X86-SLM: # %bb.0: 30; X86-SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx 31; X86-SLM-NEXT: xorl %eax, %eax 32; X86-SLM-NEXT: lock xaddb %al, (%ecx) 33; X86-SLM-NEXT: # kill: def $al killed $al killed $eax 34; X86-SLM-NEXT: retl 35; 36; X86-ATOM-LABEL: add8: 37; X86-ATOM: # %bb.0: 38; X86-ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx 39; X86-ATOM-NEXT: xorl %eax, %eax 40; X86-ATOM-NEXT: lock xaddb %al, (%ecx) 41; X86-ATOM-NEXT: # kill: def $al killed $al killed $eax 42; X86-ATOM-NEXT: nop 43; X86-ATOM-NEXT: nop 44; X86-ATOM-NEXT: retl 45 %1 = atomicrmw add ptr %p, i8 0 monotonic 46 ret i8 %1 47} 48 49define i16 @or16(ptr %p) { 50; X64-LABEL: or16: 51; X64: # %bb.0: 52; X64-NEXT: mfence 53; X64-NEXT: movzwl (%rdi), %eax 54; X64-NEXT: retq 55; 56; X86-SSE2-LABEL: or16: 57; X86-SSE2: # %bb.0: 58; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 59; X86-SSE2-NEXT: mfence 60; X86-SSE2-NEXT: movzwl (%eax), %eax 61; X86-SSE2-NEXT: retl 62; 63; X86-SLM-LABEL: or16: 64; X86-SLM: # %bb.0: 65; X86-SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx 66; X86-SLM-NEXT: movzwl (%ecx), %eax 67; X86-SLM-NEXT: .p2align 4, 0x90 68; X86-SLM-NEXT: .LBB1_1: # %atomicrmw.start 69; X86-SLM-NEXT: # =>This Inner Loop Header: Depth=1 70; X86-SLM-NEXT: lock cmpxchgw %ax, (%ecx) 71; X86-SLM-NEXT: jne .LBB1_1 72; X86-SLM-NEXT: # %bb.2: # %atomicrmw.end 73; X86-SLM-NEXT: retl 74; 75; X86-ATOM-LABEL: or16: 76; X86-ATOM: # %bb.0: 77; X86-ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx 78; X86-ATOM-NEXT: movzwl (%ecx), %eax 79; X86-ATOM-NEXT: .p2align 4, 0x90 80; X86-ATOM-NEXT: .LBB1_1: # %atomicrmw.start 81; X86-ATOM-NEXT: # =>This Inner Loop Header: Depth=1 82; X86-ATOM-NEXT: lock cmpxchgw %ax, (%ecx) 83; X86-ATOM-NEXT: jne .LBB1_1 84; X86-ATOM-NEXT: # %bb.2: # %atomicrmw.end 85; X86-ATOM-NEXT: retl 86 %1 = atomicrmw or ptr %p, i16 0 acquire 87 ret i16 %1 88} 89 90define i32 @xor32(ptr %p) { 91; X64-LABEL: xor32: 92; X64: # %bb.0: 93; X64-NEXT: mfence 94; X64-NEXT: movl (%rdi), %eax 95; X64-NEXT: retq 96; 97; X86-SSE2-LABEL: xor32: 98; X86-SSE2: # %bb.0: 99; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 100; X86-SSE2-NEXT: mfence 101; X86-SSE2-NEXT: movl (%eax), %eax 102; X86-SSE2-NEXT: retl 103; 104; X86-SLM-LABEL: xor32: 105; X86-SLM: # %bb.0: 106; X86-SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx 107; X86-SLM-NEXT: movl (%ecx), %eax 108; X86-SLM-NEXT: .p2align 4, 0x90 109; X86-SLM-NEXT: .LBB2_1: # %atomicrmw.start 110; X86-SLM-NEXT: # =>This Inner Loop Header: Depth=1 111; X86-SLM-NEXT: lock cmpxchgl %eax, (%ecx) 112; X86-SLM-NEXT: jne .LBB2_1 113; X86-SLM-NEXT: # %bb.2: # %atomicrmw.end 114; X86-SLM-NEXT: retl 115; 116; X86-ATOM-LABEL: xor32: 117; X86-ATOM: # %bb.0: 118; X86-ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx 119; X86-ATOM-NEXT: movl (%ecx), %eax 120; X86-ATOM-NEXT: .p2align 4, 0x90 121; X86-ATOM-NEXT: .LBB2_1: # %atomicrmw.start 122; X86-ATOM-NEXT: # =>This Inner Loop Header: Depth=1 123; X86-ATOM-NEXT: lock cmpxchgl %eax, (%ecx) 124; X86-ATOM-NEXT: jne .LBB2_1 125; X86-ATOM-NEXT: # %bb.2: # %atomicrmw.end 126; X86-ATOM-NEXT: retl 127 %1 = atomicrmw xor ptr %p, i32 0 release 128 ret i32 %1 129} 130 131define i64 @sub64(ptr %p) { 132; X64-LABEL: sub64: 133; X64: # %bb.0: 134; X64-NEXT: mfence 135; X64-NEXT: movq (%rdi), %rax 136; X64-NEXT: retq 137; 138; X86-LABEL: sub64: 139; X86: # %bb.0: 140; X86-NEXT: pushl %ebx 141; X86-NEXT: .cfi_def_cfa_offset 8 142; X86-NEXT: pushl %esi 143; X86-NEXT: .cfi_def_cfa_offset 12 144; X86-NEXT: .cfi_offset %esi, -12 145; X86-NEXT: .cfi_offset %ebx, -8 146; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 147; X86-NEXT: movl (%esi), %eax 148; X86-NEXT: movl 4(%esi), %edx 149; X86-NEXT: .p2align 4, 0x90 150; X86-NEXT: .LBB3_1: # %atomicrmw.start 151; X86-NEXT: # =>This Inner Loop Header: Depth=1 152; X86-NEXT: movl %edx, %ecx 153; X86-NEXT: movl %eax, %ebx 154; X86-NEXT: lock cmpxchg8b (%esi) 155; X86-NEXT: jne .LBB3_1 156; X86-NEXT: # %bb.2: # %atomicrmw.end 157; X86-NEXT: popl %esi 158; X86-NEXT: .cfi_def_cfa_offset 8 159; X86-NEXT: popl %ebx 160; X86-NEXT: .cfi_def_cfa_offset 4 161; X86-NEXT: retl 162 %1 = atomicrmw sub ptr %p, i64 0 seq_cst 163 ret i64 %1 164} 165 166define i128 @or128(ptr %p) { 167; X64-LABEL: or128: 168; X64: # %bb.0: 169; X64-NEXT: pushq %rax 170; X64-NEXT: .cfi_def_cfa_offset 16 171; X64-NEXT: xorl %esi, %esi 172; X64-NEXT: xorl %edx, %edx 173; X64-NEXT: callq __sync_fetch_and_or_16@PLT 174; X64-NEXT: popq %rcx 175; X64-NEXT: .cfi_def_cfa_offset 8 176; X64-NEXT: retq 177; 178; X86-SSE2-LABEL: or128: 179; X86-SSE2: # %bb.0: 180; X86-SSE2-NEXT: pushl %ebp 181; X86-SSE2-NEXT: .cfi_def_cfa_offset 8 182; X86-SSE2-NEXT: .cfi_offset %ebp, -8 183; X86-SSE2-NEXT: movl %esp, %ebp 184; X86-SSE2-NEXT: .cfi_def_cfa_register %ebp 185; X86-SSE2-NEXT: pushl %edi 186; X86-SSE2-NEXT: pushl %esi 187; X86-SSE2-NEXT: andl $-8, %esp 188; X86-SSE2-NEXT: subl $16, %esp 189; X86-SSE2-NEXT: .cfi_offset %esi, -16 190; X86-SSE2-NEXT: .cfi_offset %edi, -12 191; X86-SSE2-NEXT: movl 8(%ebp), %esi 192; X86-SSE2-NEXT: movl %esp, %eax 193; X86-SSE2-NEXT: pushl $0 194; X86-SSE2-NEXT: pushl $0 195; X86-SSE2-NEXT: pushl $0 196; X86-SSE2-NEXT: pushl $0 197; X86-SSE2-NEXT: pushl 12(%ebp) 198; X86-SSE2-NEXT: pushl %eax 199; X86-SSE2-NEXT: calll __sync_fetch_and_or_16 200; X86-SSE2-NEXT: addl $20, %esp 201; X86-SSE2-NEXT: movl (%esp), %eax 202; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 203; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx 204; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edi 205; X86-SSE2-NEXT: movl %edi, 8(%esi) 206; X86-SSE2-NEXT: movl %edx, 12(%esi) 207; X86-SSE2-NEXT: movl %eax, (%esi) 208; X86-SSE2-NEXT: movl %ecx, 4(%esi) 209; X86-SSE2-NEXT: movl %esi, %eax 210; X86-SSE2-NEXT: leal -8(%ebp), %esp 211; X86-SSE2-NEXT: popl %esi 212; X86-SSE2-NEXT: popl %edi 213; X86-SSE2-NEXT: popl %ebp 214; X86-SSE2-NEXT: .cfi_def_cfa %esp, 4 215; X86-SSE2-NEXT: retl $4 216; 217; X86-SLM-LABEL: or128: 218; X86-SLM: # %bb.0: 219; X86-SLM-NEXT: pushl %ebp 220; X86-SLM-NEXT: .cfi_def_cfa_offset 8 221; X86-SLM-NEXT: .cfi_offset %ebp, -8 222; X86-SLM-NEXT: movl %esp, %ebp 223; X86-SLM-NEXT: .cfi_def_cfa_register %ebp 224; X86-SLM-NEXT: pushl %edi 225; X86-SLM-NEXT: pushl %esi 226; X86-SLM-NEXT: andl $-8, %esp 227; X86-SLM-NEXT: subl $16, %esp 228; X86-SLM-NEXT: .cfi_offset %esi, -16 229; X86-SLM-NEXT: .cfi_offset %edi, -12 230; X86-SLM-NEXT: movl 8(%ebp), %esi 231; X86-SLM-NEXT: movl 12(%ebp), %eax 232; X86-SLM-NEXT: movl %esp, %ecx 233; X86-SLM-NEXT: pushl $0 234; X86-SLM-NEXT: pushl $0 235; X86-SLM-NEXT: pushl $0 236; X86-SLM-NEXT: pushl $0 237; X86-SLM-NEXT: pushl %eax 238; X86-SLM-NEXT: pushl %ecx 239; X86-SLM-NEXT: calll __sync_fetch_and_or_16 240; X86-SLM-NEXT: addl $20, %esp 241; X86-SLM-NEXT: movl (%esp), %eax 242; X86-SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx 243; X86-SLM-NEXT: movl {{[0-9]+}}(%esp), %edx 244; X86-SLM-NEXT: movl {{[0-9]+}}(%esp), %edi 245; X86-SLM-NEXT: movl %edi, 8(%esi) 246; X86-SLM-NEXT: movl %edx, 12(%esi) 247; X86-SLM-NEXT: movl %eax, (%esi) 248; X86-SLM-NEXT: movl %ecx, 4(%esi) 249; X86-SLM-NEXT: movl %esi, %eax 250; X86-SLM-NEXT: leal -8(%ebp), %esp 251; X86-SLM-NEXT: popl %esi 252; X86-SLM-NEXT: popl %edi 253; X86-SLM-NEXT: popl %ebp 254; X86-SLM-NEXT: .cfi_def_cfa %esp, 4 255; X86-SLM-NEXT: retl $4 256; 257; X86-ATOM-LABEL: or128: 258; X86-ATOM: # %bb.0: 259; X86-ATOM-NEXT: pushl %ebp 260; X86-ATOM-NEXT: .cfi_def_cfa_offset 8 261; X86-ATOM-NEXT: .cfi_offset %ebp, -8 262; X86-ATOM-NEXT: leal (%esp), %ebp 263; X86-ATOM-NEXT: .cfi_def_cfa_register %ebp 264; X86-ATOM-NEXT: pushl %edi 265; X86-ATOM-NEXT: pushl %esi 266; X86-ATOM-NEXT: andl $-8, %esp 267; X86-ATOM-NEXT: leal -{{[0-9]+}}(%esp), %esp 268; X86-ATOM-NEXT: .cfi_offset %esi, -16 269; X86-ATOM-NEXT: .cfi_offset %edi, -12 270; X86-ATOM-NEXT: movl 8(%ebp), %esi 271; X86-ATOM-NEXT: movl 12(%ebp), %eax 272; X86-ATOM-NEXT: movl %esp, %ecx 273; X86-ATOM-NEXT: pushl $0 274; X86-ATOM-NEXT: pushl $0 275; X86-ATOM-NEXT: pushl $0 276; X86-ATOM-NEXT: pushl $0 277; X86-ATOM-NEXT: pushl %eax 278; X86-ATOM-NEXT: pushl %ecx 279; X86-ATOM-NEXT: calll __sync_fetch_and_or_16 280; X86-ATOM-NEXT: leal {{[0-9]+}}(%esp), %esp 281; X86-ATOM-NEXT: movl (%esp), %ecx 282; X86-ATOM-NEXT: movl {{[0-9]+}}(%esp), %edx 283; X86-ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax 284; X86-ATOM-NEXT: movl {{[0-9]+}}(%esp), %edi 285; X86-ATOM-NEXT: movl %eax, 8(%esi) 286; X86-ATOM-NEXT: movl %edi, 12(%esi) 287; X86-ATOM-NEXT: movl %ecx, (%esi) 288; X86-ATOM-NEXT: movl %esi, %eax 289; X86-ATOM-NEXT: movl %edx, 4(%esi) 290; X86-ATOM-NEXT: leal -8(%ebp), %esp 291; X86-ATOM-NEXT: popl %esi 292; X86-ATOM-NEXT: popl %edi 293; X86-ATOM-NEXT: popl %ebp 294; X86-ATOM-NEXT: .cfi_def_cfa %esp, 4 295; X86-ATOM-NEXT: retl $4 296 %1 = atomicrmw or ptr %p, i128 0 monotonic 297 ret i128 %1 298} 299 300; For 'and', the idempotent value is (-1) 301define i32 @and32 (ptr %p) { 302; X64-LABEL: and32: 303; X64: # %bb.0: 304; X64-NEXT: mfence 305; X64-NEXT: movl (%rdi), %eax 306; X64-NEXT: retq 307; 308; X86-SSE2-LABEL: and32: 309; X86-SSE2: # %bb.0: 310; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 311; X86-SSE2-NEXT: mfence 312; X86-SSE2-NEXT: movl (%eax), %eax 313; X86-SSE2-NEXT: retl 314; 315; X86-SLM-LABEL: and32: 316; X86-SLM: # %bb.0: 317; X86-SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx 318; X86-SLM-NEXT: movl (%ecx), %eax 319; X86-SLM-NEXT: .p2align 4, 0x90 320; X86-SLM-NEXT: .LBB5_1: # %atomicrmw.start 321; X86-SLM-NEXT: # =>This Inner Loop Header: Depth=1 322; X86-SLM-NEXT: lock cmpxchgl %eax, (%ecx) 323; X86-SLM-NEXT: jne .LBB5_1 324; X86-SLM-NEXT: # %bb.2: # %atomicrmw.end 325; X86-SLM-NEXT: retl 326; 327; X86-ATOM-LABEL: and32: 328; X86-ATOM: # %bb.0: 329; X86-ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx 330; X86-ATOM-NEXT: movl (%ecx), %eax 331; X86-ATOM-NEXT: .p2align 4, 0x90 332; X86-ATOM-NEXT: .LBB5_1: # %atomicrmw.start 333; X86-ATOM-NEXT: # =>This Inner Loop Header: Depth=1 334; X86-ATOM-NEXT: lock cmpxchgl %eax, (%ecx) 335; X86-ATOM-NEXT: jne .LBB5_1 336; X86-ATOM-NEXT: # %bb.2: # %atomicrmw.end 337; X86-ATOM-NEXT: retl 338 %1 = atomicrmw and ptr %p, i32 -1 acq_rel 339 ret i32 %1 340} 341 342define void @or32_nouse_monotonic(ptr %p) { 343; X64-LABEL: or32_nouse_monotonic: 344; X64: # %bb.0: 345; X64-NEXT: #MEMBARRIER 346; X64-NEXT: retq 347; 348; X86-GENERIC-LABEL: or32_nouse_monotonic: 349; X86-GENERIC: # %bb.0: 350; X86-GENERIC-NEXT: #MEMBARRIER 351; X86-GENERIC-NEXT: retl 352; 353; X86-ATOM-LABEL: or32_nouse_monotonic: 354; X86-ATOM: # %bb.0: 355; X86-ATOM-NEXT: #MEMBARRIER 356; X86-ATOM-NEXT: nop 357; X86-ATOM-NEXT: nop 358; X86-ATOM-NEXT: nop 359; X86-ATOM-NEXT: nop 360; X86-ATOM-NEXT: nop 361; X86-ATOM-NEXT: nop 362; X86-ATOM-NEXT: retl 363 atomicrmw or ptr %p, i32 0 monotonic 364 ret void 365} 366 367 368define void @or32_nouse_acquire(ptr %p) { 369; X64-LABEL: or32_nouse_acquire: 370; X64: # %bb.0: 371; X64-NEXT: #MEMBARRIER 372; X64-NEXT: retq 373; 374; X86-GENERIC-LABEL: or32_nouse_acquire: 375; X86-GENERIC: # %bb.0: 376; X86-GENERIC-NEXT: #MEMBARRIER 377; X86-GENERIC-NEXT: retl 378; 379; X86-ATOM-LABEL: or32_nouse_acquire: 380; X86-ATOM: # %bb.0: 381; X86-ATOM-NEXT: #MEMBARRIER 382; X86-ATOM-NEXT: nop 383; X86-ATOM-NEXT: nop 384; X86-ATOM-NEXT: nop 385; X86-ATOM-NEXT: nop 386; X86-ATOM-NEXT: nop 387; X86-ATOM-NEXT: nop 388; X86-ATOM-NEXT: retl 389 atomicrmw or ptr %p, i32 0 acquire 390 ret void 391} 392 393define void @or32_nouse_release(ptr %p) { 394; X64-LABEL: or32_nouse_release: 395; X64: # %bb.0: 396; X64-NEXT: #MEMBARRIER 397; X64-NEXT: retq 398; 399; X86-GENERIC-LABEL: or32_nouse_release: 400; X86-GENERIC: # %bb.0: 401; X86-GENERIC-NEXT: #MEMBARRIER 402; X86-GENERIC-NEXT: retl 403; 404; X86-ATOM-LABEL: or32_nouse_release: 405; X86-ATOM: # %bb.0: 406; X86-ATOM-NEXT: #MEMBARRIER 407; X86-ATOM-NEXT: nop 408; X86-ATOM-NEXT: nop 409; X86-ATOM-NEXT: nop 410; X86-ATOM-NEXT: nop 411; X86-ATOM-NEXT: nop 412; X86-ATOM-NEXT: nop 413; X86-ATOM-NEXT: retl 414 atomicrmw or ptr %p, i32 0 release 415 ret void 416} 417 418define void @or32_nouse_acq_rel(ptr %p) { 419; X64-LABEL: or32_nouse_acq_rel: 420; X64: # %bb.0: 421; X64-NEXT: #MEMBARRIER 422; X64-NEXT: retq 423; 424; X86-GENERIC-LABEL: or32_nouse_acq_rel: 425; X86-GENERIC: # %bb.0: 426; X86-GENERIC-NEXT: #MEMBARRIER 427; X86-GENERIC-NEXT: retl 428; 429; X86-ATOM-LABEL: or32_nouse_acq_rel: 430; X86-ATOM: # %bb.0: 431; X86-ATOM-NEXT: #MEMBARRIER 432; X86-ATOM-NEXT: nop 433; X86-ATOM-NEXT: nop 434; X86-ATOM-NEXT: nop 435; X86-ATOM-NEXT: nop 436; X86-ATOM-NEXT: nop 437; X86-ATOM-NEXT: nop 438; X86-ATOM-NEXT: retl 439 atomicrmw or ptr %p, i32 0 acq_rel 440 ret void 441} 442 443define void @or32_nouse_seq_cst(ptr %p) { 444; X64-LABEL: or32_nouse_seq_cst: 445; X64: # %bb.0: 446; X64-NEXT: lock orl $0, -{{[0-9]+}}(%rsp) 447; X64-NEXT: retq 448; 449; X86-GENERIC-LABEL: or32_nouse_seq_cst: 450; X86-GENERIC: # %bb.0: 451; X86-GENERIC-NEXT: lock orl $0, (%esp) 452; X86-GENERIC-NEXT: retl 453; 454; X86-ATOM-LABEL: or32_nouse_seq_cst: 455; X86-ATOM: # %bb.0: 456; X86-ATOM-NEXT: lock orl $0, (%esp) 457; X86-ATOM-NEXT: nop 458; X86-ATOM-NEXT: nop 459; X86-ATOM-NEXT: nop 460; X86-ATOM-NEXT: nop 461; X86-ATOM-NEXT: nop 462; X86-ATOM-NEXT: nop 463; X86-ATOM-NEXT: retl 464 atomicrmw or ptr %p, i32 0 seq_cst 465 ret void 466} 467 468; TODO: The value isn't used on 32 bit, so the cmpxchg8b is unneeded 469define void @or64_nouse_seq_cst(ptr %p) { 470; X64-LABEL: or64_nouse_seq_cst: 471; X64: # %bb.0: 472; X64-NEXT: lock orl $0, -{{[0-9]+}}(%rsp) 473; X64-NEXT: retq 474; 475; X86-LABEL: or64_nouse_seq_cst: 476; X86: # %bb.0: 477; X86-NEXT: pushl %ebx 478; X86-NEXT: .cfi_def_cfa_offset 8 479; X86-NEXT: pushl %esi 480; X86-NEXT: .cfi_def_cfa_offset 12 481; X86-NEXT: .cfi_offset %esi, -12 482; X86-NEXT: .cfi_offset %ebx, -8 483; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 484; X86-NEXT: movl (%esi), %eax 485; X86-NEXT: movl 4(%esi), %edx 486; X86-NEXT: .p2align 4, 0x90 487; X86-NEXT: .LBB11_1: # %atomicrmw.start 488; X86-NEXT: # =>This Inner Loop Header: Depth=1 489; X86-NEXT: movl %edx, %ecx 490; X86-NEXT: movl %eax, %ebx 491; X86-NEXT: lock cmpxchg8b (%esi) 492; X86-NEXT: jne .LBB11_1 493; X86-NEXT: # %bb.2: # %atomicrmw.end 494; X86-NEXT: popl %esi 495; X86-NEXT: .cfi_def_cfa_offset 8 496; X86-NEXT: popl %ebx 497; X86-NEXT: .cfi_def_cfa_offset 4 498; X86-NEXT: retl 499 atomicrmw or ptr %p, i64 0 seq_cst 500 ret void 501} 502 503; TODO: Don't need to lower as sync_and_fetch call 504define void @or128_nouse_seq_cst(ptr %p) { 505; X64-LABEL: or128_nouse_seq_cst: 506; X64: # %bb.0: 507; X64-NEXT: pushq %rax 508; X64-NEXT: .cfi_def_cfa_offset 16 509; X64-NEXT: xorl %esi, %esi 510; X64-NEXT: xorl %edx, %edx 511; X64-NEXT: callq __sync_fetch_and_or_16@PLT 512; X64-NEXT: popq %rax 513; X64-NEXT: .cfi_def_cfa_offset 8 514; X64-NEXT: retq 515; 516; X86-SSE2-LABEL: or128_nouse_seq_cst: 517; X86-SSE2: # %bb.0: 518; X86-SSE2-NEXT: pushl %ebp 519; X86-SSE2-NEXT: .cfi_def_cfa_offset 8 520; X86-SSE2-NEXT: .cfi_offset %ebp, -8 521; X86-SSE2-NEXT: movl %esp, %ebp 522; X86-SSE2-NEXT: .cfi_def_cfa_register %ebp 523; X86-SSE2-NEXT: andl $-8, %esp 524; X86-SSE2-NEXT: subl $16, %esp 525; X86-SSE2-NEXT: movl %esp, %eax 526; X86-SSE2-NEXT: pushl $0 527; X86-SSE2-NEXT: pushl $0 528; X86-SSE2-NEXT: pushl $0 529; X86-SSE2-NEXT: pushl $0 530; X86-SSE2-NEXT: pushl 8(%ebp) 531; X86-SSE2-NEXT: pushl %eax 532; X86-SSE2-NEXT: calll __sync_fetch_and_or_16 533; X86-SSE2-NEXT: addl $20, %esp 534; X86-SSE2-NEXT: movl %ebp, %esp 535; X86-SSE2-NEXT: popl %ebp 536; X86-SSE2-NEXT: .cfi_def_cfa %esp, 4 537; X86-SSE2-NEXT: retl 538; 539; X86-SLM-LABEL: or128_nouse_seq_cst: 540; X86-SLM: # %bb.0: 541; X86-SLM-NEXT: pushl %ebp 542; X86-SLM-NEXT: .cfi_def_cfa_offset 8 543; X86-SLM-NEXT: .cfi_offset %ebp, -8 544; X86-SLM-NEXT: movl %esp, %ebp 545; X86-SLM-NEXT: .cfi_def_cfa_register %ebp 546; X86-SLM-NEXT: andl $-8, %esp 547; X86-SLM-NEXT: subl $16, %esp 548; X86-SLM-NEXT: movl 8(%ebp), %eax 549; X86-SLM-NEXT: movl %esp, %ecx 550; X86-SLM-NEXT: pushl $0 551; X86-SLM-NEXT: pushl $0 552; X86-SLM-NEXT: pushl $0 553; X86-SLM-NEXT: pushl $0 554; X86-SLM-NEXT: pushl %eax 555; X86-SLM-NEXT: pushl %ecx 556; X86-SLM-NEXT: calll __sync_fetch_and_or_16 557; X86-SLM-NEXT: addl $20, %esp 558; X86-SLM-NEXT: movl %ebp, %esp 559; X86-SLM-NEXT: popl %ebp 560; X86-SLM-NEXT: .cfi_def_cfa %esp, 4 561; X86-SLM-NEXT: retl 562; 563; X86-ATOM-LABEL: or128_nouse_seq_cst: 564; X86-ATOM: # %bb.0: 565; X86-ATOM-NEXT: pushl %ebp 566; X86-ATOM-NEXT: .cfi_def_cfa_offset 8 567; X86-ATOM-NEXT: .cfi_offset %ebp, -8 568; X86-ATOM-NEXT: leal (%esp), %ebp 569; X86-ATOM-NEXT: .cfi_def_cfa_register %ebp 570; X86-ATOM-NEXT: andl $-8, %esp 571; X86-ATOM-NEXT: leal -{{[0-9]+}}(%esp), %esp 572; X86-ATOM-NEXT: movl 8(%ebp), %eax 573; X86-ATOM-NEXT: movl %esp, %ecx 574; X86-ATOM-NEXT: pushl $0 575; X86-ATOM-NEXT: pushl $0 576; X86-ATOM-NEXT: pushl $0 577; X86-ATOM-NEXT: pushl $0 578; X86-ATOM-NEXT: pushl %eax 579; X86-ATOM-NEXT: pushl %ecx 580; X86-ATOM-NEXT: calll __sync_fetch_and_or_16 581; X86-ATOM-NEXT: leal {{[0-9]+}}(%esp), %esp 582; X86-ATOM-NEXT: movl %ebp, %esp 583; X86-ATOM-NEXT: popl %ebp 584; X86-ATOM-NEXT: .cfi_def_cfa %esp, 4 585; X86-ATOM-NEXT: retl 586 atomicrmw or ptr %p, i128 0 seq_cst 587 ret void 588} 589 590 591define void @or16_nouse_seq_cst(ptr %p) { 592; X64-LABEL: or16_nouse_seq_cst: 593; X64: # %bb.0: 594; X64-NEXT: lock orl $0, -{{[0-9]+}}(%rsp) 595; X64-NEXT: retq 596; 597; X86-GENERIC-LABEL: or16_nouse_seq_cst: 598; X86-GENERIC: # %bb.0: 599; X86-GENERIC-NEXT: lock orl $0, (%esp) 600; X86-GENERIC-NEXT: retl 601; 602; X86-ATOM-LABEL: or16_nouse_seq_cst: 603; X86-ATOM: # %bb.0: 604; X86-ATOM-NEXT: lock orl $0, (%esp) 605; X86-ATOM-NEXT: nop 606; X86-ATOM-NEXT: nop 607; X86-ATOM-NEXT: nop 608; X86-ATOM-NEXT: nop 609; X86-ATOM-NEXT: nop 610; X86-ATOM-NEXT: nop 611; X86-ATOM-NEXT: retl 612 atomicrmw or ptr %p, i16 0 seq_cst 613 ret void 614} 615 616define void @or8_nouse_seq_cst(ptr %p) { 617; X64-LABEL: or8_nouse_seq_cst: 618; X64: # %bb.0: 619; X64-NEXT: lock orl $0, -{{[0-9]+}}(%rsp) 620; X64-NEXT: retq 621; 622; X86-GENERIC-LABEL: or8_nouse_seq_cst: 623; X86-GENERIC: # %bb.0: 624; X86-GENERIC-NEXT: lock orl $0, (%esp) 625; X86-GENERIC-NEXT: retl 626; 627; X86-ATOM-LABEL: or8_nouse_seq_cst: 628; X86-ATOM: # %bb.0: 629; X86-ATOM-NEXT: lock orl $0, (%esp) 630; X86-ATOM-NEXT: nop 631; X86-ATOM-NEXT: nop 632; X86-ATOM-NEXT: nop 633; X86-ATOM-NEXT: nop 634; X86-ATOM-NEXT: nop 635; X86-ATOM-NEXT: nop 636; X86-ATOM-NEXT: retl 637 atomicrmw or ptr %p, i8 0 seq_cst 638 ret void 639} 640