1; Test 32-bit additions of constants to memory. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5; Check additions of 1. 6define void @f1(i32 *%ptr) { 7; CHECK-LABEL: f1: 8; CHECK: asi 0(%r2), 1 9; CHECK: br %r14 10 %val = load i32 *%ptr 11 %add = add i32 %val, 127 12 store i32 %add, i32 *%ptr 13 ret void 14} 15 16; Check the high end of the constant range. 17define void @f2(i32 *%ptr) { 18; CHECK-LABEL: f2: 19; CHECK: asi 0(%r2), 127 20; CHECK: br %r14 21 %val = load i32 *%ptr 22 %add = add i32 %val, 127 23 store i32 %add, i32 *%ptr 24 ret void 25} 26 27; Check the next constant up, which must use an addition and a store. 28; Both L/AHI and LHI/A would be OK. 29define void @f3(i32 *%ptr) { 30; CHECK-LABEL: f3: 31; CHECK-NOT: asi 32; CHECK: st %r0, 0(%r2) 33; CHECK: br %r14 34 %val = load i32 *%ptr 35 %add = add i32 %val, 128 36 store i32 %add, i32 *%ptr 37 ret void 38} 39 40; Check the low end of the constant range. 41define void @f4(i32 *%ptr) { 42; CHECK-LABEL: f4: 43; CHECK: asi 0(%r2), -128 44; CHECK: br %r14 45 %val = load i32 *%ptr 46 %add = add i32 %val, -128 47 store i32 %add, i32 *%ptr 48 ret void 49} 50 51; Check the next value down, with the same comment as f3. 52define void @f5(i32 *%ptr) { 53; CHECK-LABEL: f5: 54; CHECK-NOT: asi 55; CHECK: st %r0, 0(%r2) 56; CHECK: br %r14 57 %val = load i32 *%ptr 58 %add = add i32 %val, -129 59 store i32 %add, i32 *%ptr 60 ret void 61} 62 63; Check the high end of the aligned ASI range. 64define void @f6(i32 *%base) { 65; CHECK-LABEL: f6: 66; CHECK: asi 524284(%r2), 1 67; CHECK: br %r14 68 %ptr = getelementptr i32 *%base, i64 131071 69 %val = load i32 *%ptr 70 %add = add i32 %val, 1 71 store i32 %add, i32 *%ptr 72 ret void 73} 74 75; Check the next word up, which must use separate address logic. 76; Other sequences besides this one would be OK. 77define void @f7(i32 *%base) { 78; CHECK-LABEL: f7: 79; CHECK: agfi %r2, 524288 80; CHECK: asi 0(%r2), 1 81; CHECK: br %r14 82 %ptr = getelementptr i32 *%base, i64 131072 83 %val = load i32 *%ptr 84 %add = add i32 %val, 1 85 store i32 %add, i32 *%ptr 86 ret void 87} 88 89; Check the low end of the ASI range. 90define void @f8(i32 *%base) { 91; CHECK-LABEL: f8: 92; CHECK: asi -524288(%r2), 1 93; CHECK: br %r14 94 %ptr = getelementptr i32 *%base, i64 -131072 95 %val = load i32 *%ptr 96 %add = add i32 %val, 1 97 store i32 %add, i32 *%ptr 98 ret void 99} 100 101; Check the next word down, which must use separate address logic. 102; Other sequences besides this one would be OK. 103define void @f9(i32 *%base) { 104; CHECK-LABEL: f9: 105; CHECK: agfi %r2, -524292 106; CHECK: asi 0(%r2), 1 107; CHECK: br %r14 108 %ptr = getelementptr i32 *%base, i64 -131073 109 %val = load i32 *%ptr 110 %add = add i32 %val, 1 111 store i32 %add, i32 *%ptr 112 ret void 113} 114 115; Check that ASI does not allow indices. 116define void @f10(i64 %base, i64 %index) { 117; CHECK-LABEL: f10: 118; CHECK: agr %r2, %r3 119; CHECK: asi 4(%r2), 1 120; CHECK: br %r14 121 %add1 = add i64 %base, %index 122 %add2 = add i64 %add1, 4 123 %ptr = inttoptr i64 %add2 to i32 * 124 %val = load i32 *%ptr 125 %add = add i32 %val, 1 126 store i32 %add, i32 *%ptr 127 ret void 128} 129