1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-linux-generic -verify-machineinstrs -mattr=sse2 | FileCheck %s 3 4; Note: This test is testing that the lowering for atomics matches what we 5; currently emit for non-atomics + the atomic restriction. The presence of 6; particular lowering detail in these tests should not be read as requiring 7; that detail for correctness unless it's related to the atomicity itself. 8; (Specifically, there were reviewer questions about the lowering for halfs 9; and their calling convention which remain unresolved.) 10 11define void @store_half(half* %fptr, half %v) { 12; CHECK-LABEL: store_half: 13; CHECK: # %bb.0: 14; CHECK-NEXT: pushq %rbx 15; CHECK-NEXT: .cfi_def_cfa_offset 16 16; CHECK-NEXT: .cfi_offset %rbx, -16 17; CHECK-NEXT: movq %rdi, %rbx 18; CHECK-NEXT: callq __gnu_f2h_ieee 19; CHECK-NEXT: movw %ax, (%rbx) 20; CHECK-NEXT: popq %rbx 21; CHECK-NEXT: .cfi_def_cfa_offset 8 22; CHECK-NEXT: retq 23 store atomic half %v, half* %fptr unordered, align 2 24 ret void 25} 26 27define void @store_float(float* %fptr, float %v) { 28; CHECK-LABEL: store_float: 29; CHECK: # %bb.0: 30; CHECK-NEXT: movd %xmm0, %eax 31; CHECK-NEXT: movl %eax, (%rdi) 32; CHECK-NEXT: retq 33 store atomic float %v, float* %fptr unordered, align 4 34 ret void 35} 36 37define void @store_double(double* %fptr, double %v) { 38; CHECK-LABEL: store_double: 39; CHECK: # %bb.0: 40; CHECK-NEXT: movq %xmm0, %rax 41; CHECK-NEXT: movq %rax, (%rdi) 42; CHECK-NEXT: retq 43 store atomic double %v, double* %fptr unordered, align 8 44 ret void 45} 46 47define void @store_fp128(fp128* %fptr, fp128 %v) { 48; CHECK-LABEL: store_fp128: 49; CHECK: # %bb.0: 50; CHECK-NEXT: pushq %rax 51; CHECK-NEXT: .cfi_def_cfa_offset 16 52; CHECK-NEXT: callq __sync_lock_test_and_set_16 53; CHECK-NEXT: popq %rax 54; CHECK-NEXT: .cfi_def_cfa_offset 8 55; CHECK-NEXT: retq 56 store atomic fp128 %v, fp128* %fptr unordered, align 16 57 ret void 58} 59 60define half @load_half(half* %fptr) { 61; CHECK-LABEL: load_half: 62; CHECK: # %bb.0: 63; CHECK-NEXT: pushq %rax 64; CHECK-NEXT: .cfi_def_cfa_offset 16 65; CHECK-NEXT: movzwl (%rdi), %eax 66; CHECK-NEXT: movzwl %ax, %edi 67; CHECK-NEXT: callq __gnu_h2f_ieee 68; CHECK-NEXT: popq %rax 69; CHECK-NEXT: .cfi_def_cfa_offset 8 70; CHECK-NEXT: retq 71 %v = load atomic half, half* %fptr unordered, align 2 72 ret half %v 73} 74 75define float @load_float(float* %fptr) { 76; CHECK-LABEL: load_float: 77; CHECK: # %bb.0: 78; CHECK-NEXT: movl (%rdi), %eax 79; CHECK-NEXT: movd %eax, %xmm0 80; CHECK-NEXT: retq 81 %v = load atomic float, float* %fptr unordered, align 4 82 ret float %v 83} 84 85define double @load_double(double* %fptr) { 86; CHECK-LABEL: load_double: 87; CHECK: # %bb.0: 88; CHECK-NEXT: movq (%rdi), %rax 89; CHECK-NEXT: movq %rax, %xmm0 90; CHECK-NEXT: retq 91 %v = load atomic double, double* %fptr unordered, align 8 92 ret double %v 93} 94 95define fp128 @load_fp128(fp128* %fptr) { 96; CHECK-LABEL: load_fp128: 97; CHECK: # %bb.0: 98; CHECK-NEXT: pushq %rax 99; CHECK-NEXT: .cfi_def_cfa_offset 16 100; CHECK-NEXT: xorl %esi, %esi 101; CHECK-NEXT: xorl %edx, %edx 102; CHECK-NEXT: xorl %ecx, %ecx 103; CHECK-NEXT: xorl %r8d, %r8d 104; CHECK-NEXT: callq __sync_val_compare_and_swap_16 105; CHECK-NEXT: popq %rcx 106; CHECK-NEXT: .cfi_def_cfa_offset 8 107; CHECK-NEXT: retq 108 %v = load atomic fp128, fp128* %fptr unordered, align 16 109 ret fp128 %v 110} 111 112 113; sanity check the seq_cst lowering since that's the 114; interesting one from an ordering perspective on x86. 115 116define void @store_float_seq_cst(float* %fptr, float %v) { 117; CHECK-LABEL: store_float_seq_cst: 118; CHECK: # %bb.0: 119; CHECK-NEXT: movd %xmm0, %eax 120; CHECK-NEXT: xchgl %eax, (%rdi) 121; CHECK-NEXT: retq 122 store atomic float %v, float* %fptr seq_cst, align 4 123 ret void 124} 125 126define void @store_double_seq_cst(double* %fptr, double %v) { 127; CHECK-LABEL: store_double_seq_cst: 128; CHECK: # %bb.0: 129; CHECK-NEXT: movq %xmm0, %rax 130; CHECK-NEXT: xchgq %rax, (%rdi) 131; CHECK-NEXT: retq 132 store atomic double %v, double* %fptr seq_cst, align 8 133 ret void 134} 135 136define float @load_float_seq_cst(float* %fptr) { 137; CHECK-LABEL: load_float_seq_cst: 138; CHECK: # %bb.0: 139; CHECK-NEXT: movl (%rdi), %eax 140; CHECK-NEXT: movd %eax, %xmm0 141; CHECK-NEXT: retq 142 %v = load atomic float, float* %fptr seq_cst, align 4 143 ret float %v 144} 145 146define double @load_double_seq_cst(double* %fptr) { 147; CHECK-LABEL: load_double_seq_cst: 148; CHECK: # %bb.0: 149; CHECK-NEXT: movq (%rdi), %rax 150; CHECK-NEXT: movq %rax, %xmm0 151; CHECK-NEXT: retq 152 %v = load atomic double, double* %fptr seq_cst, align 8 153 ret double %v 154} 155