1; Test LOC. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 4 5; Run the test again to make sure it still works the same even 6; in the presence of the load-store-on-condition-2 facility. 7; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s 8 9declare i32 @foo(i32 *) 10 11; Test the simple case. 12define i32 @f1(i32 %easy, i32 *%ptr, i32 %limit) { 13; CHECK-LABEL: f1: 14; CHECK: clfi %r4, 42 15; CHECK: loche %r2, 0(%r3) 16; CHECK: br %r14 17 %cond = icmp ult i32 %limit, 42 18 %other = load i32, i32 *%ptr 19 %res = select i1 %cond, i32 %easy, i32 %other 20 ret i32 %res 21} 22 23; ...and again with the operands swapped. 24define i32 @f2(i32 %easy, i32 *%ptr, i32 %limit) { 25; CHECK-LABEL: f2: 26; CHECK: clfi %r4, 42 27; CHECK: locl %r2, 0(%r3) 28; CHECK: br %r14 29 %cond = icmp ult i32 %limit, 42 30 %other = load i32, i32 *%ptr 31 %res = select i1 %cond, i32 %other, i32 %easy 32 ret i32 %res 33} 34 35; Check the high end of the aligned LOC range. 36define i32 @f3(i32 %easy, i32 *%base, i32 %limit) { 37; CHECK-LABEL: f3: 38; CHECK: clfi %r4, 42 39; CHECK: loche %r2, 524284(%r3) 40; CHECK: br %r14 41 %ptr = getelementptr i32, i32 *%base, i64 131071 42 %cond = icmp ult i32 %limit, 42 43 %other = load i32, i32 *%ptr 44 %res = select i1 %cond, i32 %easy, i32 %other 45 ret i32 %res 46} 47 48; Check the next word up. Other sequences besides this one would be OK. 49define i32 @f4(i32 %easy, i32 *%base, i32 %limit) { 50; CHECK-LABEL: f4: 51; CHECK: agfi %r3, 524288 52; CHECK: clfi %r4, 42 53; CHECK: loche %r2, 0(%r3) 54; CHECK: br %r14 55 %ptr = getelementptr i32, i32 *%base, i64 131072 56 %cond = icmp ult i32 %limit, 42 57 %other = load i32, i32 *%ptr 58 %res = select i1 %cond, i32 %easy, i32 %other 59 ret i32 %res 60} 61 62; Check the low end of the LOC range. 63define i32 @f5(i32 %easy, i32 *%base, i32 %limit) { 64; CHECK-LABEL: f5: 65; CHECK: clfi %r4, 42 66; CHECK: loche %r2, -524288(%r3) 67; CHECK: br %r14 68 %ptr = getelementptr i32, i32 *%base, i64 -131072 69 %cond = icmp ult i32 %limit, 42 70 %other = load i32, i32 *%ptr 71 %res = select i1 %cond, i32 %easy, i32 %other 72 ret i32 %res 73} 74 75; Check the next word down, with the same comments as f4. 76define i32 @f6(i32 %easy, i32 *%base, i32 %limit) { 77; CHECK-LABEL: f6: 78; CHECK: agfi %r3, -524292 79; CHECK: clfi %r4, 42 80; CHECK: loche %r2, 0(%r3) 81; CHECK: br %r14 82 %ptr = getelementptr i32, i32 *%base, i64 -131073 83 %cond = icmp ult i32 %limit, 42 84 %other = load i32, i32 *%ptr 85 %res = select i1 %cond, i32 %easy, i32 %other 86 ret i32 %res 87} 88 89; Try a frame index base. 90define i32 @f7(i32 %alt, i32 %limit) { 91; CHECK-LABEL: f7: 92; CHECK: brasl %r14, foo@PLT 93; CHECK: loche %r2, {{[0-9]+}}(%r15) 94; CHECK: br %r14 95 %ptr = alloca i32 96 %easy = call i32 @foo(i32 *%ptr) 97 %cond = icmp ult i32 %limit, 42 98 %other = load i32, i32 *%ptr 99 %res = select i1 %cond, i32 %easy, i32 %other 100 ret i32 %res 101} 102 103; Try a case when an index is involved. 104define i32 @f8(i32 %easy, i32 %limit, i64 %base, i64 %index) { 105; CHECK-LABEL: f8: 106; CHECK: clfi %r3, 42 107; CHECK: loche %r2, 0({{%r[1-5]}}) 108; CHECK: br %r14 109 %add = add i64 %base, %index 110 %ptr = inttoptr i64 %add to i32 * 111 %cond = icmp ult i32 %limit, 42 112 %other = load i32, i32 *%ptr 113 %res = select i1 %cond, i32 %easy, i32 %other 114 ret i32 %res 115} 116 117; Test that conditionally-executed loads do not use LOC, since it is allowed 118; to trap even when the condition is false. 119define i32 @f9(i32 %easy, i32 %limit, i32 *%ptr) { 120; CHECK-LABEL: f9: 121; CHECK-NOT: loc 122; CHECK: br %r14 123entry: 124 %cmp = icmp ule i32 %easy, %limit 125 br i1 %cmp, label %load, label %exit 126 127load: 128 %other = load i32, i32 *%ptr 129 br label %exit 130 131exit: 132 %res = phi i32 [ %easy, %entry ], [ %other, %load ] 133 ret i32 %res 134} 135 136; Test that volatile loads do not use LOC, since if the condition is false, 137; it is unspecified whether or not the load happens. LOCR is fine though. 138define i32 @f10(i32 %easy, i32 *%ptr, i32 %limit) { 139; CHECK-LABEL: f10: 140; CHECK: l {{%r[0-9]*}}, 0(%r3) 141; CHECK: locr 142; CHECK: br %r14 143 %cond = icmp ult i32 %limit, 42 144 %other = load volatile i32, i32 *%ptr 145 %res = select i1 %cond, i32 %easy, i32 %other 146 ret i32 %res 147} 148 149