1; Test 64-bit GPR accesses to a PC-relative location.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5@gsrc16 = dso_local global i16 1
6@gsrc32 = dso_local global i32 1
7@gsrc64 = dso_local global i64 1
8@gdst16 = dso_local global i16 2
9@gdst32 = dso_local global i32 2
10@gdst64 = dso_local global i64 2
11@gsrc16u = dso_local global i16 1, align 1, section "foo"
12@gsrc32u = dso_local global i32 1, align 2, section "foo"
13@gsrc64u = dso_local global i64 1, align 4, section "foo"
14@gdst16u = dso_local global i16 2, align 1, section "foo"
15@gdst32u = dso_local global i32 2, align 2, section "foo"
16@gdst64u = dso_local global i64 2, align 4, section "foo"
17
18; Check sign-extending loads from i16.
19define dso_local i64 @f1() {
20; CHECK-LABEL: f1:
21; CHECK: lghrl %r2, gsrc16
22; CHECK: br %r14
23  %val = load i16, i16 *@gsrc16
24  %ext = sext i16 %val to i64
25  ret i64 %ext
26}
27
28; Check zero-extending loads from i16.
29define dso_local i64 @f2() {
30; CHECK-LABEL: f2:
31; CHECK: llghrl %r2, gsrc16
32; CHECK: br %r14
33  %val = load i16, i16 *@gsrc16
34  %ext = zext i16 %val to i64
35  ret i64 %ext
36}
37
38; Check sign-extending loads from i32.
39define dso_local i64 @f3() {
40; CHECK-LABEL: f3:
41; CHECK: lgfrl %r2, gsrc32
42; CHECK: br %r14
43  %val = load i32, i32 *@gsrc32
44  %ext = sext i32 %val to i64
45  ret i64 %ext
46}
47
48; Check zero-extending loads from i32.
49define dso_local i64 @f4() {
50; CHECK-LABEL: f4:
51; CHECK: llgfrl %r2, gsrc32
52; CHECK: br %r14
53  %val = load i32, i32 *@gsrc32
54  %ext = zext i32 %val to i64
55  ret i64 %ext
56}
57
58; Check truncating 16-bit stores.
59define dso_local void @f5(i64 %val) {
60; CHECK-LABEL: f5:
61; CHECK: sthrl %r2, gdst16
62; CHECK: br %r14
63  %half = trunc i64 %val to i16
64  store i16 %half, i16 *@gdst16
65  ret void
66}
67
68; Check truncating 32-bit stores.
69define dso_local void @f6(i64 %val) {
70; CHECK-LABEL: f6:
71; CHECK: strl %r2, gdst32
72; CHECK: br %r14
73  %word = trunc i64 %val to i32
74  store i32 %word, i32 *@gdst32
75  ret void
76}
77
78; Check plain loads and stores.
79define dso_local void @f7() {
80; CHECK-LABEL: f7:
81; CHECK: lgrl %r0, gsrc64
82; CHECK: stgrl %r0, gdst64
83; CHECK: br %r14
84  %val = load i64, i64 *@gsrc64
85  store i64 %val, i64 *@gdst64
86  ret void
87}
88
89; Repeat f1 with an unaligned variable.
90define dso_local i64 @f8() {
91; CHECK-LABEL: f8:
92; CHECK: lgrl [[REG:%r[0-5]]], gsrc16u@GOT
93; CHECK: lgh %r2, 0([[REG]])
94; CHECK: br %r14
95  %val = load i16, i16 *@gsrc16u, align 1
96  %ext = sext i16 %val to i64
97  ret i64 %ext
98}
99
100; Repeat f2 with an unaligned variable.
101define dso_local i64 @f9() {
102; CHECK-LABEL: f9:
103; CHECK: lgrl [[REG:%r[0-5]]], gsrc16u@GOT
104; CHECK: llgh %r2, 0([[REG]])
105; CHECK: br %r14
106  %val = load i16, i16 *@gsrc16u, align 1
107  %ext = zext i16 %val to i64
108  ret i64 %ext
109}
110
111; Repeat f3 with an unaligned variable.
112define dso_local i64 @f10() {
113; CHECK-LABEL: f10:
114; CHECK: larl [[REG:%r[0-5]]], gsrc32u
115; CHECK: lgf %r2, 0([[REG]])
116; CHECK: br %r14
117  %val = load i32, i32 *@gsrc32u, align 2
118  %ext = sext i32 %val to i64
119  ret i64 %ext
120}
121
122; Repeat f4 with an unaligned variable.
123define dso_local i64 @f11() {
124; CHECK-LABEL: f11:
125; CHECK: larl [[REG:%r[0-5]]], gsrc32u
126; CHECK: llgf %r2, 0([[REG]])
127; CHECK: br %r14
128  %val = load i32, i32 *@gsrc32u, align 2
129  %ext = zext i32 %val to i64
130  ret i64 %ext
131}
132
133; Repeat f5 with an unaligned variable.
134define dso_local void @f12(i64 %val) {
135; CHECK-LABEL: f12:
136; CHECK: lgrl [[REG:%r[0-5]]], gdst16u@GOT
137; CHECK: sth %r2, 0([[REG]])
138; CHECK: br %r14
139  %half = trunc i64 %val to i16
140  store i16 %half, i16 *@gdst16u, align 1
141  ret void
142}
143
144; Repeat f6 with an unaligned variable.
145define dso_local void @f13(i64 %val) {
146; CHECK-LABEL: f13:
147; CHECK: larl [[REG:%r[0-5]]], gdst32u
148; CHECK: st %r2, 0([[REG]])
149; CHECK: br %r14
150  %word = trunc i64 %val to i32
151  store i32 %word, i32 *@gdst32u, align 2
152  ret void
153}
154
155; Repeat f7 with unaligned variables.
156define dso_local void @f14() {
157; CHECK-LABEL: f14:
158; CHECK: larl [[REG:%r[0-5]]], gsrc64u
159; CHECK: lg [[VAL:%r[0-5]]], 0([[REG]])
160; CHECK: larl [[REG:%r[0-5]]], gdst64u
161; CHECK: stg [[VAL]], 0([[REG]])
162; CHECK: br %r14
163  %val = load i64, i64 *@gsrc64u, align 4
164  store i64 %val, i64 *@gdst64u, align 4
165  ret void
166}
167