1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=core-avx2 | FileCheck %s 3 4define i1 @try_cmpxchg(i128* %addr, i128 %desired, i128 %new) { 5; CHECK-LABEL: try_cmpxchg: 6; CHECK: # %bb.0: 7; CHECK-NEXT: pushq %rbx 8; CHECK-NEXT: .cfi_def_cfa_offset 16 9; CHECK-NEXT: .cfi_offset %rbx, -16 10; CHECK-NEXT: movq %rcx, %rbx 11; CHECK-NEXT: movq %rsi, %rax 12; CHECK-NEXT: movq %r8, %rcx 13; CHECK-NEXT: lock cmpxchg16b (%rdi) 14; CHECK-NEXT: sete %al 15; CHECK-NEXT: popq %rbx 16; CHECK-NEXT: .cfi_def_cfa_offset 8 17; CHECK-NEXT: retq 18 %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst 19 %success = extractvalue { i128, i1 } %pair, 1 20 ret i1 %success 21} 22 23define void @cmpxchg_flow(i128* %addr, i128 %desired, i128 %new) { 24; CHECK-LABEL: cmpxchg_flow: 25; CHECK: # %bb.0: 26; CHECK-NEXT: pushq %rbx 27; CHECK-NEXT: .cfi_def_cfa_offset 16 28; CHECK-NEXT: .cfi_offset %rbx, -16 29; CHECK-NEXT: movq %rcx, %rbx 30; CHECK-NEXT: movq %rsi, %rax 31; CHECK-NEXT: movq %r8, %rcx 32; CHECK-NEXT: lock cmpxchg16b (%rdi) 33; CHECK-NEXT: jne .LBB1_2 34; CHECK-NEXT: # %bb.1: # %true 35; CHECK-NEXT: callq foo 36; CHECK-NEXT: popq %rbx 37; CHECK-NEXT: .cfi_def_cfa_offset 8 38; CHECK-NEXT: retq 39; CHECK-NEXT: .LBB1_2: # %false 40; CHECK-NEXT: .cfi_def_cfa_offset 16 41; CHECK-NEXT: callq bar 42; CHECK-NEXT: popq %rbx 43; CHECK-NEXT: .cfi_def_cfa_offset 8 44; CHECK-NEXT: retq 45 %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst 46 %success = extractvalue { i128, i1 } %pair, 1 47 br i1 %success, label %true, label %false 48 49true: 50 call void @foo() 51 ret void 52 53false: 54 call void @bar() 55 ret void 56} 57 58; Can't use the flags here because cmpxchg16b only sets ZF. 59define i1 @cmpxchg_arithcmp(i128* %addr, i128 %desired, i128 %new) { 60; CHECK-LABEL: cmpxchg_arithcmp: 61; CHECK: # %bb.0: 62; CHECK-NEXT: pushq %rbx 63; CHECK-NEXT: .cfi_def_cfa_offset 16 64; CHECK-NEXT: .cfi_offset %rbx, -16 65; CHECK-NEXT: movq %rcx, %rbx 66; CHECK-NEXT: movq %rdx, %r9 67; CHECK-NEXT: movq %rsi, %rax 68; CHECK-NEXT: movq %r8, %rcx 69; CHECK-NEXT: lock cmpxchg16b (%rdi) 70; CHECK-NEXT: cmpq %rsi, %rax 71; CHECK-NEXT: sbbq %r9, %rdx 72; CHECK-NEXT: setge %al 73; CHECK-NEXT: popq %rbx 74; CHECK-NEXT: .cfi_def_cfa_offset 8 75; CHECK-NEXT: retq 76 %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst 77 %oldval = extractvalue { i128, i1 } %pair, 0 78 %success = icmp sge i128 %oldval, %desired 79 ret i1 %success 80} 81 82define i128 @cmpxchg_zext(i128* %addr, i128 %desired, i128 %new) { 83; CHECK-LABEL: cmpxchg_zext: 84; CHECK: # %bb.0: 85; CHECK-NEXT: pushq %rbx 86; CHECK-NEXT: .cfi_def_cfa_offset 16 87; CHECK-NEXT: .cfi_offset %rbx, -16 88; CHECK-NEXT: movq %rcx, %rbx 89; CHECK-NEXT: movq %rsi, %rax 90; CHECK-NEXT: xorl %esi, %esi 91; CHECK-NEXT: movq %r8, %rcx 92; CHECK-NEXT: lock cmpxchg16b (%rdi) 93; CHECK-NEXT: sete %sil 94; CHECK-NEXT: movq %rsi, %rax 95; CHECK-NEXT: xorl %edx, %edx 96; CHECK-NEXT: popq %rbx 97; CHECK-NEXT: .cfi_def_cfa_offset 8 98; CHECK-NEXT: retq 99 %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst 100 %success = extractvalue { i128, i1 } %pair, 1 101 %mask = zext i1 %success to i128 102 ret i128 %mask 103} 104 105 106define i128 @cmpxchg_use_eflags_and_val(i128* %addr, i128 %offset) { 107; CHECK-LABEL: cmpxchg_use_eflags_and_val: 108; CHECK: # %bb.0: # %entry 109; CHECK-NEXT: pushq %rbx 110; CHECK-NEXT: .cfi_def_cfa_offset 16 111; CHECK-NEXT: .cfi_offset %rbx, -16 112; CHECK-NEXT: movq %rdx, %r8 113; CHECK-NEXT: xorl %eax, %eax 114; CHECK-NEXT: xorl %edx, %edx 115; CHECK-NEXT: xorl %ecx, %ecx 116; CHECK-NEXT: xorl %ebx, %ebx 117; CHECK-NEXT: lock cmpxchg16b (%rdi) 118; CHECK-NEXT: .p2align 4, 0x90 119; CHECK-NEXT: .LBB4_1: # %loop 120; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 121; CHECK-NEXT: movq %rdx, %r9 122; CHECK-NEXT: movq %rax, %r10 123; CHECK-NEXT: movq %rax, %rbx 124; CHECK-NEXT: addq %rsi, %rbx 125; CHECK-NEXT: movq %rdx, %rcx 126; CHECK-NEXT: adcq %r8, %rcx 127; CHECK-NEXT: lock cmpxchg16b (%rdi) 128; CHECK-NEXT: jne .LBB4_1 129; CHECK-NEXT: # %bb.2: # %done 130; CHECK-NEXT: movq %r10, %rax 131; CHECK-NEXT: movq %r9, %rdx 132; CHECK-NEXT: popq %rbx 133; CHECK-NEXT: .cfi_def_cfa_offset 8 134; CHECK-NEXT: retq 135entry: 136 %init = load atomic i128, i128* %addr seq_cst, align 16 137 br label %loop 138 139loop: 140 %old = phi i128 [%init, %entry], [%oldval, %loop] 141 %new = add i128 %old, %offset 142 143 %pair = cmpxchg i128* %addr, i128 %old, i128 %new seq_cst seq_cst 144 %oldval = extractvalue { i128, i1 } %pair, 0 145 %success = extractvalue { i128, i1 } %pair, 1 146 147 br i1 %success, label %done, label %loop 148 149done: 150 ret i128 %old 151} 152 153declare void @foo() 154declare void @bar() 155