1; Test LOC.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
4
5declare i32 @foo(i32 *)
6
7; Test the simple case.
8define i32 @f1(i32 %easy, i32 *%ptr, i32 %limit) {
9; CHECK-LABEL: f1:
10; CHECK: clfi %r4, 42
11; CHECK: loche %r2, 0(%r3)
12; CHECK: br %r14
13  %cond = icmp ult i32 %limit, 42
14  %other = load i32 *%ptr
15  %res = select i1 %cond, i32 %easy, i32 %other
16  ret i32 %res
17}
18
19; ...and again with the operands swapped.
20define i32 @f2(i32 %easy, i32 *%ptr, i32 %limit) {
21; CHECK-LABEL: f2:
22; CHECK: clfi %r4, 42
23; CHECK: locl %r2, 0(%r3)
24; CHECK: br %r14
25  %cond = icmp ult i32 %limit, 42
26  %other = load i32 *%ptr
27  %res = select i1 %cond, i32 %other, i32 %easy
28  ret i32 %res
29}
30
31; Check the high end of the aligned LOC range.
32define i32 @f3(i32 %easy, i32 *%base, i32 %limit) {
33; CHECK-LABEL: f3:
34; CHECK: clfi %r4, 42
35; CHECK: loche %r2, 524284(%r3)
36; CHECK: br %r14
37  %ptr = getelementptr i32 *%base, i64 131071
38  %cond = icmp ult i32 %limit, 42
39  %other = load i32 *%ptr
40  %res = select i1 %cond, i32 %easy, i32 %other
41  ret i32 %res
42}
43
44; Check the next word up.  Other sequences besides this one would be OK.
45define i32 @f4(i32 %easy, i32 *%base, i32 %limit) {
46; CHECK-LABEL: f4:
47; CHECK: agfi %r3, 524288
48; CHECK: clfi %r4, 42
49; CHECK: loche %r2, 0(%r3)
50; CHECK: br %r14
51  %ptr = getelementptr i32 *%base, i64 131072
52  %cond = icmp ult i32 %limit, 42
53  %other = load i32 *%ptr
54  %res = select i1 %cond, i32 %easy, i32 %other
55  ret i32 %res
56}
57
58; Check the low end of the LOC range.
59define i32 @f5(i32 %easy, i32 *%base, i32 %limit) {
60; CHECK-LABEL: f5:
61; CHECK: clfi %r4, 42
62; CHECK: loche %r2, -524288(%r3)
63; CHECK: br %r14
64  %ptr = getelementptr i32 *%base, i64 -131072
65  %cond = icmp ult i32 %limit, 42
66  %other = load i32 *%ptr
67  %res = select i1 %cond, i32 %easy, i32 %other
68  ret i32 %res
69}
70
71; Check the next word down, with the same comments as f4.
72define i32 @f6(i32 %easy, i32 *%base, i32 %limit) {
73; CHECK-LABEL: f6:
74; CHECK: agfi %r3, -524292
75; CHECK: clfi %r4, 42
76; CHECK: loche %r2, 0(%r3)
77; CHECK: br %r14
78  %ptr = getelementptr i32 *%base, i64 -131073
79  %cond = icmp ult i32 %limit, 42
80  %other = load i32 *%ptr
81  %res = select i1 %cond, i32 %easy, i32 %other
82  ret i32 %res
83}
84
85; Try a frame index base.
86define i32 @f7(i32 %alt, i32 %limit) {
87; CHECK-LABEL: f7:
88; CHECK: brasl %r14, foo@PLT
89; CHECK: loche %r2, {{[0-9]+}}(%r15)
90; CHECK: br %r14
91  %ptr = alloca i32
92  %easy = call i32 @foo(i32 *%ptr)
93  %cond = icmp ult i32 %limit, 42
94  %other = load i32 *%ptr
95  %res = select i1 %cond, i32 %easy, i32 %other
96  ret i32 %res
97}
98
99; Try a case when an index is involved.
100define i32 @f8(i32 %easy, i32 %limit, i64 %base, i64 %index) {
101; CHECK-LABEL: f8:
102; CHECK: clfi %r3, 42
103; CHECK: loche %r2, 0({{%r[1-5]}})
104; CHECK: br %r14
105  %add = add i64 %base, %index
106  %ptr = inttoptr i64 %add to i32 *
107  %cond = icmp ult i32 %limit, 42
108  %other = load i32 *%ptr
109  %res = select i1 %cond, i32 %easy, i32 %other
110  ret i32 %res
111}
112
113; Test that conditionally-executed loads do not use LOC, since it is allowed
114; to trap even when the condition is false.
115define i32 @f9(i32 %easy, i32 %limit, i32 *%ptr) {
116; CHECK-LABEL: f9:
117; CHECK-NOT: loc
118; CHECK: br %r14
119entry:
120  %cmp = icmp ule i32 %easy, %limit
121  br i1 %cmp, label %load, label %exit
122
123load:
124  %other = load i32 *%ptr
125  br label %exit
126
127exit:
128  %res = phi i32 [ %easy, %entry ], [ %other, %load ]
129  ret i32 %res
130}
131