diff options
Diffstat (limited to 'test/CodeGen/X86/cmpxchg-i1.ll')
-rw-r--r-- | test/CodeGen/X86/cmpxchg-i1.ll | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/test/CodeGen/X86/cmpxchg-i1.ll b/test/CodeGen/X86/cmpxchg-i1.ll new file mode 100644 index 0000000..a21ab59 --- /dev/null +++ b/test/CodeGen/X86/cmpxchg-i1.ll @@ -0,0 +1,87 @@ +; RUN: llc -mtriple=x86_64 -o - %s | FileCheck %s + +define i1 @try_cmpxchg(i32* %addr, i32 %desired, i32 %new) { +; CHECK-LABEL: try_cmpxchg: +; CHECK: cmpxchgl +; CHECK-NOT: cmp +; CHECK: sete %al +; CHECK: retq + %pair = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst + %success = extractvalue { i32, i1 } %pair, 1 + ret i1 %success +} + +define void @cmpxchg_flow(i64* %addr, i64 %desired, i64 %new) { +; CHECK-LABEL: cmpxchg_flow: +; CHECK: cmpxchgq +; CHECK-NOT: cmp +; CHECK-NOT: set +; CHECK: {{jne|jeq}} + %pair = cmpxchg i64* %addr, i64 %desired, i64 %new seq_cst seq_cst + %success = extractvalue { i64, i1 } %pair, 1 + br i1 %success, label %true, label %false + +true: + call void @foo() + ret void + +false: + call void @bar() + ret void +} + +define i64 @cmpxchg_sext(i32* %addr, i32 %desired, i32 %new) { +; CHECK-LABEL: cmpxchg_sext: +; CHECK-DAG: cmpxchgl +; CHECK-NOT: cmpl +; CHECK: sete %al +; CHECK: retq + %pair = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst + %success = extractvalue { i32, i1 } %pair, 1 + %mask = sext i1 %success to i64 + ret i64 %mask +} + +define i32 @cmpxchg_zext(i32* %addr, i32 %desired, i32 %new) { +; CHECK-LABEL: cmpxchg_zext: +; CHECK: cmpxchgl +; CHECK-NOT: cmp +; CHECK: sete [[BYTE:%[a-z0-9]+]] +; CHECK: movzbl [[BYTE]], %eax + %pair = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst + %success = extractvalue { i32, i1 } %pair, 1 + %mask = zext i1 %success to i32 + ret i32 %mask +} + + +define i32 @cmpxchg_use_eflags_and_val(i32* %addr, i32 %offset) { +; CHECK-LABEL: cmpxchg_use_eflags_and_val: +; CHECK: movl (%rdi), %e[[OLDVAL:[a-z0-9]+]] + +; CHECK: [[LOOPBB:.?LBB[0-9]+_[0-9]+]]: +; CHECK: leal (%r[[OLDVAL]],%rsi), [[NEW:%[a-z0-9]+]] +; CHECK: cmpxchgl [[NEW]], (%rdi) +; CHECK-NOT: cmpl +; CHECK: jne [[LOOPBB]] + + ; Result already in %eax +; CHECK: retq +entry: + %init = load atomic i32* %addr seq_cst, align 4 + br label %loop + +loop: + %old = phi i32 [%init, %entry], [%oldval, %loop] + %new = add i32 %old, %offset + %pair = cmpxchg i32* %addr, i32 %old, i32 %new seq_cst seq_cst + %oldval = extractvalue { i32, i1 } %pair, 0 + %success = extractvalue { i32, i1 } %pair, 1 + br i1 %success, label %done, label %loop + +done: + ret i32 %oldval +} + +declare void @foo() +declare void @bar() |