1; Test load-and-trap instructions (LLGFAT/LLGFTAT)
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s
4
5declare void @llvm.trap()
6
7; Check LLGFAT with no displacement.
8define i64 @f1(i32 *%ptr) {
9; CHECK-LABEL: f1:
10; CHECK: llgfat %r2, 0(%r2)
11; CHECK: br %r14
12entry:
13  %val = load i32, i32 *%ptr
14  %ext = zext i32 %val to i64
15  %cmp = icmp eq i64 %ext, 0
16  br i1 %cmp, label %if.then, label %if.end
17
18if.then:                                          ; preds = %entry
19  tail call void @llvm.trap()
20  unreachable
21
22if.end:                                           ; preds = %entry
23  ret i64 %ext
24}
25
26; Check the high end of the LLGFAT range.
27define i64 @f2(i32 *%src) {
28; CHECK-LABEL: f2:
29; CHECK: llgfat %r2, 524284(%r2)
30; CHECK: br %r14
31  %ptr = getelementptr i32, i32 *%src, i64 131071
32  %val = load i32, i32 *%ptr
33  %ext = zext i32 %val to i64
34  %cmp = icmp eq i64 %ext, 0
35  br i1 %cmp, label %if.then, label %if.end
36
37if.then:                                          ; preds = %entry
38  tail call void @llvm.trap()
39  unreachable
40
41if.end:                                           ; preds = %entry
42  ret i64 %ext
43}
44
45; Check the next word up, which needs separate address logic.
46; Other sequences besides this one would be OK.
47define i64 @f3(i32 *%src) {
48; CHECK-LABEL: f3:
49; CHECK: agfi %r2, 524288
50; CHECK: llgfat %r2, 0(%r2)
51; CHECK: br %r14
52  %ptr = getelementptr i32, i32 *%src, i64 131072
53  %val = load i32, i32 *%ptr
54  %ext = zext i32 %val to i64
55  %cmp = icmp eq i64 %ext, 0
56  br i1 %cmp, label %if.then, label %if.end
57
58if.then:                                          ; preds = %entry
59  tail call void @llvm.trap()
60  unreachable
61
62if.end:                                           ; preds = %entry
63  ret i64 %ext
64}
65
66; Check that LLGFAT allows an index.
67define i64 @f4(i64 %src, i64 %index) {
68; CHECK-LABEL: f4:
69; CHECK: llgfat %r2, 524287(%r3,%r2)
70; CHECK: br %r14
71  %add1 = add i64 %src, %index
72  %add2 = add i64 %add1, 524287
73  %ptr = inttoptr i64 %add2 to i32 *
74  %val = load i32, i32 *%ptr
75  %ext = zext i32 %val to i64
76  %cmp = icmp eq i64 %ext, 0
77  br i1 %cmp, label %if.then, label %if.end
78
79if.then:                                          ; preds = %entry
80  tail call void @llvm.trap()
81  unreachable
82
83if.end:                                           ; preds = %entry
84  ret i64 %ext
85}
86
87; Check LLGTAT with no displacement.
88define i64 @f5(i32 *%ptr) {
89; CHECK-LABEL: f5:
90; CHECK: llgtat %r2, 0(%r2)
91; CHECK: br %r14
92entry:
93  %val = load i32, i32 *%ptr
94  %ext = zext i32 %val to i64
95  %and = and i64 %ext, 2147483647
96  %cmp = icmp eq i64 %and, 0
97  br i1 %cmp, label %if.then, label %if.end
98
99if.then:                                          ; preds = %entry
100  tail call void @llvm.trap()
101  unreachable
102
103if.end:                                           ; preds = %entry
104  ret i64 %and
105}
106
107; Check the high end of the LLGTAT range.
108define i64 @f6(i32 *%src) {
109; CHECK-LABEL: f6:
110; CHECK: llgtat %r2, 524284(%r2)
111; CHECK: br %r14
112  %ptr = getelementptr i32, i32 *%src, i64 131071
113  %val = load i32, i32 *%ptr
114  %ext = zext i32 %val to i64
115  %and = and i64 %ext, 2147483647
116  %cmp = icmp eq i64 %and, 0
117  br i1 %cmp, label %if.then, label %if.end
118
119if.then:                                          ; preds = %entry
120  tail call void @llvm.trap()
121  unreachable
122
123if.end:                                           ; preds = %entry
124  ret i64 %and
125}
126
127; Check the next word up, which needs separate address logic.
128; Other sequences besides this one would be OK.
129define i64 @f7(i32 *%src) {
130; CHECK-LABEL: f7:
131; CHECK: agfi %r2, 524288
132; CHECK: llgtat %r2, 0(%r2)
133; CHECK: br %r14
134  %ptr = getelementptr i32, i32 *%src, i64 131072
135  %val = load i32, i32 *%ptr
136  %ext = zext i32 %val to i64
137  %and = and i64 %ext, 2147483647
138  %cmp = icmp eq i64 %and, 0
139  br i1 %cmp, label %if.then, label %if.end
140
141if.then:                                          ; preds = %entry
142  tail call void @llvm.trap()
143  unreachable
144
145if.end:                                           ; preds = %entry
146  ret i64 %and
147}
148
149; Check that LLGTAT allows an index.
150define i64 @f8(i64 %src, i64 %index) {
151; CHECK-LABEL: f8:
152; CHECK: llgtat %r2, 524287(%r3,%r2)
153; CHECK: br %r14
154  %add1 = add i64 %src, %index
155  %add2 = add i64 %add1, 524287
156  %ptr = inttoptr i64 %add2 to i32 *
157  %val = load i32, i32 *%ptr
158  %ext = zext i32 %val to i64
159  %and = and i64 %ext, 2147483647
160  %cmp = icmp eq i64 %and, 0
161  br i1 %cmp, label %if.then, label %if.end
162
163if.then:                                          ; preds = %entry
164  tail call void @llvm.trap()
165  unreachable
166
167if.end:                                           ; preds = %entry
168  ret i64 %and
169}
170
171