blob: f4406508d4002a31c293ac263f8b9bb0194663f8 [file] [log] [blame]
Ulrich Weigand524f2762016-11-28 13:34:08 +00001; Test LOCFH. See comments in asm-18.ll about testing high-word operations.
2;
3; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z13 \
Joel E. Denny9fa9c932018-07-11 20:25:49 +00004; RUN: -no-integrated-as | FileCheck -allow-deprecated-dag-overlap %s
Ulrich Weigand524f2762016-11-28 13:34:08 +00005
6declare void @foo(i32 *)
7
8; Test the simple case.
9define void @f1(i32 *%ptr, i32 %limit) {
10; CHECK-LABEL: f1:
11; CHECK-DAG: stepa [[REG:%r[0-5]]]
12; CHECK-DAG: clfi %r3, 42
13; CHECK: locfhhe [[REG]], 0(%r2)
14; CHECK: br %r14
15 %easy = call i32 asm "stepa $0", "=h"()
16 %cond = icmp ult i32 %limit, 42
17 %other = load i32, i32 *%ptr
18 %res = select i1 %cond, i32 %easy, i32 %other
19 call void asm sideeffect "stepb $0", "h"(i32 %res)
20 ret void
21}
22
23; ...and again with the operands swapped.
24define void @f2(i32 *%ptr, i32 %limit) {
25; CHECK-LABEL: f2:
26; CHECK-DAG: stepa [[REG:%r[0-5]]]
27; CHECK-DAG: clfi %r3, 42
28; CHECK: locfhl [[REG]], 0(%r2)
29; CHECK: br %r14
30 %easy = call i32 asm "stepa $0", "=h"()
31 %cond = icmp ult i32 %limit, 42
32 %other = load i32, i32 *%ptr
33 %res = select i1 %cond, i32 %other, i32 %easy
34 call void asm sideeffect "stepb $0", "h"(i32 %res)
35 ret void
36}
37
38; Check the high end of the aligned LOC range.
39define void @f3(i32 *%base, i32 %limit) {
40; CHECK-LABEL: f3:
41; CHECK-DAG: stepa [[REG:%r[0-5]]]
42; CHECK-DAG: clfi %r3, 42
43; CHECK: locfhhe [[REG]], 524284(%r2)
44; CHECK: br %r14
45 %easy = call i32 asm "stepa $0", "=h"()
46 %ptr = getelementptr i32, i32 *%base, i64 131071
47 %cond = icmp ult i32 %limit, 42
48 %other = load i32, i32 *%ptr
49 %res = select i1 %cond, i32 %easy, i32 %other
50 call void asm sideeffect "stepb $0", "h"(i32 %res)
51 ret void
52}
53
54; Check the next word up. Other sequences besides this one would be OK.
55define void @f4(i32 *%base, i32 %limit) {
56; CHECK-LABEL: f4:
57; CHECK-DAG: stepa [[REG:%r[0-5]]]
58; CHECK-DAG: agfi %r2, 524288
59; CHECK-DAG: clfi %r3, 42
60; CHECK: locfhhe [[REG]], 0(%r2)
61; CHECK: br %r14
62 %easy = call i32 asm "stepa $0", "=h"()
63 %ptr = getelementptr i32, i32 *%base, i64 131072
64 %cond = icmp ult i32 %limit, 42
65 %other = load i32, i32 *%ptr
66 %res = select i1 %cond, i32 %easy, i32 %other
67 call void asm sideeffect "stepb $0", "h"(i32 %res)
68 ret void
69}
70
71; Check the low end of the LOC range.
72define void @f5(i32 *%base, i32 %limit) {
73; CHECK-LABEL: f5:
74; CHECK-DAG: stepa [[REG:%r[0-5]]]
75; CHECK-DAG: clfi %r3, 42
76; CHECK: locfhhe [[REG]], -524288(%r2)
77; CHECK: br %r14
78 %easy = call i32 asm "stepa $0", "=h"()
79 %ptr = getelementptr i32, i32 *%base, i64 -131072
80 %cond = icmp ult i32 %limit, 42
81 %other = load i32, i32 *%ptr
82 %res = select i1 %cond, i32 %easy, i32 %other
83 call void asm sideeffect "stepb $0", "h"(i32 %res)
84 ret void
85}
86
87; Check the next word down, with the same comments as f4.
88define void @f6(i32 *%base, i32 %limit) {
89; CHECK-LABEL: f6:
90; CHECK-DAG: stepa [[REG:%r[0-5]]]
91; CHECK-DAG: clfi %r3, 42
92; CHECK-DAG: agfi %r2, -524292
93; CHECK-DAG: clfi %r3, 42
94; CHECK: locfhhe [[REG]], 0(%r2)
95; CHECK: br %r14
96 %easy = call i32 asm "stepa $0", "=h"()
97 %ptr = getelementptr i32, i32 *%base, i64 -131073
98 %cond = icmp ult i32 %limit, 42
99 %other = load i32, i32 *%ptr
100 %res = select i1 %cond, i32 %easy, i32 %other
101 call void asm sideeffect "stepb $0", "h"(i32 %res)
102 ret void
103}
104
105; Try a frame index base.
106define void @f7(i32 %alt, i32 %limit) {
107; CHECK-LABEL: f7:
108; CHECK: brasl %r14, foo@PLT
109; CHECK: stepa [[REG:%r[0-5]]]
110; CHECK: locfhhe [[REG]], {{[0-9]+}}(%r15)
111; CHECK: br %r14
112 %ptr = alloca i32
113 call void @foo(i32 *%ptr)
114 %easy = call i32 asm "stepa $0", "=h"()
115 %cond = icmp ult i32 %limit, 42
116 %other = load i32, i32 *%ptr
117 %res = select i1 %cond, i32 %easy, i32 %other
118 call void asm sideeffect "stepb $0", "h"(i32 %res)
119 ret void
120}
121
122; Try a case when an index is involved.
123define void @f8(i32 %limit, i64 %base, i64 %index) {
124; CHECK-LABEL: f8:
125; CHECK-DAG: stepa [[REG:%r[0-5]]]
126; CHECK-DAG: clfi %r2, 42
127; CHECK: locfhhe [[REG]], 0({{%r[1-5]}})
128; CHECK: br %r14
129 %easy = call i32 asm "stepa $0", "=h"()
130 %add = add i64 %base, %index
131 %ptr = inttoptr i64 %add to i32 *
132 %cond = icmp ult i32 %limit, 42
133 %other = load i32, i32 *%ptr
134 %res = select i1 %cond, i32 %easy, i32 %other
135 call void asm sideeffect "stepb $0", "h"(i32 %res)
136 ret void
137}
138
139; Test that conditionally-executed loads do not use LOC, since it is allowed
140; to trap even when the condition is false.
141define void @f9(i32 %limit, i32 *%ptr) {
142; CHECK-LABEL: f9:
143; CHECK-NOT: loc
144; CHECK: lfh
145; CHECK: br %r14
146entry:
147 %easy = call i32 asm "stepa $0", "=h"()
148 %cmp = icmp ule i32 %easy, %limit
149 br i1 %cmp, label %load, label %exit
150
151load:
152 %other = load i32, i32 *%ptr
153 br label %exit
154
155exit:
156 %res = phi i32 [ %easy, %entry ], [ %other, %load ]
157 call void asm sideeffect "stepb $0", "h"(i32 %res)
158 ret void
159}