CodeGen peephole: fold redundant phys reg copies
[oota-llvm.git] / test / CodeGen / X86 / cmpxchg-i1.ll
index 53cf3e300fdb1dba5641b2bc15ec24c4c0745d99..5f5869f78bba598768190eda6304f2b064571b78 100644 (file)
@@ -6,8 +6,8 @@ define i1 @try_cmpxchg(i32* %addr, i32 %desired, i32 %new) {
 ; CHECK-NOT: cmp
 ; CHECK: sete %al
 ; CHECK: retq
-  %old = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
-  %success = icmp eq i32 %old, %desired
+  %pair = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
+  %success = extractvalue { i32, i1 } %pair, 1
   ret i1 %success
 }
 
@@ -17,8 +17,8 @@ define void @cmpxchg_flow(i64* %addr, i64 %desired, i64 %new) {
 ; CHECK-NOT: cmp
 ; CHECK-NOT: set
 ; CHECK: {{jne|jeq}}
-  %old = cmpxchg i64* %addr, i64 %desired, i64 %new seq_cst seq_cst
-  %success = icmp eq i64 %old, %desired
+  %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:
@@ -30,38 +30,14 @@ false:
   ret void
 }
 
-define i1 @cmpxchg_arithcmp(i16* %addr, i16 %desired, i16 %new) {
-; CHECK-LABEL: cmpxchg_arithcmp:
-; CHECK: cmpxchgw
-; CHECK-NOT: cmp
-; CHECK: setbe %al
-; CHECK: retq
-  %old = cmpxchg i16* %addr, i16 %desired, i16 %new seq_cst seq_cst
-  %success = icmp uge i16 %old, %desired
-  ret i1 %success
-}
-
-define i1 @cmpxchg_arithcmp_swapped(i8* %addr, i8 %desired, i8 %new) {
-; CHECK-LABEL: cmpxchg_arithcmp_swapped:
-; CHECK: cmpxchgb
-; CHECK-NOT: cmp
-; CHECK: setge %al
-; CHECK: retq
-  %old = cmpxchg i8* %addr, i8 %desired, i8 %new seq_cst seq_cst
-  %success = icmp sge i8 %desired, %old
-  ret i1 %success
-}
-
 define i64 @cmpxchg_sext(i32* %addr, i32 %desired, i32 %new) {
 ; CHECK-LABEL: cmpxchg_sext:
 ; CHECK-DAG: cmpxchgl
-; CHECK-DAG: movq $-1, %rax
-; CHECK-DAG: xorl %e[[ZERO:[a-z0-9]+]], %e[[ZERO]]
 ; CHECK-NOT: cmpl
-; CHECK: cmovneq %r[[ZERO]], %rax
+; CHECK: sete %al
 ; CHECK: retq
-  %old = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
-  %success = icmp eq i32 %old, %desired
+  %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
 }
@@ -72,11 +48,40 @@ define i32 @cmpxchg_zext(i32* %addr, i32 %desired, i32 %new) {
 ; CHECK-NOT: cmp
 ; CHECK: sete [[BYTE:%[a-z0-9]+]]
 ; CHECK: movzbl [[BYTE]], %eax
-  %old = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
-  %success = icmp eq i32 %old, %desired
+  %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, 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()