Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -mtriple=x86_64 -o - %s | FileCheck %s
      2 
      3 define i1 @try_cmpxchg(i32* %addr, i32 %desired, i32 %new) {
      4 ; CHECK-LABEL: try_cmpxchg:
      5 ; CHECK: cmpxchgl
      6 ; CHECK-NOT: cmp
      7 ; CHECK: sete %al
      8 ; CHECK: retq
      9   %pair = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
     10   %success = extractvalue { i32, i1 } %pair, 1
     11   ret i1 %success
     12 }
     13 
     14 define void @cmpxchg_flow(i64* %addr, i64 %desired, i64 %new) {
     15 ; CHECK-LABEL: cmpxchg_flow:
     16 ; CHECK: cmpxchgq
     17 ; CHECK-NOT: cmp
     18 ; CHECK-NOT: set
     19 ; CHECK: {{jne|jeq}}
     20   %pair = cmpxchg i64* %addr, i64 %desired, i64 %new seq_cst seq_cst
     21   %success = extractvalue { i64, 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 define i64 @cmpxchg_sext(i32* %addr, i32 %desired, i32 %new) {
     34 ; CHECK-LABEL: cmpxchg_sext:
     35 ; CHECK-DAG: cmpxchgl
     36 ; CHECK-NOT: cmpl
     37 ; CHECK: sete %al
     38 ; CHECK: retq
     39   %pair = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
     40   %success = extractvalue { i32, i1 } %pair, 1
     41   %mask = sext i1 %success to i64
     42   ret i64 %mask
     43 }
     44 
     45 define i32 @cmpxchg_zext(i32* %addr, i32 %desired, i32 %new) {
     46 ; CHECK-LABEL: cmpxchg_zext:
     47 ; CHECK: cmpxchgl
     48 ; CHECK-NOT: cmp
     49 ; CHECK: sete [[BYTE:%[a-z0-9]+]]
     50 ; CHECK: movzbl [[BYTE]], %eax
     51   %pair = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
     52   %success = extractvalue { i32, i1 } %pair, 1
     53   %mask = zext i1 %success to i32
     54   ret i32 %mask
     55 }
     56 
     57 
     58 define i32 @cmpxchg_use_eflags_and_val(i32* %addr, i32 %offset) {
     59 ; CHECK-LABEL: cmpxchg_use_eflags_and_val:
     60 ; CHECK: movl (%rdi), %e[[OLDVAL:[a-z0-9]+]]
     61 
     62 ; CHECK: [[LOOPBB:.?LBB[0-9]+_[0-9]+]]:
     63 ; CHECK: leal (%r[[OLDVAL]],%rsi), [[NEW:%[a-z0-9]+]]
     64 ; CHECK: cmpxchgl [[NEW]], (%rdi)
     65 ; CHECK-NOT: cmpl
     66 ; CHECK: jne [[LOOPBB]]
     67 
     68   ; Result already in %eax
     69 ; CHECK: retq
     70 entry:
     71   %init = load atomic i32* %addr seq_cst, align 4
     72   br label %loop
     73 
     74 loop:
     75   %old = phi i32 [%init, %entry], [%oldval, %loop]
     76   %new = add i32 %old, %offset
     77   %pair = cmpxchg i32* %addr, i32 %old, i32 %new seq_cst seq_cst
     78   %oldval = extractvalue { i32, i1 } %pair, 0
     79   %success = extractvalue { i32, i1 } %pair, 1
     80   br i1 %success, label %done, label %loop
     81 
     82 done:
     83   ret i32 %oldval
     84 }
     85 
     86 declare void @foo()
     87 declare void @bar()
     88