blob: ac1c44ccaeb9daf5ba01b49517816c61d49fc889 [file] [log] [blame]
Richard Sandiford09a8cf32013-07-25 09:04:52 +00001; Test LOCG.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
4
5declare i64 @foo(i64 *)
6
7; Test the simple case.
8define i64 @f1(i64 %easy, i64 *%ptr, i64 %limit) {
9; CHECK-LABEL: f1:
10; CHECK: clgfi %r4, 42
Richard Sandifordee834382013-07-31 12:38:08 +000011; CHECK: locghe %r2, 0(%r3)
Richard Sandiford09a8cf32013-07-25 09:04:52 +000012; CHECK: br %r14
13 %cond = icmp ult i64 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000014 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +000015 %res = select i1 %cond, i64 %easy, i64 %other
16 ret i64 %res
17}
18
19; ...and again with the operands swapped.
20define i64 @f2(i64 %easy, i64 *%ptr, i64 %limit) {
21; CHECK-LABEL: f2:
22; CHECK: clgfi %r4, 42
23; CHECK: locgl %r2, 0(%r3)
24; CHECK: br %r14
25 %cond = icmp ult i64 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000026 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +000027 %res = select i1 %cond, i64 %other, i64 %easy
28 ret i64 %res
29}
30
31; Check the high end of the aligned LOCG range.
32define i64 @f3(i64 %easy, i64 *%base, i64 %limit) {
33; CHECK-LABEL: f3:
34; CHECK: clgfi %r4, 42
Richard Sandifordee834382013-07-31 12:38:08 +000035; CHECK: locghe %r2, 524280(%r3)
Richard Sandiford09a8cf32013-07-25 09:04:52 +000036; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000037 %ptr = getelementptr i64, i64 *%base, i64 65535
Richard Sandiford09a8cf32013-07-25 09:04:52 +000038 %cond = icmp ult i64 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000039 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +000040 %res = select i1 %cond, i64 %easy, i64 %other
41 ret i64 %res
42}
43
44; Check the next doubleword up. Other sequences besides this one would be OK.
45define i64 @f4(i64 %easy, i64 *%base, i64 %limit) {
46; CHECK-LABEL: f4:
47; CHECK: agfi %r3, 524288
48; CHECK: clgfi %r4, 42
Richard Sandifordee834382013-07-31 12:38:08 +000049; CHECK: locghe %r2, 0(%r3)
Richard Sandiford09a8cf32013-07-25 09:04:52 +000050; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000051 %ptr = getelementptr i64, i64 *%base, i64 65536
Richard Sandiford09a8cf32013-07-25 09:04:52 +000052 %cond = icmp ult i64 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000053 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +000054 %res = select i1 %cond, i64 %easy, i64 %other
55 ret i64 %res
56}
57
58; Check the low end of the LOCG range.
59define i64 @f5(i64 %easy, i64 *%base, i64 %limit) {
60; CHECK-LABEL: f5:
61; CHECK: clgfi %r4, 42
Richard Sandifordee834382013-07-31 12:38:08 +000062; CHECK: locghe %r2, -524288(%r3)
Richard Sandiford09a8cf32013-07-25 09:04:52 +000063; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000064 %ptr = getelementptr i64, i64 *%base, i64 -65536
Richard Sandiford09a8cf32013-07-25 09:04:52 +000065 %cond = icmp ult i64 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000066 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +000067 %res = select i1 %cond, i64 %easy, i64 %other
68 ret i64 %res
69}
70
71; Check the next doubleword down, with the same comments as f4.
72define i64 @f6(i64 %easy, i64 *%base, i64 %limit) {
73; CHECK-LABEL: f6:
74; CHECK: agfi %r3, -524296
75; CHECK: clgfi %r4, 42
Richard Sandifordee834382013-07-31 12:38:08 +000076; CHECK: locghe %r2, 0(%r3)
Richard Sandiford09a8cf32013-07-25 09:04:52 +000077; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000078 %ptr = getelementptr i64, i64 *%base, i64 -65537
Richard Sandiford09a8cf32013-07-25 09:04:52 +000079 %cond = icmp ult i64 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000080 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +000081 %res = select i1 %cond, i64 %easy, i64 %other
82 ret i64 %res
83}
84
85; Try a frame index base.
86define i64 @f7(i64 %alt, i64 %limit) {
87; CHECK-LABEL: f7:
88; CHECK: brasl %r14, foo@PLT
Richard Sandifordee834382013-07-31 12:38:08 +000089; CHECK: locghe %r2, {{[0-9]+}}(%r15)
Richard Sandiford09a8cf32013-07-25 09:04:52 +000090; CHECK: br %r14
91 %ptr = alloca i64
92 %easy = call i64 @foo(i64 *%ptr)
93 %cond = icmp ult i64 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000094 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +000095 %res = select i1 %cond, i64 %easy, i64 %other
96 ret i64 %res
97}
98
99; Try a case when an index is involved.
100define i64 @f8(i64 %easy, i64 %limit, i64 %base, i64 %index) {
101; CHECK-LABEL: f8:
102; CHECK: clgfi %r3, 42
Richard Sandifordee834382013-07-31 12:38:08 +0000103; CHECK: locghe %r2, 0({{%r[1-5]}})
Richard Sandiford09a8cf32013-07-25 09:04:52 +0000104; CHECK: br %r14
105 %add = add i64 %base, %index
106 %ptr = inttoptr i64 %add to i64 *
107 %cond = icmp ult i64 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000108 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +0000109 %res = select i1 %cond, i64 %easy, i64 %other
110 ret i64 %res
111}
112
113; Test that conditionally-executed loads do not use LOCG, since it is allowed
114; to trap even when the condition is false.
115define i64 @f9(i64 %easy, i64 %limit, i64 *%ptr) {
116; CHECK-LABEL: f9:
117; CHECK-NOT: locg
118; CHECK: br %r14
119entry:
120 %cmp = icmp ule i64 %easy, %limit
121 br i1 %cmp, label %load, label %exit
122
123load:
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000124 %other = load i64, i64 *%ptr
Richard Sandiford09a8cf32013-07-25 09:04:52 +0000125 br label %exit
126
127exit:
128 %res = phi i64 [ %easy, %entry ], [ %other, %load ]
129 ret i64 %res
130}
Ulrich Weigand7bdb4852016-10-25 15:39:15 +0000131
132; Test that volatile loads do not use LOCG, since if the condition is false,
133; it is unspecified whether or not the load happens. LOCGR is fine though.
134define i64 @f10(i64 %easy, i64 *%ptr, i64 %limit) {
135; CHECK-LABEL: f10:
136; CHECK: lg {{%r[0-9]*}}, 0(%r3)
137; CHECK: locgr
138; CHECK: br %r14
139 %cond = icmp ult i64 %limit, 42
140 %other = load volatile i64, i64 *%ptr
141 %res = select i1 %cond, i64 %easy, i64 %other
142 ret i64 %res
143}
144