1; Test selection of addresses with indices in cases where the address
2; is used once.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5
6; A simple index address.
7define void @f1(i64 %addr, i64 %index) {
8; CHECK-LABEL: f1:
9; CHECK: lb %r0, 0(%r3,%r2)
10; CHECK: br %r14
11  %add = add i64 %addr, %index
12  %ptr = inttoptr i64 %add to i8 *
13  %a = load volatile i8 *%ptr
14  ret void
15}
16
17; An address with an index and a displacement (order 1).
18define void @f2(i64 %addr, i64 %index) {
19; CHECK-LABEL: f2:
20; CHECK: lb %r0, 100(%r3,%r2)
21; CHECK: br %r14
22  %add1 = add i64 %addr, %index
23  %add2 = add i64 %add1, 100
24  %ptr = inttoptr i64 %add2 to i8 *
25  %a = load volatile i8 *%ptr
26  ret void
27}
28
29; An address with an index and a displacement (order 2).
30define void @f3(i64 %addr, i64 %index) {
31; CHECK-LABEL: f3:
32; CHECK: lb %r0, 100(%r3,%r2)
33; CHECK: br %r14
34  %add1 = add i64 %addr, 100
35  %add2 = add i64 %add1, %index
36  %ptr = inttoptr i64 %add2 to i8 *
37  %a = load volatile i8 *%ptr
38  ret void
39}
40
41; An address with an index and a subtracted displacement (order 1).
42define void @f4(i64 %addr, i64 %index) {
43; CHECK-LABEL: f4:
44; CHECK: lb %r0, -100(%r3,%r2)
45; CHECK: br %r14
46  %add1 = add i64 %addr, %index
47  %add2 = sub i64 %add1, 100
48  %ptr = inttoptr i64 %add2 to i8 *
49  %a = load volatile i8 *%ptr
50  ret void
51}
52
53; An address with an index and a subtracted displacement (order 2).
54define void @f5(i64 %addr, i64 %index) {
55; CHECK-LABEL: f5:
56; CHECK: lb %r0, -100(%r3,%r2)
57; CHECK: br %r14
58  %add1 = sub i64 %addr, 100
59  %add2 = add i64 %add1, %index
60  %ptr = inttoptr i64 %add2 to i8 *
61  %a = load volatile i8 *%ptr
62  ret void
63}
64
65; An address with an index and a displacement added using OR.
66define void @f6(i64 %addr, i64 %index) {
67; CHECK-LABEL: f6:
68; CHECK: nill %r2, 65528
69; CHECK: lb %r0, 6(%r3,%r2)
70; CHECK: br %r14
71  %aligned = and i64 %addr, -8
72  %or = or i64 %aligned, 6
73  %add = add i64 %or, %index
74  %ptr = inttoptr i64 %add to i8 *
75  %a = load volatile i8 *%ptr
76  ret void
77}
78
79; Like f6, but without the masking.  This OR doesn't count as a displacement.
80define void @f7(i64 %addr, i64 %index) {
81; CHECK-LABEL: f7:
82; CHECK: oill %r2, 6
83; CHECK: lb %r0, 0(%r3,%r2)
84; CHECK: br %r14
85  %or = or i64 %addr, 6
86  %add = add i64 %or, %index
87  %ptr = inttoptr i64 %add to i8 *
88  %a = load volatile i8 *%ptr
89  ret void
90}
91
92; Like f6, but with the OR applied after the index.  We don't know anything
93; about the alignment of %add here.
94define void @f8(i64 %addr, i64 %index) {
95; CHECK-LABEL: f8:
96; CHECK: nill %r2, 65528
97; CHECK: agr %r2, %r3
98; CHECK: oill %r2, 6
99; CHECK: lb %r0, 0(%r2)
100; CHECK: br %r14
101  %aligned = and i64 %addr, -8
102  %add = add i64 %aligned, %index
103  %or = or i64 %add, 6
104  %ptr = inttoptr i64 %or to i8 *
105  %a = load volatile i8 *%ptr
106  ret void
107}
108