Home | History | Annotate | Download | only in ARM
      1 ; RUN: opt -atomic-expand -codegen-opt-level=1 -S -mtriple=thumbv7s-apple-ios7.0 %s | FileCheck %s
      2 
      3 define i32 @test_cmpxchg_seq_cst(i32* %addr, i32 %desired, i32 %new) {
      4 ; CHECK-LABEL: @test_cmpxchg_seq_cst
      5 ; Intrinsic for "dmb ishst" is then expected
      6 ; CHECK:     br label %[[START:.*]]
      7 
      8 ; CHECK: [[START]]:
      9 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
     10 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
     11 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
     12 
     13 ; CHECK: [[FENCED_STORE]]:
     14 ; CHECK:     call void @llvm.arm.dmb(i32 10)
     15 ; CHECK:     br label %[[TRY_STORE:.*]]
     16 
     17 ; CHECK: [[TRY_STORE]]:
     18 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
     19 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
     20 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
     21 
     22 ; CHECK: [[SUCCESS_BB]]:
     23 ; CHECK:     call void @llvm.arm.dmb(i32 11)
     24 ; CHECK:     br label %[[END:.*]]
     25 
     26 ; CHECK: [[NO_STORE_BB]]:
     27 ; CHECK:     call void @llvm.arm.clrex()
     28 ; CHECK:     br label %[[FAILURE_BB]]
     29 
     30 ; CHECK: [[FAILURE_BB]]:
     31 ; CHECK:     call void @llvm.arm.dmb(i32 11)
     32 ; CHECK:     br label %[[END]]
     33 
     34 ; CHECK: [[END]]:
     35 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
     36 ; CHECK:     ret i32 [[LOADED]]
     37 
     38   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
     39   %oldval = extractvalue { i32, i1 } %pair, 0
     40   ret i32 %oldval
     41 }
     42 
     43 define i1 @test_cmpxchg_weak_fail(i32* %addr, i32 %desired, i32 %new) {
     44 ; CHECK-LABEL: @test_cmpxchg_weak_fail
     45 ; CHECK:     br label %[[START:.*]]
     46 
     47 ; CHECK: [[START]]:
     48 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
     49 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
     50 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
     51 
     52 ; CHECK: [[FENCED_STORE]]:
     53 ; CHECK:     call void @llvm.arm.dmb(i32 10)
     54 ; CHECK:     br label %[[TRY_STORE:.*]]
     55 
     56 ; CHECK: [[TRY_STORE]]:
     57 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
     58 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
     59 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
     60 
     61 ; CHECK: [[SUCCESS_BB]]:
     62 ; CHECK:     call void @llvm.arm.dmb(i32 11)
     63 ; CHECK:     br label %[[END:.*]]
     64 
     65 ; CHECK: [[NO_STORE_BB]]:
     66 ; CHECK:     call void @llvm.arm.clrex()
     67 ; CHECK:     br label %[[FAILURE_BB]]
     68 
     69 ; CHECK: [[FAILURE_BB]]:
     70 ; CHECK-NOT: dmb
     71 ; CHECK:     br label %[[END]]
     72 
     73 ; CHECK: [[END]]:
     74 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
     75 ; CHECK:     ret i1 [[SUCCESS]]
     76 
     77   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst monotonic
     78   %oldval = extractvalue { i32, i1 } %pair, 1
     79   ret i1 %oldval
     80 }
     81 
     82 define i32 @test_cmpxchg_monotonic(i32* %addr, i32 %desired, i32 %new) {
     83 ; CHECK-LABEL: @test_cmpxchg_monotonic
     84 ; CHECK-NOT: dmb
     85 ; CHECK:     br label %[[START:.*]]
     86 
     87 ; CHECK: [[START]]:
     88 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
     89 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
     90 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
     91 
     92 ; CHECK: [[TRY_STORE]]:
     93 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
     94 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
     95 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
     96 
     97 ; CHECK: [[SUCCESS_BB]]:
     98 ; CHECK-NOT: dmb
     99 ; CHECK:     br label %[[END:.*]]
    100 
    101 ; CHECK: [[NO_STORE_BB]]:
    102 ; CHECK:     call void @llvm.arm.clrex()
    103 ; CHECK:     br label %[[FAILURE_BB]]
    104 
    105 ; CHECK: [[FAILURE_BB]]:
    106 ; CHECK-NOT: dmb
    107 ; CHECK:     br label %[[END]]
    108 
    109 ; CHECK: [[END]]:
    110 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
    111 ; CHECK:     ret i32 [[LOADED]]
    112 
    113   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new monotonic monotonic
    114   %oldval = extractvalue { i32, i1 } %pair, 0
    115   ret i32 %oldval
    116 }
    117 
    118 define i32 @test_cmpxchg_seq_cst_minsize(i32* %addr, i32 %desired, i32 %new) minsize {
    119 ; CHECK-LABEL: @test_cmpxchg_seq_cst_minsize
    120 ; CHECK:     br label %[[START:.*]]
    121 
    122 ; CHECK: [[START]]:
    123 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
    124 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
    125 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
    126 
    127 ; CHECK: [[FENCED_STORE]]:
    128 ; CHECK:     call void @llvm.arm.dmb(i32 10)
    129 ; CHECK:     br label %[[TRY_STORE:.*]]
    130 
    131 ; CHECK: [[TRY_STORE]]:
    132 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
    133 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
    134 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
    135 
    136 ; CHECK: [[SUCCESS_BB]]:
    137 ; CHECK:     call void @llvm.arm.dmb(i32 11)
    138 ; CHECK:     br label %[[END:.*]]
    139 
    140 ; CHECK: [[NO_STORE_BB]]:
    141 ; CHECK:     call void @llvm.arm.clrex()
    142 ; CHECK:     br label %[[FAILURE_BB]]
    143 
    144 ; CHECK: [[FAILURE_BB]]:
    145 ; CHECK:     call void @llvm.arm.dmb(i32 11)
    146 ; CHECK:     br label %[[END]]
    147 
    148 ; CHECK: [[END]]:
    149 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
    150 ; CHECK:     ret i32 [[LOADED]]
    151 
    152   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
    153   %oldval = extractvalue { i32, i1 } %pair, 0
    154   ret i32 %oldval
    155 }
    156