Home | History | Annotate | Download | only in ARM
      1 ; RUN: opt -atomic-expand -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:     call void @llvm.arm.dmb(i32 10)
      7 ; CHECK:     br label %[[START:.*]]
      8 
      9 ; CHECK: [[START]]:
     10 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
     11 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
     12 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
     13 
     14 ; CHECK: [[TRY_STORE]]:
     15 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
     16 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
     17 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
     18 
     19 ; CHECK: [[SUCCESS_BB]]:
     20 ; CHECK:     call void @llvm.arm.dmb(i32 11)
     21 ; CHECK:     br label %[[END:.*]]
     22 
     23 ; CHECK: [[NO_STORE_BB]]:
     24 ; CHECK:     call void @llvm.arm.clrex()
     25 ; CHECK:     br label %[[FAILURE_BB]]
     26 
     27 ; CHECK: [[FAILURE_BB]]:
     28 ; CHECK:     call void @llvm.arm.dmb(i32 11)
     29 ; CHECK:     br label %[[END]]
     30 
     31 ; CHECK: [[END]]:
     32 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
     33 ; CHECK:     ret i32 [[LOADED]]
     34 
     35   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
     36   %oldval = extractvalue { i32, i1 } %pair, 0
     37   ret i32 %oldval
     38 }
     39 
     40 define i1 @test_cmpxchg_weak_fail(i32* %addr, i32 %desired, i32 %new) {
     41 ; CHECK-LABEL: @test_cmpxchg_weak_fail
     42 ; CHECK:     call void @llvm.arm.dmb(i32 10)
     43 ; CHECK:     br label %[[START:.*]]
     44 
     45 ; CHECK: [[START]]:
     46 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
     47 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
     48 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
     49 
     50 ; CHECK: [[TRY_STORE]]:
     51 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
     52 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
     53 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
     54 
     55 ; CHECK: [[SUCCESS_BB]]:
     56 ; CHECK:     call void @llvm.arm.dmb(i32 11)
     57 ; CHECK:     br label %[[END:.*]]
     58 
     59 ; CHECK: [[NO_STORE_BB]]:
     60 ; CHECK:     call void @llvm.arm.clrex()
     61 ; CHECK:     br label %[[FAILURE_BB]]
     62 
     63 ; CHECK: [[FAILURE_BB]]:
     64 ; CHECK-NOT: dmb
     65 ; CHECK:     br label %[[END]]
     66 
     67 ; CHECK: [[END]]:
     68 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
     69 ; CHECK:     ret i1 [[SUCCESS]]
     70 
     71   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst monotonic
     72   %oldval = extractvalue { i32, i1 } %pair, 1
     73   ret i1 %oldval
     74 }
     75 
     76 define i32 @test_cmpxchg_monotonic(i32* %addr, i32 %desired, i32 %new) {
     77 ; CHECK-LABEL: @test_cmpxchg_monotonic
     78 ; CHECK-NOT: dmb
     79 ; CHECK:     br label %[[START:.*]]
     80 
     81 ; CHECK: [[START]]:
     82 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
     83 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
     84 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
     85 
     86 ; CHECK: [[TRY_STORE]]:
     87 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
     88 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
     89 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
     90 
     91 ; CHECK: [[SUCCESS_BB]]:
     92 ; CHECK-NOT: dmb
     93 ; CHECK:     br label %[[END:.*]]
     94 
     95 ; CHECK: [[NO_STORE_BB]]:
     96 ; CHECK:     call void @llvm.arm.clrex()
     97 ; CHECK:     br label %[[FAILURE_BB]]
     98 
     99 ; CHECK: [[FAILURE_BB]]:
    100 ; CHECK-NOT: dmb
    101 ; CHECK:     br label %[[END]]
    102 
    103 ; CHECK: [[END]]:
    104 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
    105 ; CHECK:     ret i32 [[LOADED]]
    106 
    107   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new monotonic monotonic
    108   %oldval = extractvalue { i32, i1 } %pair, 0
    109   ret i32 %oldval
    110 }
    111