1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; addr-01.ll in which the address is also used in a non-address context.
3 ; The assumption here is that we should match complex addresses where
4 ; possible, but this might well need to change in future.
6 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
8 ; A simple index address.
9 define void @f1(i64 %addr, i64 %index, i8 **%dst) {
12 ; CHECK-NEXT: lb %r0, 0(%r3,%r2)
13 ; CHECK-NEXT: la %r0, 0(%r3,%r2)
14 ; CHECK-NEXT: stg %r0, 0(%r4)
16 %add = add i64 %addr, %index
17 %ptr = inttoptr i64 %add to i8 *
18 %a = load volatile i8, i8 *%ptr
19 store volatile i8 *%ptr, i8 **%dst
23 ; An address with an index and a displacement (order 1).
24 define void @f2(i64 %addr, i64 %index, i8 **%dst) {
27 ; CHECK-NEXT: lb %r0, 100(%r3,%r2)
28 ; CHECK-NEXT: la %r0, 100(%r3,%r2)
29 ; CHECK-NEXT: stg %r0, 0(%r4)
31 %add1 = add i64 %addr, %index
32 %add2 = add i64 %add1, 100
33 %ptr = inttoptr i64 %add2 to i8 *
34 %a = load volatile i8, i8 *%ptr
35 store volatile i8 *%ptr, i8 **%dst
39 ; An address with an index and a displacement (order 2).
40 define void @f3(i64 %addr, i64 %index, i8 **%dst) {
43 ; CHECK-NEXT: lb %r0, 100(%r3,%r2)
44 ; CHECK-NEXT: la %r0, 100(%r3,%r2)
45 ; CHECK-NEXT: stg %r0, 0(%r4)
47 %add1 = add i64 %addr, 100
48 %add2 = add i64 %add1, %index
49 %ptr = inttoptr i64 %add2 to i8 *
50 %a = load volatile i8, i8 *%ptr
51 store volatile i8 *%ptr, i8 **%dst
55 ; An address with an index and a subtracted displacement (order 1).
56 define void @f4(i64 %addr, i64 %index, i8 **%dst) {
59 ; CHECK-NEXT: lb %r0, -100(%r3,%r2)
60 ; CHECK-NEXT: lay %r0, -100(%r3,%r2)
61 ; CHECK-NEXT: stg %r0, 0(%r4)
63 %add1 = add i64 %addr, %index
64 %add2 = sub i64 %add1, 100
65 %ptr = inttoptr i64 %add2 to i8 *
66 %a = load volatile i8, i8 *%ptr
67 store volatile i8 *%ptr, i8 **%dst
71 ; An address with an index and a subtracted displacement (order 2).
72 define void @f5(i64 %addr, i64 %index, i8 **%dst) {
75 ; CHECK-NEXT: lb %r0, -100(%r3,%r2)
76 ; CHECK-NEXT: lay %r0, -100(%r3,%r2)
77 ; CHECK-NEXT: stg %r0, 0(%r4)
79 %add1 = sub i64 %addr, 100
80 %add2 = add i64 %add1, %index
81 %ptr = inttoptr i64 %add2 to i8 *
82 %a = load volatile i8, i8 *%ptr
83 store volatile i8 *%ptr, i8 **%dst
87 ; An address with an index and a displacement added using OR.
88 define void @f6(i64 %addr, i64 %index, i8 **%dst) {
91 ; CHECK-NEXT: nill %r2, 65528
92 ; CHECK-NEXT: lb %r0, 6(%r2,%r3)
93 ; CHECK-NEXT: la %r0, 6(%r2,%r3)
94 ; CHECK-NEXT: stg %r0, 0(%r4)
96 %aligned = and i64 %addr, -8
97 %or = or i64 %aligned, 6
98 %add = add i64 %or, %index
99 %ptr = inttoptr i64 %add to i8 *
100 %a = load volatile i8, i8 *%ptr
101 store volatile i8 *%ptr, i8 **%dst
105 ; Like f6, but without the masking. This OR doesn't count as a displacement.
106 define void @f7(i64 %addr, i64 %index, i8 **%dst) {
109 ; CHECK-NEXT: oill %r2, 6
110 ; CHECK-NEXT: lb %r0, 0(%r3,%r2)
111 ; CHECK-NEXT: la %r0, 0(%r3,%r2)
112 ; CHECK-NEXT: stg %r0, 0(%r4)
113 ; CHECK-NEXT: br %r14
114 %or = or i64 %addr, 6
115 %add = add i64 %or, %index
116 %ptr = inttoptr i64 %add to i8 *
117 %a = load volatile i8, i8 *%ptr
118 store volatile i8 *%ptr, i8 **%dst
122 ; Like f6, but with the OR applied after the index. We don't know anything
123 ; about the alignment of %add here.
124 define void @f8(i64 %addr, i64 %index, i8 **%dst) {
127 ; CHECK-NEXT: nill %r2, 65528
128 ; CHECK-NEXT: agr %r2, %r3
129 ; CHECK-NEXT: oill %r2, 6
130 ; CHECK-NEXT: lb %r0, 0(%r2)
131 ; CHECK-NEXT: stg %r2, 0(%r4)
132 ; CHECK-NEXT: br %r14
133 %aligned = and i64 %addr, -8
134 %add = add i64 %aligned, %index
136 %ptr = inttoptr i64 %or to i8 *
137 %a = load volatile i8, i8 *%ptr
138 store volatile i8 *%ptr, i8 **%dst