1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i386-linux-generic -verify-machineinstrs -mattr=sse | FileCheck %s --check-prefix=X86 --check-prefix=X86-SSE --check-prefix=X86-SSE1 3; RUN: llc < %s -mtriple=i386-linux-generic -verify-machineinstrs -mattr=sse2 | FileCheck %s --check-prefix=X86 --check-prefix=X86-SSE --check-prefix=X86-SSE2 4; RUN: llc < %s -mtriple=i386-linux-generic -verify-machineinstrs -mattr=avx | FileCheck %s --check-prefix=X86 --check-prefix=X86-AVX --check-prefix=X86-AVX1 5; RUN: llc < %s -mtriple=i386-linux-generic -verify-machineinstrs -mattr=avx512f | FileCheck %s --check-prefix=X86 --check-prefix=X86-AVX --check-prefix=X86-AVX512 6; RUN: llc < %s -mtriple=i386-linux-generic -verify-machineinstrs | FileCheck %s --check-prefix=X86 --check-prefix=X86-NOSSE 7; RUN: llc < %s -mtriple=x86_64-linux-generic -verify-machineinstrs -mattr=sse2 | FileCheck %s --check-prefix=X64 --check-prefix=X64-SSE 8; RUN: llc < %s -mtriple=x86_64-linux-generic -verify-machineinstrs -mattr=avx | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX --check-prefix=X64-AVX1 9; RUN: llc < %s -mtriple=x86_64-linux-generic -verify-machineinstrs -mattr=avx512f | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX --check-prefix=X64-AVX512 10 11; Note: This test is testing that the lowering for atomics matches what we 12; currently emit for non-atomics + the atomic restriction. The presence of 13; particular lowering detail in these tests should not be read as requiring 14; that detail for correctness unless it's related to the atomicity itself. 15; (Specifically, there were reviewer questions about the lowering for halfs 16; and their calling convention which remain unresolved.) 17 18define void @store_half(half* %fptr, half %v) { 19; X86-SSE-LABEL: store_half: 20; X86-SSE: # %bb.0: 21; X86-SSE-NEXT: pushl %esi 22; X86-SSE-NEXT: .cfi_def_cfa_offset 8 23; X86-SSE-NEXT: subl $8, %esp 24; X86-SSE-NEXT: .cfi_def_cfa_offset 16 25; X86-SSE-NEXT: .cfi_offset %esi, -8 26; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 27; X86-SSE-NEXT: movss %xmm0, (%esp) 28; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %esi 29; X86-SSE-NEXT: calll __gnu_f2h_ieee 30; X86-SSE-NEXT: movw %ax, (%esi) 31; X86-SSE-NEXT: addl $8, %esp 32; X86-SSE-NEXT: .cfi_def_cfa_offset 8 33; X86-SSE-NEXT: popl %esi 34; X86-SSE-NEXT: .cfi_def_cfa_offset 4 35; X86-SSE-NEXT: retl 36; 37; X86-AVX1-LABEL: store_half: 38; X86-AVX1: # %bb.0: 39; X86-AVX1-NEXT: pushl %esi 40; X86-AVX1-NEXT: .cfi_def_cfa_offset 8 41; X86-AVX1-NEXT: subl $8, %esp 42; X86-AVX1-NEXT: .cfi_def_cfa_offset 16 43; X86-AVX1-NEXT: .cfi_offset %esi, -8 44; X86-AVX1-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero 45; X86-AVX1-NEXT: vmovss %xmm0, (%esp) 46; X86-AVX1-NEXT: movl {{[0-9]+}}(%esp), %esi 47; X86-AVX1-NEXT: calll __gnu_f2h_ieee 48; X86-AVX1-NEXT: movw %ax, (%esi) 49; X86-AVX1-NEXT: addl $8, %esp 50; X86-AVX1-NEXT: .cfi_def_cfa_offset 8 51; X86-AVX1-NEXT: popl %esi 52; X86-AVX1-NEXT: .cfi_def_cfa_offset 4 53; X86-AVX1-NEXT: retl 54; 55; X86-AVX512-LABEL: store_half: 56; X86-AVX512: # %bb.0: 57; X86-AVX512-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero 58; X86-AVX512-NEXT: vcvtps2ph $4, %xmm0, %xmm0 59; X86-AVX512-NEXT: vmovd %xmm0, %eax 60; X86-AVX512-NEXT: movl {{[0-9]+}}(%esp), %ecx 61; X86-AVX512-NEXT: movw %ax, (%ecx) 62; X86-AVX512-NEXT: retl 63; 64; X86-NOSSE-LABEL: store_half: 65; X86-NOSSE: # %bb.0: 66; X86-NOSSE-NEXT: pushl %esi 67; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 68; X86-NOSSE-NEXT: subl $8, %esp 69; X86-NOSSE-NEXT: .cfi_def_cfa_offset 16 70; X86-NOSSE-NEXT: .cfi_offset %esi, -8 71; X86-NOSSE-NEXT: flds {{[0-9]+}}(%esp) 72; X86-NOSSE-NEXT: fstps (%esp) 73; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %esi 74; X86-NOSSE-NEXT: calll __gnu_f2h_ieee 75; X86-NOSSE-NEXT: movw %ax, (%esi) 76; X86-NOSSE-NEXT: addl $8, %esp 77; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 78; X86-NOSSE-NEXT: popl %esi 79; X86-NOSSE-NEXT: .cfi_def_cfa_offset 4 80; X86-NOSSE-NEXT: retl 81; 82; X64-SSE-LABEL: store_half: 83; X64-SSE: # %bb.0: 84; X64-SSE-NEXT: pushq %rbx 85; X64-SSE-NEXT: .cfi_def_cfa_offset 16 86; X64-SSE-NEXT: .cfi_offset %rbx, -16 87; X64-SSE-NEXT: movq %rdi, %rbx 88; X64-SSE-NEXT: callq __gnu_f2h_ieee 89; X64-SSE-NEXT: movw %ax, (%rbx) 90; X64-SSE-NEXT: popq %rbx 91; X64-SSE-NEXT: .cfi_def_cfa_offset 8 92; X64-SSE-NEXT: retq 93; 94; X64-AVX1-LABEL: store_half: 95; X64-AVX1: # %bb.0: 96; X64-AVX1-NEXT: pushq %rbx 97; X64-AVX1-NEXT: .cfi_def_cfa_offset 16 98; X64-AVX1-NEXT: .cfi_offset %rbx, -16 99; X64-AVX1-NEXT: movq %rdi, %rbx 100; X64-AVX1-NEXT: callq __gnu_f2h_ieee 101; X64-AVX1-NEXT: movw %ax, (%rbx) 102; X64-AVX1-NEXT: popq %rbx 103; X64-AVX1-NEXT: .cfi_def_cfa_offset 8 104; X64-AVX1-NEXT: retq 105; 106; X64-AVX512-LABEL: store_half: 107; X64-AVX512: # %bb.0: 108; X64-AVX512-NEXT: vcvtps2ph $4, %xmm0, %xmm0 109; X64-AVX512-NEXT: vmovd %xmm0, %eax 110; X64-AVX512-NEXT: movw %ax, (%rdi) 111; X64-AVX512-NEXT: retq 112 store atomic half %v, half* %fptr unordered, align 2 113 ret void 114} 115 116define void @store_float(float* %fptr, float %v) { 117; X86-SSE-LABEL: store_float: 118; X86-SSE: # %bb.0: 119; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 120; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax 121; X86-SSE-NEXT: movss %xmm0, (%eax) 122; X86-SSE-NEXT: retl 123; 124; X86-AVX-LABEL: store_float: 125; X86-AVX: # %bb.0: 126; X86-AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero 127; X86-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax 128; X86-AVX-NEXT: vmovss %xmm0, (%eax) 129; X86-AVX-NEXT: retl 130; 131; X86-NOSSE-LABEL: store_float: 132; X86-NOSSE: # %bb.0: 133; X86-NOSSE-NEXT: flds {{[0-9]+}}(%esp) 134; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %eax 135; X86-NOSSE-NEXT: fstps (%eax) 136; X86-NOSSE-NEXT: retl 137; 138; X64-SSE-LABEL: store_float: 139; X64-SSE: # %bb.0: 140; X64-SSE-NEXT: movss %xmm0, (%rdi) 141; X64-SSE-NEXT: retq 142; 143; X64-AVX-LABEL: store_float: 144; X64-AVX: # %bb.0: 145; X64-AVX-NEXT: vmovss %xmm0, (%rdi) 146; X64-AVX-NEXT: retq 147 store atomic float %v, float* %fptr unordered, align 4 148 ret void 149} 150 151define void @store_double(double* %fptr, double %v) { 152; X86-SSE1-LABEL: store_double: 153; X86-SSE1: # %bb.0: 154; X86-SSE1-NEXT: pushl %ebx 155; X86-SSE1-NEXT: .cfi_def_cfa_offset 8 156; X86-SSE1-NEXT: pushl %esi 157; X86-SSE1-NEXT: .cfi_def_cfa_offset 12 158; X86-SSE1-NEXT: .cfi_offset %esi, -12 159; X86-SSE1-NEXT: .cfi_offset %ebx, -8 160; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %esi 161; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ebx 162; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx 163; X86-SSE1-NEXT: movl (%esi), %eax 164; X86-SSE1-NEXT: movl 4(%esi), %edx 165; X86-SSE1-NEXT: .p2align 4, 0x90 166; X86-SSE1-NEXT: .LBB2_1: # %atomicrmw.start 167; X86-SSE1-NEXT: # =>This Inner Loop Header: Depth=1 168; X86-SSE1-NEXT: lock cmpxchg8b (%esi) 169; X86-SSE1-NEXT: jne .LBB2_1 170; X86-SSE1-NEXT: # %bb.2: # %atomicrmw.end 171; X86-SSE1-NEXT: popl %esi 172; X86-SSE1-NEXT: .cfi_def_cfa_offset 8 173; X86-SSE1-NEXT: popl %ebx 174; X86-SSE1-NEXT: .cfi_def_cfa_offset 4 175; X86-SSE1-NEXT: retl 176; 177; X86-SSE2-LABEL: store_double: 178; X86-SSE2: # %bb.0: 179; X86-SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 180; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 181; X86-SSE2-NEXT: movsd %xmm0, (%eax) 182; X86-SSE2-NEXT: retl 183; 184; X86-AVX-LABEL: store_double: 185; X86-AVX: # %bb.0: 186; X86-AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 187; X86-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax 188; X86-AVX-NEXT: vmovsd %xmm0, (%eax) 189; X86-AVX-NEXT: retl 190; 191; X86-NOSSE-LABEL: store_double: 192; X86-NOSSE: # %bb.0: 193; X86-NOSSE-NEXT: pushl %ebx 194; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 195; X86-NOSSE-NEXT: pushl %esi 196; X86-NOSSE-NEXT: .cfi_def_cfa_offset 12 197; X86-NOSSE-NEXT: .cfi_offset %esi, -12 198; X86-NOSSE-NEXT: .cfi_offset %ebx, -8 199; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %esi 200; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %ebx 201; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %ecx 202; X86-NOSSE-NEXT: movl (%esi), %eax 203; X86-NOSSE-NEXT: movl 4(%esi), %edx 204; X86-NOSSE-NEXT: .p2align 4, 0x90 205; X86-NOSSE-NEXT: .LBB2_1: # %atomicrmw.start 206; X86-NOSSE-NEXT: # =>This Inner Loop Header: Depth=1 207; X86-NOSSE-NEXT: lock cmpxchg8b (%esi) 208; X86-NOSSE-NEXT: jne .LBB2_1 209; X86-NOSSE-NEXT: # %bb.2: # %atomicrmw.end 210; X86-NOSSE-NEXT: popl %esi 211; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 212; X86-NOSSE-NEXT: popl %ebx 213; X86-NOSSE-NEXT: .cfi_def_cfa_offset 4 214; X86-NOSSE-NEXT: retl 215; 216; X64-SSE-LABEL: store_double: 217; X64-SSE: # %bb.0: 218; X64-SSE-NEXT: movsd %xmm0, (%rdi) 219; X64-SSE-NEXT: retq 220; 221; X64-AVX-LABEL: store_double: 222; X64-AVX: # %bb.0: 223; X64-AVX-NEXT: vmovsd %xmm0, (%rdi) 224; X64-AVX-NEXT: retq 225 store atomic double %v, double* %fptr unordered, align 8 226 ret void 227} 228 229define void @store_fp128(fp128* %fptr, fp128 %v) { 230; X86-SSE-LABEL: store_fp128: 231; X86-SSE: # %bb.0: 232; X86-SSE-NEXT: subl $36, %esp 233; X86-SSE-NEXT: .cfi_adjust_cfa_offset 36 234; X86-SSE-NEXT: leal {{[0-9]+}}(%esp), %eax 235; X86-SSE-NEXT: pushl {{[0-9]+}}(%esp) 236; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 237; X86-SSE-NEXT: pushl {{[0-9]+}}(%esp) 238; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 239; X86-SSE-NEXT: pushl {{[0-9]+}}(%esp) 240; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 241; X86-SSE-NEXT: pushl {{[0-9]+}}(%esp) 242; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 243; X86-SSE-NEXT: pushl {{[0-9]+}}(%esp) 244; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 245; X86-SSE-NEXT: pushl %eax 246; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 247; X86-SSE-NEXT: calll __sync_lock_test_and_set_16 248; X86-SSE-NEXT: .cfi_adjust_cfa_offset -4 249; X86-SSE-NEXT: addl $56, %esp 250; X86-SSE-NEXT: .cfi_adjust_cfa_offset -56 251; X86-SSE-NEXT: retl 252; 253; X86-AVX-LABEL: store_fp128: 254; X86-AVX: # %bb.0: 255; X86-AVX-NEXT: subl $44, %esp 256; X86-AVX-NEXT: .cfi_def_cfa_offset 48 257; X86-AVX-NEXT: vmovaps {{[0-9]+}}(%esp), %xmm0 258; X86-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax 259; X86-AVX-NEXT: movl %eax, {{[0-9]+}}(%esp) 260; X86-AVX-NEXT: vmovups %xmm0, {{[0-9]+}}(%esp) 261; X86-AVX-NEXT: leal {{[0-9]+}}(%esp), %eax 262; X86-AVX-NEXT: movl %eax, (%esp) 263; X86-AVX-NEXT: calll __sync_lock_test_and_set_16 264; X86-AVX-NEXT: addl $40, %esp 265; X86-AVX-NEXT: .cfi_def_cfa_offset 4 266; X86-AVX-NEXT: retl 267; 268; X86-NOSSE-LABEL: store_fp128: 269; X86-NOSSE: # %bb.0: 270; X86-NOSSE-NEXT: subl $36, %esp 271; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 36 272; X86-NOSSE-NEXT: leal {{[0-9]+}}(%esp), %eax 273; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 274; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 275; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 276; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 277; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 278; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 279; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 280; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 281; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 282; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 283; X86-NOSSE-NEXT: pushl %eax 284; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 285; X86-NOSSE-NEXT: calll __sync_lock_test_and_set_16 286; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset -4 287; X86-NOSSE-NEXT: addl $56, %esp 288; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset -56 289; X86-NOSSE-NEXT: retl 290; 291; X64-SSE-LABEL: store_fp128: 292; X64-SSE: # %bb.0: 293; X64-SSE-NEXT: movaps %xmm0, (%rdi) 294; X64-SSE-NEXT: retq 295; 296; X64-AVX-LABEL: store_fp128: 297; X64-AVX: # %bb.0: 298; X64-AVX-NEXT: vmovaps %xmm0, (%rdi) 299; X64-AVX-NEXT: retq 300 store atomic fp128 %v, fp128* %fptr unordered, align 16 301 ret void 302} 303 304define half @load_half(half* %fptr) { 305; X86-SSE-LABEL: load_half: 306; X86-SSE: # %bb.0: 307; X86-SSE-NEXT: subl $12, %esp 308; X86-SSE-NEXT: .cfi_def_cfa_offset 16 309; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax 310; X86-SSE-NEXT: movzwl (%eax), %eax 311; X86-SSE-NEXT: movl %eax, (%esp) 312; X86-SSE-NEXT: calll __gnu_h2f_ieee 313; X86-SSE-NEXT: addl $12, %esp 314; X86-SSE-NEXT: .cfi_def_cfa_offset 4 315; X86-SSE-NEXT: retl 316; 317; X86-AVX1-LABEL: load_half: 318; X86-AVX1: # %bb.0: 319; X86-AVX1-NEXT: subl $12, %esp 320; X86-AVX1-NEXT: .cfi_def_cfa_offset 16 321; X86-AVX1-NEXT: movl {{[0-9]+}}(%esp), %eax 322; X86-AVX1-NEXT: movzwl (%eax), %eax 323; X86-AVX1-NEXT: movl %eax, (%esp) 324; X86-AVX1-NEXT: calll __gnu_h2f_ieee 325; X86-AVX1-NEXT: addl $12, %esp 326; X86-AVX1-NEXT: .cfi_def_cfa_offset 4 327; X86-AVX1-NEXT: retl 328; 329; X86-AVX512-LABEL: load_half: 330; X86-AVX512: # %bb.0: 331; X86-AVX512-NEXT: pushl %eax 332; X86-AVX512-NEXT: .cfi_def_cfa_offset 8 333; X86-AVX512-NEXT: movl {{[0-9]+}}(%esp), %eax 334; X86-AVX512-NEXT: movswl (%eax), %eax 335; X86-AVX512-NEXT: vmovd %eax, %xmm0 336; X86-AVX512-NEXT: vcvtph2ps %xmm0, %xmm0 337; X86-AVX512-NEXT: vmovss %xmm0, (%esp) 338; X86-AVX512-NEXT: flds (%esp) 339; X86-AVX512-NEXT: popl %eax 340; X86-AVX512-NEXT: .cfi_def_cfa_offset 4 341; X86-AVX512-NEXT: retl 342; 343; X86-NOSSE-LABEL: load_half: 344; X86-NOSSE: # %bb.0: 345; X86-NOSSE-NEXT: subl $12, %esp 346; X86-NOSSE-NEXT: .cfi_def_cfa_offset 16 347; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %eax 348; X86-NOSSE-NEXT: movzwl (%eax), %eax 349; X86-NOSSE-NEXT: movl %eax, (%esp) 350; X86-NOSSE-NEXT: calll __gnu_h2f_ieee 351; X86-NOSSE-NEXT: addl $12, %esp 352; X86-NOSSE-NEXT: .cfi_def_cfa_offset 4 353; X86-NOSSE-NEXT: retl 354; 355; X64-SSE-LABEL: load_half: 356; X64-SSE: # %bb.0: 357; X64-SSE-NEXT: pushq %rax 358; X64-SSE-NEXT: .cfi_def_cfa_offset 16 359; X64-SSE-NEXT: movzwl (%rdi), %edi 360; X64-SSE-NEXT: callq __gnu_h2f_ieee 361; X64-SSE-NEXT: popq %rax 362; X64-SSE-NEXT: .cfi_def_cfa_offset 8 363; X64-SSE-NEXT: retq 364; 365; X64-AVX1-LABEL: load_half: 366; X64-AVX1: # %bb.0: 367; X64-AVX1-NEXT: pushq %rax 368; X64-AVX1-NEXT: .cfi_def_cfa_offset 16 369; X64-AVX1-NEXT: movzwl (%rdi), %edi 370; X64-AVX1-NEXT: callq __gnu_h2f_ieee 371; X64-AVX1-NEXT: popq %rax 372; X64-AVX1-NEXT: .cfi_def_cfa_offset 8 373; X64-AVX1-NEXT: retq 374; 375; X64-AVX512-LABEL: load_half: 376; X64-AVX512: # %bb.0: 377; X64-AVX512-NEXT: movswl (%rdi), %eax 378; X64-AVX512-NEXT: vmovd %eax, %xmm0 379; X64-AVX512-NEXT: vcvtph2ps %xmm0, %xmm0 380; X64-AVX512-NEXT: retq 381 %v = load atomic half, half* %fptr unordered, align 2 382 ret half %v 383} 384 385define float @load_float(float* %fptr) { 386; X86-LABEL: load_float: 387; X86: # %bb.0: 388; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 389; X86-NEXT: flds (%eax) 390; X86-NEXT: retl 391; 392; X64-SSE-LABEL: load_float: 393; X64-SSE: # %bb.0: 394; X64-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 395; X64-SSE-NEXT: retq 396; 397; X64-AVX-LABEL: load_float: 398; X64-AVX: # %bb.0: 399; X64-AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero 400; X64-AVX-NEXT: retq 401 %v = load atomic float, float* %fptr unordered, align 4 402 ret float %v 403} 404 405define double @load_double(double* %fptr) { 406; X86-LABEL: load_double: 407; X86: # %bb.0: 408; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 409; X86-NEXT: fldl (%eax) 410; X86-NEXT: retl 411; 412; X64-SSE-LABEL: load_double: 413; X64-SSE: # %bb.0: 414; X64-SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 415; X64-SSE-NEXT: retq 416; 417; X64-AVX-LABEL: load_double: 418; X64-AVX: # %bb.0: 419; X64-AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 420; X64-AVX-NEXT: retq 421 %v = load atomic double, double* %fptr unordered, align 8 422 ret double %v 423} 424 425define fp128 @load_fp128(fp128* %fptr) { 426; X86-SSE-LABEL: load_fp128: 427; X86-SSE: # %bb.0: 428; X86-SSE-NEXT: pushl %edi 429; X86-SSE-NEXT: .cfi_def_cfa_offset 8 430; X86-SSE-NEXT: pushl %esi 431; X86-SSE-NEXT: .cfi_def_cfa_offset 12 432; X86-SSE-NEXT: subl $20, %esp 433; X86-SSE-NEXT: .cfi_def_cfa_offset 32 434; X86-SSE-NEXT: .cfi_offset %esi, -12 435; X86-SSE-NEXT: .cfi_offset %edi, -8 436; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %esi 437; X86-SSE-NEXT: subl $8, %esp 438; X86-SSE-NEXT: .cfi_adjust_cfa_offset 8 439; X86-SSE-NEXT: leal {{[0-9]+}}(%esp), %eax 440; X86-SSE-NEXT: pushl $0 441; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 442; X86-SSE-NEXT: pushl $0 443; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 444; X86-SSE-NEXT: pushl $0 445; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 446; X86-SSE-NEXT: pushl $0 447; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 448; X86-SSE-NEXT: pushl $0 449; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 450; X86-SSE-NEXT: pushl $0 451; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 452; X86-SSE-NEXT: pushl $0 453; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 454; X86-SSE-NEXT: pushl $0 455; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 456; X86-SSE-NEXT: pushl {{[0-9]+}}(%esp) 457; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 458; X86-SSE-NEXT: pushl %eax 459; X86-SSE-NEXT: .cfi_adjust_cfa_offset 4 460; X86-SSE-NEXT: calll __sync_val_compare_and_swap_16 461; X86-SSE-NEXT: .cfi_adjust_cfa_offset -4 462; X86-SSE-NEXT: addl $44, %esp 463; X86-SSE-NEXT: .cfi_adjust_cfa_offset -44 464; X86-SSE-NEXT: movl (%esp), %eax 465; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %ecx 466; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %edx 467; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %edi 468; X86-SSE-NEXT: movl %edi, 12(%esi) 469; X86-SSE-NEXT: movl %edx, 8(%esi) 470; X86-SSE-NEXT: movl %ecx, 4(%esi) 471; X86-SSE-NEXT: movl %eax, (%esi) 472; X86-SSE-NEXT: movl %esi, %eax 473; X86-SSE-NEXT: addl $20, %esp 474; X86-SSE-NEXT: .cfi_def_cfa_offset 12 475; X86-SSE-NEXT: popl %esi 476; X86-SSE-NEXT: .cfi_def_cfa_offset 8 477; X86-SSE-NEXT: popl %edi 478; X86-SSE-NEXT: .cfi_def_cfa_offset 4 479; X86-SSE-NEXT: retl $4 480; 481; X86-AVX-LABEL: load_fp128: 482; X86-AVX: # %bb.0: 483; X86-AVX-NEXT: pushl %esi 484; X86-AVX-NEXT: .cfi_def_cfa_offset 8 485; X86-AVX-NEXT: subl $56, %esp 486; X86-AVX-NEXT: .cfi_def_cfa_offset 64 487; X86-AVX-NEXT: .cfi_offset %esi, -8 488; X86-AVX-NEXT: movl {{[0-9]+}}(%esp), %esi 489; X86-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax 490; X86-AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 491; X86-AVX-NEXT: vmovups %ymm0, {{[0-9]+}}(%esp) 492; X86-AVX-NEXT: movl %eax, {{[0-9]+}}(%esp) 493; X86-AVX-NEXT: leal {{[0-9]+}}(%esp), %eax 494; X86-AVX-NEXT: movl %eax, (%esp) 495; X86-AVX-NEXT: vzeroupper 496; X86-AVX-NEXT: calll __sync_val_compare_and_swap_16 497; X86-AVX-NEXT: subl $4, %esp 498; X86-AVX-NEXT: vmovups {{[0-9]+}}(%esp), %xmm0 499; X86-AVX-NEXT: vmovaps %xmm0, (%esi) 500; X86-AVX-NEXT: movl %esi, %eax 501; X86-AVX-NEXT: addl $56, %esp 502; X86-AVX-NEXT: .cfi_def_cfa_offset 8 503; X86-AVX-NEXT: popl %esi 504; X86-AVX-NEXT: .cfi_def_cfa_offset 4 505; X86-AVX-NEXT: retl $4 506; 507; X86-NOSSE-LABEL: load_fp128: 508; X86-NOSSE: # %bb.0: 509; X86-NOSSE-NEXT: pushl %edi 510; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 511; X86-NOSSE-NEXT: pushl %esi 512; X86-NOSSE-NEXT: .cfi_def_cfa_offset 12 513; X86-NOSSE-NEXT: subl $20, %esp 514; X86-NOSSE-NEXT: .cfi_def_cfa_offset 32 515; X86-NOSSE-NEXT: .cfi_offset %esi, -12 516; X86-NOSSE-NEXT: .cfi_offset %edi, -8 517; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %esi 518; X86-NOSSE-NEXT: subl $8, %esp 519; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 8 520; X86-NOSSE-NEXT: leal {{[0-9]+}}(%esp), %eax 521; X86-NOSSE-NEXT: pushl $0 522; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 523; X86-NOSSE-NEXT: pushl $0 524; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 525; X86-NOSSE-NEXT: pushl $0 526; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 527; X86-NOSSE-NEXT: pushl $0 528; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 529; X86-NOSSE-NEXT: pushl $0 530; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 531; X86-NOSSE-NEXT: pushl $0 532; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 533; X86-NOSSE-NEXT: pushl $0 534; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 535; X86-NOSSE-NEXT: pushl $0 536; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 537; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 538; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 539; X86-NOSSE-NEXT: pushl %eax 540; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset 4 541; X86-NOSSE-NEXT: calll __sync_val_compare_and_swap_16 542; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset -4 543; X86-NOSSE-NEXT: addl $44, %esp 544; X86-NOSSE-NEXT: .cfi_adjust_cfa_offset -44 545; X86-NOSSE-NEXT: movl (%esp), %eax 546; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %ecx 547; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %edx 548; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %edi 549; X86-NOSSE-NEXT: movl %edi, 12(%esi) 550; X86-NOSSE-NEXT: movl %edx, 8(%esi) 551; X86-NOSSE-NEXT: movl %ecx, 4(%esi) 552; X86-NOSSE-NEXT: movl %eax, (%esi) 553; X86-NOSSE-NEXT: movl %esi, %eax 554; X86-NOSSE-NEXT: addl $20, %esp 555; X86-NOSSE-NEXT: .cfi_def_cfa_offset 12 556; X86-NOSSE-NEXT: popl %esi 557; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 558; X86-NOSSE-NEXT: popl %edi 559; X86-NOSSE-NEXT: .cfi_def_cfa_offset 4 560; X86-NOSSE-NEXT: retl $4 561; 562; X64-SSE-LABEL: load_fp128: 563; X64-SSE: # %bb.0: 564; X64-SSE-NEXT: movaps (%rdi), %xmm0 565; X64-SSE-NEXT: retq 566; 567; X64-AVX-LABEL: load_fp128: 568; X64-AVX: # %bb.0: 569; X64-AVX-NEXT: vmovaps (%rdi), %xmm0 570; X64-AVX-NEXT: retq 571 %v = load atomic fp128, fp128* %fptr unordered, align 16 572 ret fp128 %v 573} 574 575 576; sanity check the seq_cst lowering since that's the 577; interesting one from an ordering perspective on x86. 578 579define void @store_float_seq_cst(float* %fptr, float %v) { 580; X86-LABEL: store_float_seq_cst: 581; X86: # %bb.0: 582; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 583; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 584; X86-NEXT: xchgl %ecx, (%eax) 585; X86-NEXT: retl 586; 587; X64-SSE-LABEL: store_float_seq_cst: 588; X64-SSE: # %bb.0: 589; X64-SSE-NEXT: movd %xmm0, %eax 590; X64-SSE-NEXT: xchgl %eax, (%rdi) 591; X64-SSE-NEXT: retq 592; 593; X64-AVX-LABEL: store_float_seq_cst: 594; X64-AVX: # %bb.0: 595; X64-AVX-NEXT: vmovd %xmm0, %eax 596; X64-AVX-NEXT: xchgl %eax, (%rdi) 597; X64-AVX-NEXT: retq 598 store atomic float %v, float* %fptr seq_cst, align 4 599 ret void 600} 601 602define void @store_double_seq_cst(double* %fptr, double %v) { 603; X86-SSE1-LABEL: store_double_seq_cst: 604; X86-SSE1: # %bb.0: 605; X86-SSE1-NEXT: pushl %ebx 606; X86-SSE1-NEXT: .cfi_def_cfa_offset 8 607; X86-SSE1-NEXT: pushl %esi 608; X86-SSE1-NEXT: .cfi_def_cfa_offset 12 609; X86-SSE1-NEXT: .cfi_offset %esi, -12 610; X86-SSE1-NEXT: .cfi_offset %ebx, -8 611; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %esi 612; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ebx 613; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx 614; X86-SSE1-NEXT: movl (%esi), %eax 615; X86-SSE1-NEXT: movl 4(%esi), %edx 616; X86-SSE1-NEXT: .p2align 4, 0x90 617; X86-SSE1-NEXT: .LBB9_1: # %atomicrmw.start 618; X86-SSE1-NEXT: # =>This Inner Loop Header: Depth=1 619; X86-SSE1-NEXT: lock cmpxchg8b (%esi) 620; X86-SSE1-NEXT: jne .LBB9_1 621; X86-SSE1-NEXT: # %bb.2: # %atomicrmw.end 622; X86-SSE1-NEXT: popl %esi 623; X86-SSE1-NEXT: .cfi_def_cfa_offset 8 624; X86-SSE1-NEXT: popl %ebx 625; X86-SSE1-NEXT: .cfi_def_cfa_offset 4 626; X86-SSE1-NEXT: retl 627; 628; X86-SSE2-LABEL: store_double_seq_cst: 629; X86-SSE2: # %bb.0: 630; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 631; X86-SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 632; X86-SSE2-NEXT: movlps %xmm0, (%eax) 633; X86-SSE2-NEXT: lock orl $0, (%esp) 634; X86-SSE2-NEXT: retl 635; 636; X86-AVX-LABEL: store_double_seq_cst: 637; X86-AVX: # %bb.0: 638; X86-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax 639; X86-AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 640; X86-AVX-NEXT: vmovlps %xmm0, (%eax) 641; X86-AVX-NEXT: lock orl $0, (%esp) 642; X86-AVX-NEXT: retl 643; 644; X86-NOSSE-LABEL: store_double_seq_cst: 645; X86-NOSSE: # %bb.0: 646; X86-NOSSE-NEXT: pushl %ebx 647; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 648; X86-NOSSE-NEXT: pushl %esi 649; X86-NOSSE-NEXT: .cfi_def_cfa_offset 12 650; X86-NOSSE-NEXT: .cfi_offset %esi, -12 651; X86-NOSSE-NEXT: .cfi_offset %ebx, -8 652; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %esi 653; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %ebx 654; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %ecx 655; X86-NOSSE-NEXT: movl (%esi), %eax 656; X86-NOSSE-NEXT: movl 4(%esi), %edx 657; X86-NOSSE-NEXT: .p2align 4, 0x90 658; X86-NOSSE-NEXT: .LBB9_1: # %atomicrmw.start 659; X86-NOSSE-NEXT: # =>This Inner Loop Header: Depth=1 660; X86-NOSSE-NEXT: lock cmpxchg8b (%esi) 661; X86-NOSSE-NEXT: jne .LBB9_1 662; X86-NOSSE-NEXT: # %bb.2: # %atomicrmw.end 663; X86-NOSSE-NEXT: popl %esi 664; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 665; X86-NOSSE-NEXT: popl %ebx 666; X86-NOSSE-NEXT: .cfi_def_cfa_offset 4 667; X86-NOSSE-NEXT: retl 668; 669; X64-SSE-LABEL: store_double_seq_cst: 670; X64-SSE: # %bb.0: 671; X64-SSE-NEXT: movq %xmm0, %rax 672; X64-SSE-NEXT: xchgq %rax, (%rdi) 673; X64-SSE-NEXT: retq 674; 675; X64-AVX-LABEL: store_double_seq_cst: 676; X64-AVX: # %bb.0: 677; X64-AVX-NEXT: vmovq %xmm0, %rax 678; X64-AVX-NEXT: xchgq %rax, (%rdi) 679; X64-AVX-NEXT: retq 680 store atomic double %v, double* %fptr seq_cst, align 8 681 ret void 682} 683 684define float @load_float_seq_cst(float* %fptr) { 685; X86-SSE1-LABEL: load_float_seq_cst: 686; X86-SSE1: # %bb.0: 687; X86-SSE1-NEXT: pushl %eax 688; X86-SSE1-NEXT: .cfi_def_cfa_offset 8 689; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax 690; X86-SSE1-NEXT: movl (%eax), %eax 691; X86-SSE1-NEXT: movl %eax, (%esp) 692; X86-SSE1-NEXT: flds (%esp) 693; X86-SSE1-NEXT: popl %eax 694; X86-SSE1-NEXT: .cfi_def_cfa_offset 4 695; X86-SSE1-NEXT: retl 696; 697; X86-SSE2-LABEL: load_float_seq_cst: 698; X86-SSE2: # %bb.0: 699; X86-SSE2-NEXT: pushl %eax 700; X86-SSE2-NEXT: .cfi_def_cfa_offset 8 701; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 702; X86-SSE2-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 703; X86-SSE2-NEXT: movss %xmm0, (%esp) 704; X86-SSE2-NEXT: flds (%esp) 705; X86-SSE2-NEXT: popl %eax 706; X86-SSE2-NEXT: .cfi_def_cfa_offset 4 707; X86-SSE2-NEXT: retl 708; 709; X86-AVX-LABEL: load_float_seq_cst: 710; X86-AVX: # %bb.0: 711; X86-AVX-NEXT: pushl %eax 712; X86-AVX-NEXT: .cfi_def_cfa_offset 8 713; X86-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax 714; X86-AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero 715; X86-AVX-NEXT: vmovss %xmm0, (%esp) 716; X86-AVX-NEXT: flds (%esp) 717; X86-AVX-NEXT: popl %eax 718; X86-AVX-NEXT: .cfi_def_cfa_offset 4 719; X86-AVX-NEXT: retl 720; 721; X86-NOSSE-LABEL: load_float_seq_cst: 722; X86-NOSSE: # %bb.0: 723; X86-NOSSE-NEXT: pushl %eax 724; X86-NOSSE-NEXT: .cfi_def_cfa_offset 8 725; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %eax 726; X86-NOSSE-NEXT: movl (%eax), %eax 727; X86-NOSSE-NEXT: movl %eax, (%esp) 728; X86-NOSSE-NEXT: flds (%esp) 729; X86-NOSSE-NEXT: popl %eax 730; X86-NOSSE-NEXT: .cfi_def_cfa_offset 4 731; X86-NOSSE-NEXT: retl 732; 733; X64-SSE-LABEL: load_float_seq_cst: 734; X64-SSE: # %bb.0: 735; X64-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 736; X64-SSE-NEXT: retq 737; 738; X64-AVX-LABEL: load_float_seq_cst: 739; X64-AVX: # %bb.0: 740; X64-AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero 741; X64-AVX-NEXT: retq 742 %v = load atomic float, float* %fptr seq_cst, align 4 743 ret float %v 744} 745 746define double @load_double_seq_cst(double* %fptr) { 747; X86-SSE1-LABEL: load_double_seq_cst: 748; X86-SSE1: # %bb.0: 749; X86-SSE1-NEXT: subl $20, %esp 750; X86-SSE1-NEXT: .cfi_def_cfa_offset 24 751; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax 752; X86-SSE1-NEXT: fildll (%eax) 753; X86-SSE1-NEXT: fistpll {{[0-9]+}}(%esp) 754; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax 755; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx 756; X86-SSE1-NEXT: movl %ecx, {{[0-9]+}}(%esp) 757; X86-SSE1-NEXT: movl %eax, (%esp) 758; X86-SSE1-NEXT: fldl (%esp) 759; X86-SSE1-NEXT: addl $20, %esp 760; X86-SSE1-NEXT: .cfi_def_cfa_offset 4 761; X86-SSE1-NEXT: retl 762; 763; X86-SSE2-LABEL: load_double_seq_cst: 764; X86-SSE2: # %bb.0: 765; X86-SSE2-NEXT: subl $12, %esp 766; X86-SSE2-NEXT: .cfi_def_cfa_offset 16 767; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 768; X86-SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 769; X86-SSE2-NEXT: movlps %xmm0, (%esp) 770; X86-SSE2-NEXT: fldl (%esp) 771; X86-SSE2-NEXT: addl $12, %esp 772; X86-SSE2-NEXT: .cfi_def_cfa_offset 4 773; X86-SSE2-NEXT: retl 774; 775; X86-AVX-LABEL: load_double_seq_cst: 776; X86-AVX: # %bb.0: 777; X86-AVX-NEXT: subl $12, %esp 778; X86-AVX-NEXT: .cfi_def_cfa_offset 16 779; X86-AVX-NEXT: movl {{[0-9]+}}(%esp), %eax 780; X86-AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 781; X86-AVX-NEXT: vmovlps %xmm0, (%esp) 782; X86-AVX-NEXT: fldl (%esp) 783; X86-AVX-NEXT: addl $12, %esp 784; X86-AVX-NEXT: .cfi_def_cfa_offset 4 785; X86-AVX-NEXT: retl 786; 787; X86-NOSSE-LABEL: load_double_seq_cst: 788; X86-NOSSE: # %bb.0: 789; X86-NOSSE-NEXT: subl $20, %esp 790; X86-NOSSE-NEXT: .cfi_def_cfa_offset 24 791; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %eax 792; X86-NOSSE-NEXT: fildll (%eax) 793; X86-NOSSE-NEXT: fistpll {{[0-9]+}}(%esp) 794; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %eax 795; X86-NOSSE-NEXT: movl {{[0-9]+}}(%esp), %ecx 796; X86-NOSSE-NEXT: movl %ecx, {{[0-9]+}}(%esp) 797; X86-NOSSE-NEXT: movl %eax, (%esp) 798; X86-NOSSE-NEXT: fldl (%esp) 799; X86-NOSSE-NEXT: addl $20, %esp 800; X86-NOSSE-NEXT: .cfi_def_cfa_offset 4 801; X86-NOSSE-NEXT: retl 802; 803; X64-SSE-LABEL: load_double_seq_cst: 804; X64-SSE: # %bb.0: 805; X64-SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 806; X64-SSE-NEXT: retq 807; 808; X64-AVX-LABEL: load_double_seq_cst: 809; X64-AVX: # %bb.0: 810; X64-AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 811; X64-AVX-NEXT: retq 812 %v = load atomic double, double* %fptr seq_cst, align 8 813 ret double %v 814} 815