blob: a7393fea73d25c5de606bbc1038ba57af630a283 [file] [log] [blame]
Richard Sandifordb86a8342013-06-27 09:27:40 +00001; Test 64-bit conditional stores that are presented as selects.
2;
Richard Sandiforda68e6f52013-07-25 08:57:02 +00003; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
Richard Sandifordb86a8342013-06-27 09:27:40 +00004
5declare void @foo(i64 *)
6
7; Test with the loaded value first.
8define void @f1(i64 *%ptr, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +00009; CHECK-LABEL: f1:
Richard Sandifordb86a8342013-06-27 09:27:40 +000010; CHECK-NOT: %r2
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000011; CHECK: blr %r14
Richard Sandifordb86a8342013-06-27 09:27:40 +000012; CHECK-NOT: %r2
13; CHECK: stg %r3, 0(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +000014; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +000015 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000016 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +000017 %res = select i1 %cond, i64 %orig, i64 %alt
18 store i64 %res, i64 *%ptr
19 ret void
20}
21
22; ...and with the loaded value second
23define void @f2(i64 *%ptr, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000024; CHECK-LABEL: f2:
Richard Sandifordb86a8342013-06-27 09:27:40 +000025; CHECK-NOT: %r2
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000026; CHECK: bher %r14
Richard Sandifordb86a8342013-06-27 09:27:40 +000027; CHECK-NOT: %r2
28; CHECK: stg %r3, 0(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +000029; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +000030 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000031 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +000032 %res = select i1 %cond, i64 %alt, i64 %orig
33 store i64 %res, i64 *%ptr
34 ret void
35}
36
37; Check the high end of the aligned STG range.
38define void @f3(i64 *%base, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000039; CHECK-LABEL: f3:
Richard Sandifordb86a8342013-06-27 09:27:40 +000040; CHECK-NOT: %r2
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000041; CHECK: blr %r14
Richard Sandifordb86a8342013-06-27 09:27:40 +000042; CHECK-NOT: %r2
43; CHECK: stg %r3, 524280(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +000044; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000045 %ptr = getelementptr i64, i64 *%base, i64 65535
Richard Sandiford93183ee2013-09-18 09:56:40 +000046 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000047 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +000048 %res = select i1 %cond, i64 %orig, i64 %alt
49 store i64 %res, i64 *%ptr
50 ret void
51}
52
53; Check the next doubleword up, which needs separate address logic.
54; Other sequences besides this one would be OK.
55define void @f4(i64 *%base, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000056; CHECK-LABEL: f4:
Richard Sandifordb86a8342013-06-27 09:27:40 +000057; CHECK-NOT: %r2
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000058; CHECK: blr %r14
Richard Sandifordb86a8342013-06-27 09:27:40 +000059; CHECK-NOT: %r2
60; CHECK: agfi %r2, 524288
61; CHECK: stg %r3, 0(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +000062; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000063 %ptr = getelementptr i64, i64 *%base, i64 65536
Richard Sandiford93183ee2013-09-18 09:56:40 +000064 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000065 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +000066 %res = select i1 %cond, i64 %orig, i64 %alt
67 store i64 %res, i64 *%ptr
68 ret void
69}
70
71; Check the low end of the STG range.
72define void @f5(i64 *%base, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000073; CHECK-LABEL: f5:
Richard Sandifordb86a8342013-06-27 09:27:40 +000074; CHECK-NOT: %r2
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000075; CHECK: blr %r14
Richard Sandifordb86a8342013-06-27 09:27:40 +000076; CHECK-NOT: %r2
77; CHECK: stg %r3, -524288(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +000078; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000079 %ptr = getelementptr i64, i64 *%base, i64 -65536
Richard Sandiford93183ee2013-09-18 09:56:40 +000080 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000081 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +000082 %res = select i1 %cond, i64 %orig, i64 %alt
83 store i64 %res, i64 *%ptr
84 ret void
85}
86
87; Check the next doubleword down, which needs separate address logic.
88; Other sequences besides this one would be OK.
89define void @f6(i64 *%base, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000090; CHECK-LABEL: f6:
Richard Sandifordb86a8342013-06-27 09:27:40 +000091; CHECK-NOT: %r2
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000092; CHECK: blr %r14
Richard Sandifordb86a8342013-06-27 09:27:40 +000093; CHECK-NOT: %r2
94; CHECK: agfi %r2, -524296
95; CHECK: stg %r3, 0(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +000096; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000097 %ptr = getelementptr i64, i64 *%base, i64 -65537
Richard Sandiford93183ee2013-09-18 09:56:40 +000098 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000099 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +0000100 %res = select i1 %cond, i64 %orig, i64 %alt
101 store i64 %res, i64 *%ptr
102 ret void
103}
104
105; Check that STG allows an index.
106define void @f7(i64 %base, i64 %index, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000107; CHECK-LABEL: f7:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000108; CHECK-NOT: %r2
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000109; CHECK: blr %r14
Richard Sandifordb86a8342013-06-27 09:27:40 +0000110; CHECK-NOT: %r2
111; CHECK: stg %r4, 524287(%r3,%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +0000112; CHECK: br %r14
113 %add1 = add i64 %base, %index
114 %add2 = add i64 %add1, 524287
115 %ptr = inttoptr i64 %add2 to i64 *
Richard Sandiford93183ee2013-09-18 09:56:40 +0000116 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000117 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +0000118 %res = select i1 %cond, i64 %orig, i64 %alt
119 store i64 %res, i64 *%ptr
120 ret void
121}
122
123; Check that volatile loads are not matched.
124define void @f8(i64 *%ptr, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000125; CHECK-LABEL: f8:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000126; CHECK: lg {{%r[0-5]}}, 0(%r2)
Kyle Buttefe56fe2017-01-11 19:55:19 +0000127; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000128; CHECK: [[LABEL]]:
129; CHECK: stg {{%r[0-5]}}, 0(%r2)
130; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000131 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000132 %orig = load volatile i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +0000133 %res = select i1 %cond, i64 %orig, i64 %alt
134 store i64 %res, i64 *%ptr
135 ret void
136}
137
138; ...likewise stores. In this case we should have a conditional load into %r3.
139define void @f9(i64 *%ptr, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000140; CHECK-LABEL: f9:
Richard Sandiford3d768e32013-07-31 12:30:20 +0000141; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000142; CHECK: lg %r3, 0(%r2)
143; CHECK: [[LABEL]]:
144; CHECK: stg %r3, 0(%r2)
145; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000146 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000147 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +0000148 %res = select i1 %cond, i64 %orig, i64 %alt
149 store volatile i64 %res, i64 *%ptr
150 ret void
151}
152
153; Check that atomic loads are not matched. The transformation is OK for
154; the "unordered" case tested here, but since we don't try to handle atomic
155; operations at all in this context, it seems better to assert that than
156; to restrict the test to a stronger ordering.
157define void @f10(i64 *%ptr, i64 %alt, i32 %limit) {
158; FIXME: should use a normal load instead of CSG.
Stephen Lind24ab202013-07-14 06:24:09 +0000159; CHECK-LABEL: f10:
Richard Sandifordbef3d7a2013-12-10 10:49:34 +0000160; CHECK: lg {{%r[0-5]}}, 0(%r2)
Kyle Buttefe56fe2017-01-11 19:55:19 +0000161; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000162; CHECK: [[LABEL]]:
163; CHECK: stg {{%r[0-5]}}, 0(%r2)
164; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000165 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000166 %orig = load atomic i64, i64 *%ptr unordered, align 8
Richard Sandifordb86a8342013-06-27 09:27:40 +0000167 %res = select i1 %cond, i64 %orig, i64 %alt
168 store i64 %res, i64 *%ptr
169 ret void
170}
171
172; ...likewise stores.
173define void @f11(i64 *%ptr, i64 %alt, i32 %limit) {
174; FIXME: should use a normal store instead of CSG.
Stephen Lind24ab202013-07-14 06:24:09 +0000175; CHECK-LABEL: f11:
Richard Sandiford3d768e32013-07-31 12:30:20 +0000176; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000177; CHECK: lg %r3, 0(%r2)
178; CHECK: [[LABEL]]:
Richard Sandifordbef3d7a2013-12-10 10:49:34 +0000179; CHECK: stg %r3, 0(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +0000180; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000181 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000182 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +0000183 %res = select i1 %cond, i64 %orig, i64 %alt
184 store atomic i64 %res, i64 *%ptr unordered, align 8
185 ret void
186}
187
188; Try a frame index base.
189define void @f12(i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000190; CHECK-LABEL: f12:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000191; CHECK: brasl %r14, foo@PLT
192; CHECK-NOT: %r15
193; CHECK: jl [[LABEL:[^ ]*]]
194; CHECK-NOT: %r15
195; CHECK: stg {{%r[0-9]+}}, {{[0-9]+}}(%r15)
196; CHECK: [[LABEL]]:
197; CHECK: brasl %r14, foo@PLT
198; CHECK: br %r14
199 %ptr = alloca i64
200 call void @foo(i64 *%ptr)
Richard Sandiford93183ee2013-09-18 09:56:40 +0000201 %cond = icmp ult i32 %limit, 420
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000202 %orig = load i64, i64 *%ptr
Richard Sandifordb86a8342013-06-27 09:27:40 +0000203 %res = select i1 %cond, i64 %orig, i64 %alt
204 store i64 %res, i64 *%ptr
205 call void @foo(i64 *%ptr)
206 ret void
207}