Home | History | Annotate | Download | only in X86
      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