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. 5; 6; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 7 8; A simple index address. 9define void @f1(i64 %addr, i64 %index, i8 **%dst) { 10; CHECK-LABEL: f1: 11; CHECK: # %bb.0: 12; CHECK-NEXT: lb %r0, 0(%r3,%r2) 13; CHECK-NEXT: la %r0, 0(%r3,%r2) 14; CHECK-NEXT: stg %r0, 0(%r4) 15; CHECK-NEXT: br %r14 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 20 ret void 21} 22 23; An address with an index and a displacement (order 1). 24define void @f2(i64 %addr, i64 %index, i8 **%dst) { 25; CHECK-LABEL: f2: 26; CHECK: # %bb.0: 27; CHECK-NEXT: lb %r0, 100(%r3,%r2) 28; CHECK-NEXT: la %r0, 100(%r3,%r2) 29; CHECK-NEXT: stg %r0, 0(%r4) 30; CHECK-NEXT: br %r14 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 36 ret void 37} 38 39; An address with an index and a displacement (order 2). 40define void @f3(i64 %addr, i64 %index, i8 **%dst) { 41; CHECK-LABEL: f3: 42; CHECK: # %bb.0: 43; CHECK-NEXT: lb %r0, 100(%r3,%r2) 44; CHECK-NEXT: la %r0, 100(%r3,%r2) 45; CHECK-NEXT: stg %r0, 0(%r4) 46; CHECK-NEXT: br %r14 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 52 ret void 53} 54 55; An address with an index and a subtracted displacement (order 1). 56define void @f4(i64 %addr, i64 %index, i8 **%dst) { 57; CHECK-LABEL: f4: 58; CHECK: # %bb.0: 59; CHECK-NEXT: lb %r0, -100(%r3,%r2) 60; CHECK-NEXT: lay %r0, -100(%r3,%r2) 61; CHECK-NEXT: stg %r0, 0(%r4) 62; CHECK-NEXT: br %r14 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 68 ret void 69} 70 71; An address with an index and a subtracted displacement (order 2). 72define void @f5(i64 %addr, i64 %index, i8 **%dst) { 73; CHECK-LABEL: f5: 74; CHECK: # %bb.0: 75; CHECK-NEXT: lb %r0, -100(%r3,%r2) 76; CHECK-NEXT: lay %r0, -100(%r3,%r2) 77; CHECK-NEXT: stg %r0, 0(%r4) 78; CHECK-NEXT: br %r14 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 84 ret void 85} 86 87; An address with an index and a displacement added using OR. 88define void @f6(i64 %addr, i64 %index, i8 **%dst) { 89; CHECK-LABEL: f6: 90; CHECK: # %bb.0: 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) 95; CHECK-NEXT: br %r14 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 102 ret void 103} 104 105; Like f6, but without the masking. This OR doesn't count as a displacement. 106define void @f7(i64 %addr, i64 %index, i8 **%dst) { 107; CHECK-LABEL: f7: 108; CHECK: # %bb.0: 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 119 ret void 120} 121 122; Like f6, but with the OR applied after the index. We don't know anything 123; about the alignment of %add here. 124define void @f8(i64 %addr, i64 %index, i8 **%dst) { 125; CHECK-LABEL: f8: 126; CHECK: # %bb.0: 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 135 %or = or i64 %add, 6 136 %ptr = inttoptr i64 %or to i8 * 137 %a = load volatile i8, i8 *%ptr 138 store volatile i8 *%ptr, i8 **%dst 139 ret void 140} 141