1 ; RUN: llc -mcpu=core-avx2 -mtriple=x86_64 -o - %s | FileCheck %s 2 3 define i1 @try_cmpxchg(i128* %addr, i128 %desired, i128 %new) { 4 ; CHECK-LABEL: try_cmpxchg: 5 ; CHECK: cmpxchg16b 6 ; CHECK-NOT: cmp 7 ; CHECK: sete %al 8 ; CHECK: retq 9 %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst 10 %success = extractvalue { i128, i1 } %pair, 1 11 ret i1 %success 12 } 13 14 define void @cmpxchg_flow(i128* %addr, i128 %desired, i128 %new) { 15 ; CHECK-LABEL: cmpxchg_flow: 16 ; CHECK: cmpxchg16b 17 ; CHECK-NOT: cmp 18 ; CHECK-NOT: set 19 ; CHECK: {{jne|jeq}} 20 %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst 21 %success = extractvalue { i128, i1 } %pair, 1 22 br i1 %success, label %true, label %false 23 24 true: 25 call void @foo() 26 ret void 27 28 false: 29 call void @bar() 30 ret void 31 } 32 33 ; Can't use the flags here because cmpxchg16b only sets ZF. 34 define i1 @cmpxchg_arithcmp(i128* %addr, i128 %desired, i128 %new) { 35 ; CHECK-LABEL: cmpxchg_arithcmp: 36 ; CHECK: cmpxchg16b 37 ; CHECK: cmpq 38 ; CHECK: retq 39 %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst 40 %oldval = extractvalue { i128, i1 } %pair, 0 41 %success = icmp sge i128 %oldval, %desired 42 ret i1 %success 43 } 44 45 define i128 @cmpxchg_zext(i128* %addr, i128 %desired, i128 %new) { 46 ; CHECK-LABEL: cmpxchg_zext: 47 ; CHECK: cmpxchg16b 48 ; CHECK-NOT: cmpq 49 ; CHECK: sete [[BYTE:%[a-z0-9]+]] 50 ; CHECK: movzbl [[BYTE]], %eax 51 %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst 52 %success = extractvalue { i128, i1 } %pair, 1 53 %mask = zext i1 %success to i128 54 ret i128 %mask 55 } 56 57 58 define i128 @cmpxchg_use_eflags_and_val(i128* %addr, i128 %offset) { 59 ; CHECK-LABEL: cmpxchg_use_eflags_and_val: 60 61 ; CHECK: cmpxchg16b 62 ; CHECK-NOT: cmpq 63 ; CHECK: jne 64 entry: 65 %init = load atomic i128* %addr seq_cst, align 16 66 br label %loop 67 68 loop: 69 %old = phi i128 [%init, %entry], [%oldval, %loop] 70 %new = add i128 %old, %offset 71 72 %pair = cmpxchg i128* %addr, i128 %old, i128 %new seq_cst seq_cst 73 %oldval = extractvalue { i128, i1 } %pair, 0 74 %success = extractvalue { i128, i1 } %pair, 1 75 76 br i1 %success, label %done, label %loop 77 78 done: 79 ret i128 %old 80 } 81 82 declare void @foo() 83 declare void @bar() 84