Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s | FileCheck %s
      2 
      3 define i32 @test_return(i32* %p, i32 %oldval, i32 %newval) {
      4 ; CHECK-LABEL: test_return:
      5 
      6 ; CHECK: ldrex [[LOADED:r[0-9]+]], [r0]
      7 ; CHECK: cmp [[LOADED]], r1
      8 ; CHECK: bne [[FAILED:LBB[0-9]+_[0-9]+]]
      9 
     10 ; CHECK: dmb ishst
     11 
     12 ; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
     13 ; CHECK: strex [[STATUS:r[0-9]+]], {{r[0-9]+}}, [r0]
     14 ; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
     15 
     16 ; CHECK: ldrex [[LOADED]], [r0]
     17 ; CHECK: cmp [[LOADED]], r1
     18 ; CHECK: beq [[LOOP]]
     19 
     20 ; CHECK: [[FAILED]]:
     21 ; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
     22 ; CHECK: clrex
     23 ; CHECK: dmb ish
     24 ; CHECK: movs r0, #0
     25 ; CHECK: bx lr
     26 
     27 ; CHECK: [[SUCCESS]]:
     28 ; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
     29 ; CHECK: dmb ish
     30 ; CHECK: movs r0, #1
     31 ; CHECK: bx lr
     32 
     33   %pair = cmpxchg i32* %p, i32 %oldval, i32 %newval seq_cst seq_cst
     34   %success = extractvalue { i32, i1 } %pair, 1
     35   %conv = zext i1 %success to i32
     36   ret i32 %conv
     37 }
     38 
     39 define i1 @test_return_bool(i8* %value, i8 %oldValue, i8 %newValue) {
     40 ; CHECK-LABEL: test_return_bool:
     41 
     42 ; CHECK: uxtb [[OLDBYTE:r[0-9]+]], r1
     43 
     44 ; CHECK: ldrexb [[LOADED:r[0-9]+]], [r0]
     45 ; CHECK: cmp [[LOADED]], [[OLDBYTE]]
     46 ; CHECK: bne [[FAIL:LBB[0-9]+_[0-9]+]]
     47 
     48 ; CHECK: dmb ishst
     49 
     50 ; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
     51 ; CHECK: strexb [[STATUS:r[0-9]+]], {{r[0-9]+}}, [r0]
     52 ; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
     53 
     54 ; CHECK: ldrexb [[LOADED]], [r0]
     55 ; CHECK: cmp [[LOADED]], [[OLDBYTE]]
     56 ; CHECK: beq [[LOOP]]
     57 
     58 
     59   ; FIXME: this eor is redundant. Need to teach DAG combine that.
     60 ; CHECK: [[FAIL]]:
     61 ; CHECK: clrex
     62 ; CHECK: movs [[TMP:r[0-9]+]], #0
     63 ; CHECK: eor r0, [[TMP]], #1
     64 ; CHECK: bx lr
     65 
     66 ; CHECK: [[SUCCESS]]:
     67 ; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
     68 ; CHECK: movs [[TMP:r[0-9]+]], #1
     69 ; CHECK: eor r0, [[TMP]], #1
     70 ; CHECK: bx lr
     71 
     72 
     73   %pair = cmpxchg i8* %value, i8 %oldValue, i8 %newValue acq_rel monotonic
     74   %success = extractvalue { i8, i1 } %pair, 1
     75   %failure = xor i1 %success, 1
     76   ret i1 %failure
     77 }
     78 
     79 define void @test_conditional(i32* %p, i32 %oldval, i32 %newval) {
     80 ; CHECK-LABEL: test_conditional:
     81 
     82 ; CHECK: ldrex [[LOADED:r[0-9]+]], [r0]
     83 ; CHECK: cmp [[LOADED]], r1
     84 ; CHECK: bne [[FAILED:LBB[0-9]+_[0-9]+]]
     85 
     86 ; CHECK: dmb ishst
     87 
     88 ; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
     89 ; CHECK: strex [[STATUS:r[0-9]+]], r2, [r0]
     90 ; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
     91 
     92 ; CHECK: ldrex [[LOADED]], [r0]
     93 ; CHECK: cmp [[LOADED]], r1
     94 ; CHECK: beq [[LOOP]]
     95 
     96 ; CHECK: [[FAILED]]:
     97 ; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
     98 ; CHECK: clrex
     99 ; CHECK: dmb ish
    100 ; CHECK: b.w _baz
    101 
    102 ; CHECK: [[SUCCESS]]:
    103 ; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
    104 ; CHECK: dmb ish
    105 ; CHECK: b.w _bar
    106 
    107   %pair = cmpxchg i32* %p, i32 %oldval, i32 %newval seq_cst seq_cst
    108   %success = extractvalue { i32, i1 } %pair, 1
    109   br i1 %success, label %true, label %false
    110 
    111 true:
    112   tail call void @bar() #2
    113   br label %end
    114 
    115 false:
    116   tail call void @baz() #2
    117   br label %end
    118 
    119 end:
    120   ret void
    121 }
    122 
    123 declare void @bar()
    124 declare void @baz()
    125