1 ; Test LOCFH. See comments in asm-18.ll about testing high-word operations.
3 ; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z13 \
4 ; RUN: -no-integrated-as | FileCheck -allow-deprecated-dag-overlap %s
6 declare void @foo(i32 *)
8 ; Test the simple case.
9 define void @f1(i32 *%ptr, i32 %limit) {
11 ; CHECK-DAG: stepa [[REG:%r[0-5]]]
12 ; CHECK-DAG: clfi %r3, 42
13 ; CHECK: locfhhe [[REG]], 0(%r2)
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)
23 ; ...and again with the operands swapped.
24 define void @f2(i32 *%ptr, i32 %limit) {
26 ; CHECK-DAG: stepa [[REG:%r[0-5]]]
27 ; CHECK-DAG: clfi %r3, 42
28 ; CHECK: locfhl [[REG]], 0(%r2)
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)
38 ; Check the high end of the aligned LOC range.
39 define void @f3(i32 *%base, i32 %limit) {
41 ; CHECK-DAG: stepa [[REG:%r[0-5]]]
42 ; CHECK-DAG: clfi %r3, 42
43 ; CHECK: locfhhe [[REG]], 524284(%r2)
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)
54 ; Check the next word up. Other sequences besides this one would be OK.
55 define void @f4(i32 *%base, i32 %limit) {
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)
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)
71 ; Check the low end of the LOC range.
72 define void @f5(i32 *%base, i32 %limit) {
74 ; CHECK-DAG: stepa [[REG:%r[0-5]]]
75 ; CHECK-DAG: clfi %r3, 42
76 ; CHECK: locfhhe [[REG]], -524288(%r2)
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)
87 ; Check the next word down, with the same comments as f4.
88 define void @f6(i32 *%base, i32 %limit) {
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)
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)
105 ; Try a frame index base.
106 define void @f7(i32 %alt, i32 %limit) {
108 ; CHECK: brasl %r14, foo@PLT
109 ; CHECK: stepa [[REG:%r[0-5]]]
110 ; CHECK: locfhhe [[REG]], {{[0-9]+}}(%r15)
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)
122 ; Try a case when an index is involved.
123 define void @f8(i32 %limit, i64 %base, i64 %index) {
125 ; CHECK-DAG: stepa [[REG:%r[0-5]]]
126 ; CHECK-DAG: clfi %r2, 42
127 ; CHECK: locfhhe [[REG]], 0({{%r[1-5]}})
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)
139 ; Test that conditionally-executed loads do not use LOC, since it is allowed
140 ; to trap even when the condition is false.
141 define void @f9(i32 %limit, i32 *%ptr) {
147 %easy = call i32 asm "stepa $0", "=h"()
148 %cmp = icmp ule i32 %easy, %limit
149 br i1 %cmp, label %load, label %exit
152 %other = load i32, i32 *%ptr
156 %res = phi i32 [ %easy, %entry ], [ %other, %load ]
157 call void asm sideeffect "stepb $0", "h"(i32 %res)