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