blob: 50adb3507dcf0328de59a017e73d40ffed58fcd9 [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
11; CHECK: locgnl %r2, 0(%r3)
12; CHECK: br %r14
13 %cond = icmp ult i64 %limit, 42
14 %other = load i64 *%ptr
15 %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
26 %other = load i64 *%ptr
27 %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
35; CHECK: locgnl %r2, 524280(%r3)
36; CHECK: br %r14
37 %ptr = getelementptr i64 *%base, i64 65535
38 %cond = icmp ult i64 %limit, 42
39 %other = load i64 *%ptr
40 %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
49; CHECK: locgnl %r2, 0(%r3)
50; CHECK: br %r14
51 %ptr = getelementptr i64 *%base, i64 65536
52 %cond = icmp ult i64 %limit, 42
53 %other = load i64 *%ptr
54 %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
62; CHECK: locgnl %r2, -524288(%r3)
63; CHECK: br %r14
64 %ptr = getelementptr i64 *%base, i64 -65536
65 %cond = icmp ult i64 %limit, 42
66 %other = load i64 *%ptr
67 %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
76; CHECK: locgnl %r2, 0(%r3)
77; CHECK: br %r14
78 %ptr = getelementptr i64 *%base, i64 -65537
79 %cond = icmp ult i64 %limit, 42
80 %other = load i64 *%ptr
81 %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
89; CHECK: locgnl %r2, {{[0-9]+}}(%r15)
90; CHECK: br %r14
91 %ptr = alloca i64
92 %easy = call i64 @foo(i64 *%ptr)
93 %cond = icmp ult i64 %limit, 42
94 %other = load i64 *%ptr
95 %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
103; CHECK: locgnl %r2, 0({{%r[1-5]}})
104; CHECK: br %r14
105 %add = add i64 %base, %index
106 %ptr = inttoptr i64 %add to i64 *
107 %cond = icmp ult i64 %limit, 42
108 %other = load i64 *%ptr
109 %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:
124 %other = load i64 *%ptr
125 br label %exit
126
127exit:
128 %res = phi i64 [ %easy, %entry ], [ %other, %load ]
129 ret i64 %res
130}