Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / AtomicExpand / ARM / cmpxchg-weak.ll
blob8195a5b6145e3af4d17b1bac861cdb8b58e65fa0
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -passes=atomic-expand -codegen-opt-level=1 -S -mtriple=thumbv7s-apple-ios7.0 %s | FileCheck %s
4 ; Intrinsic for "dmb ishst" is then expected
5 define i32 @test_cmpxchg_seq_cst(ptr %addr, i32 %desired, i32 %new) {
6 ; CHECK-LABEL: define i32 @test_cmpxchg_seq_cst(
7 ; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) {
8 ; CHECK-NEXT:    br label %[[CMPXCHG_START:.*]]
9 ; CHECK:       [[CMPXCHG_START]]:
10 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]])
11 ; CHECK-NEXT:    [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]]
12 ; CHECK-NEXT:    br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]]
13 ; CHECK:       [[CMPXCHG_FENCEDSTORE]]:
14 ; CHECK-NEXT:    call void @llvm.arm.dmb(i32 10)
15 ; CHECK-NEXT:    br label %[[CMPXCHG_TRYSTORE:.*]]
16 ; CHECK:       [[CMPXCHG_TRYSTORE]]:
17 ; CHECK-NEXT:    [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ]
18 ; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]])
19 ; CHECK-NEXT:    [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0
20 ; CHECK-NEXT:    br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]]
21 ; CHECK:       [[CMPXCHG_RELEASEDLOAD:.*:]]
22 ; CHECK-NEXT:    unreachable
23 ; CHECK:       [[CMPXCHG_SUCCESS]]:
24 ; CHECK-NEXT:    call void @llvm.arm.dmb(i32 11)
25 ; CHECK-NEXT:    br label %[[CMPXCHG_END:.*]]
26 ; CHECK:       [[CMPXCHG_NOSTORE]]:
27 ; CHECK-NEXT:    [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ]
28 ; CHECK-NEXT:    call void @llvm.arm.clrex()
29 ; CHECK-NEXT:    br label %[[CMPXCHG_FAILURE]]
30 ; CHECK:       [[CMPXCHG_FAILURE]]:
31 ; CHECK-NEXT:    [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ]
32 ; CHECK-NEXT:    call void @llvm.arm.dmb(i32 11)
33 ; CHECK-NEXT:    br label %[[CMPXCHG_END]]
34 ; CHECK:       [[CMPXCHG_END]]:
35 ; CHECK-NEXT:    [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ]
36 ; CHECK-NEXT:    [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ]
37 ; CHECK-NEXT:    ret i32 [[LOADED_EXIT]]
39   %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst seq_cst
40   %oldval = extractvalue { i32, i1 } %pair, 0
41   ret i32 %oldval
44 define i1 @test_cmpxchg_weak_fail(ptr %addr, i32 %desired, i32 %new) {
45 ; CHECK-LABEL: define i1 @test_cmpxchg_weak_fail(
46 ; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) {
47 ; CHECK-NEXT:    br label %[[CMPXCHG_START:.*]]
48 ; CHECK:       [[CMPXCHG_START]]:
49 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]])
50 ; CHECK-NEXT:    [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]]
51 ; CHECK-NEXT:    br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]]
52 ; CHECK:       [[CMPXCHG_FENCEDSTORE]]:
53 ; CHECK-NEXT:    call void @llvm.arm.dmb(i32 10)
54 ; CHECK-NEXT:    br label %[[CMPXCHG_TRYSTORE:.*]]
55 ; CHECK:       [[CMPXCHG_TRYSTORE]]:
56 ; CHECK-NEXT:    [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ]
57 ; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]])
58 ; CHECK-NEXT:    [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0
59 ; CHECK-NEXT:    br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]]
60 ; CHECK:       [[CMPXCHG_RELEASEDLOAD:.*:]]
61 ; CHECK-NEXT:    unreachable
62 ; CHECK:       [[CMPXCHG_SUCCESS]]:
63 ; CHECK-NEXT:    call void @llvm.arm.dmb(i32 11)
64 ; CHECK-NEXT:    br label %[[CMPXCHG_END:.*]]
65 ; CHECK:       [[CMPXCHG_NOSTORE]]:
66 ; CHECK-NEXT:    [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ]
67 ; CHECK-NEXT:    call void @llvm.arm.clrex()
68 ; CHECK-NEXT:    br label %[[CMPXCHG_FAILURE]]
69 ; CHECK:       [[CMPXCHG_FAILURE]]:
70 ; CHECK-NEXT:    [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ]
71 ; CHECK-NEXT:    br label %[[CMPXCHG_END]]
72 ; CHECK:       [[CMPXCHG_END]]:
73 ; CHECK-NEXT:    [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ]
74 ; CHECK-NEXT:    [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ]
75 ; CHECK-NEXT:    ret i1 [[SUCCESS1]]
77   %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst monotonic
78   %oldval = extractvalue { i32, i1 } %pair, 1
79   ret i1 %oldval
82 define i32 @test_cmpxchg_monotonic(ptr %addr, i32 %desired, i32 %new) {
83 ; CHECK-LABEL: define i32 @test_cmpxchg_monotonic(
84 ; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) {
85 ; CHECK-NEXT:    br label %[[CMPXCHG_START:.*]]
86 ; CHECK:       [[CMPXCHG_START]]:
87 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]])
88 ; CHECK-NEXT:    [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]]
89 ; CHECK-NEXT:    br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]]
90 ; CHECK:       [[CMPXCHG_FENCEDSTORE]]:
91 ; CHECK-NEXT:    br label %[[CMPXCHG_TRYSTORE:.*]]
92 ; CHECK:       [[CMPXCHG_TRYSTORE]]:
93 ; CHECK-NEXT:    [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ]
94 ; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]])
95 ; CHECK-NEXT:    [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0
96 ; CHECK-NEXT:    br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]]
97 ; CHECK:       [[CMPXCHG_RELEASEDLOAD:.*:]]
98 ; CHECK-NEXT:    unreachable
99 ; CHECK:       [[CMPXCHG_SUCCESS]]:
100 ; CHECK-NEXT:    br label %[[CMPXCHG_END:.*]]
101 ; CHECK:       [[CMPXCHG_NOSTORE]]:
102 ; CHECK-NEXT:    [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ]
103 ; CHECK-NEXT:    call void @llvm.arm.clrex()
104 ; CHECK-NEXT:    br label %[[CMPXCHG_FAILURE]]
105 ; CHECK:       [[CMPXCHG_FAILURE]]:
106 ; CHECK-NEXT:    [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ]
107 ; CHECK-NEXT:    br label %[[CMPXCHG_END]]
108 ; CHECK:       [[CMPXCHG_END]]:
109 ; CHECK-NEXT:    [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ]
110 ; CHECK-NEXT:    [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ]
111 ; CHECK-NEXT:    ret i32 [[LOADED_EXIT]]
113   %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new monotonic monotonic
114   %oldval = extractvalue { i32, i1 } %pair, 0
115   ret i32 %oldval
118 define i32 @test_cmpxchg_seq_cst_minsize(ptr %addr, i32 %desired, i32 %new) minsize {
119 ; CHECK-LABEL: define i32 @test_cmpxchg_seq_cst_minsize(
120 ; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) #[[ATTR0:[0-9]+]] {
121 ; CHECK-NEXT:    br label %[[CMPXCHG_START:.*]]
122 ; CHECK:       [[CMPXCHG_START]]:
123 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]])
124 ; CHECK-NEXT:    [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]]
125 ; CHECK-NEXT:    br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]]
126 ; CHECK:       [[CMPXCHG_FENCEDSTORE]]:
127 ; CHECK-NEXT:    call void @llvm.arm.dmb(i32 10)
128 ; CHECK-NEXT:    br label %[[CMPXCHG_TRYSTORE:.*]]
129 ; CHECK:       [[CMPXCHG_TRYSTORE]]:
130 ; CHECK-NEXT:    [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ]
131 ; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]])
132 ; CHECK-NEXT:    [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0
133 ; CHECK-NEXT:    br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]]
134 ; CHECK:       [[CMPXCHG_RELEASEDLOAD:.*:]]
135 ; CHECK-NEXT:    unreachable
136 ; CHECK:       [[CMPXCHG_SUCCESS]]:
137 ; CHECK-NEXT:    call void @llvm.arm.dmb(i32 11)
138 ; CHECK-NEXT:    br label %[[CMPXCHG_END:.*]]
139 ; CHECK:       [[CMPXCHG_NOSTORE]]:
140 ; CHECK-NEXT:    [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ]
141 ; CHECK-NEXT:    call void @llvm.arm.clrex()
142 ; CHECK-NEXT:    br label %[[CMPXCHG_FAILURE]]
143 ; CHECK:       [[CMPXCHG_FAILURE]]:
144 ; CHECK-NEXT:    [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ]
145 ; CHECK-NEXT:    call void @llvm.arm.dmb(i32 11)
146 ; CHECK-NEXT:    br label %[[CMPXCHG_END]]
147 ; CHECK:       [[CMPXCHG_END]]:
148 ; CHECK-NEXT:    [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ]
149 ; CHECK-NEXT:    [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ]
150 ; CHECK-NEXT:    ret i32 [[LOADED_EXIT]]
152   %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst seq_cst
153   %oldval = extractvalue { i32, i1 } %pair, 0
154   ret i32 %oldval