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