1; RUN: llc -mcpu=core-avx2 -mtriple=x86_64 -o - %s | FileCheck %s 2 3define 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 14define 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 24true: 25 call void @foo() 26 ret void 27 28false: 29 call void @bar() 30 ret void 31} 32 33; Can't use the flags here because cmpxchg16b only sets ZF. 34define 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 45define i128 @cmpxchg_zext(i128* %addr, i128 %desired, i128 %new) { 46; CHECK-LABEL: cmpxchg_zext: 47; CHECK: xorl 48; CHECK: cmpxchg16b 49; CHECK-NOT: cmpq 50; CHECK: sete 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 58define 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 64entry: 65 %init = load atomic i128, i128* %addr seq_cst, align 16 66 br label %loop 67 68loop: 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 78done: 79 ret i128 %old 80} 81 82declare void @foo() 83declare void @bar() 84