1; Test 32-bit signed comparison in which the second operand is sign-extended 2; from an i16 memory value. 3; 4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 5 6; Check the low end of the CH range. 7define void @f1(i32 %lhs, i16 *%src, i32 *%dst) { 8; CHECK-LABEL: f1: 9; CHECK: ch %r2, 0(%r3) 10; CHECK: br %r14 11 %half = load i16, i16 *%src 12 %rhs = sext i16 %half to i32 13 %cond = icmp slt i32 %lhs, %rhs 14 %res = select i1 %cond, i32 100, i32 200 15 store i32 %res, i32 *%dst 16 ret void 17} 18 19; Check the high end of the aligned CH range. 20define void @f2(i32 %lhs, i16 *%src, i32 *%dst) { 21; CHECK-LABEL: f2: 22; CHECK: ch %r2, 4094(%r3) 23; CHECK: br %r14 24 %ptr = getelementptr i16, i16 *%src, i64 2047 25 %half = load i16, i16 *%ptr 26 %rhs = sext i16 %half to i32 27 %cond = icmp slt i32 %lhs, %rhs 28 %res = select i1 %cond, i32 100, i32 200 29 store i32 %res, i32 *%dst 30 ret void 31} 32 33; Check the next halfword up, which should use CHY instead of CH. 34define void @f3(i32 %lhs, i16 *%src, i32 *%dst) { 35; CHECK-LABEL: f3: 36; CHECK: chy %r2, 4096(%r3) 37; CHECK: br %r14 38 %ptr = getelementptr i16, i16 *%src, i64 2048 39 %half = load i16, i16 *%ptr 40 %rhs = sext i16 %half to i32 41 %cond = icmp slt i32 %lhs, %rhs 42 %res = select i1 %cond, i32 100, i32 200 43 store i32 %res, i32 *%dst 44 ret void 45} 46 47; Check the high end of the aligned CHY range. 48define void @f4(i32 %lhs, i16 *%src, i32 *%dst) { 49; CHECK-LABEL: f4: 50; CHECK: chy %r2, 524286(%r3) 51; CHECK: br %r14 52 %ptr = getelementptr i16, i16 *%src, i64 262143 53 %half = load i16, i16 *%ptr 54 %rhs = sext i16 %half to i32 55 %cond = icmp slt i32 %lhs, %rhs 56 %res = select i1 %cond, i32 100, i32 200 57 store i32 %res, i32 *%dst 58 ret void 59} 60 61; Check the next halfword up, which needs separate address logic. 62; Other sequences besides this one would be OK. 63define void @f5(i32 %lhs, i16 *%src, i32 *%dst) { 64; CHECK-LABEL: f5: 65; CHECK: agfi %r3, 524288 66; CHECK: ch %r2, 0(%r3) 67; CHECK: br %r14 68 %ptr = getelementptr i16, i16 *%src, i64 262144 69 %half = load i16, i16 *%ptr 70 %rhs = sext i16 %half to i32 71 %cond = icmp slt i32 %lhs, %rhs 72 %res = select i1 %cond, i32 100, i32 200 73 store i32 %res, i32 *%dst 74 ret void 75} 76 77; Check the high end of the negative aligned CHY range. 78define void @f6(i32 %lhs, i16 *%src, i32 *%dst) { 79; CHECK-LABEL: f6: 80; CHECK: chy %r2, -2(%r3) 81; CHECK: br %r14 82 %ptr = getelementptr i16, i16 *%src, i64 -1 83 %half = load i16, i16 *%ptr 84 %rhs = sext i16 %half to i32 85 %cond = icmp slt i32 %lhs, %rhs 86 %res = select i1 %cond, i32 100, i32 200 87 store i32 %res, i32 *%dst 88 ret void 89} 90 91; Check the low end of the CHY range. 92define void @f7(i32 %lhs, i16 *%src, i32 *%dst) { 93; CHECK-LABEL: f7: 94; CHECK: chy %r2, -524288(%r3) 95; CHECK: br %r14 96 %ptr = getelementptr i16, i16 *%src, i64 -262144 97 %half = load i16, i16 *%ptr 98 %rhs = sext i16 %half to i32 99 %cond = icmp slt i32 %lhs, %rhs 100 %res = select i1 %cond, i32 100, i32 200 101 store i32 %res, i32 *%dst 102 ret void 103} 104 105; Check the next halfword down, which needs separate address logic. 106; Other sequences besides this one would be OK. 107define void @f8(i32 %lhs, i16 *%src, i32 *%dst) { 108; CHECK-LABEL: f8: 109; CHECK: agfi %r3, -524290 110; CHECK: ch %r2, 0(%r3) 111; CHECK: br %r14 112 %ptr = getelementptr i16, i16 *%src, i64 -262145 113 %half = load i16, i16 *%ptr 114 %rhs = sext i16 %half to i32 115 %cond = icmp slt i32 %lhs, %rhs 116 %res = select i1 %cond, i32 100, i32 200 117 store i32 %res, i32 *%dst 118 ret void 119} 120 121; Check that CH allows an index. 122define void @f9(i32 %lhs, i64 %base, i64 %index, i32 *%dst) { 123; CHECK-LABEL: f9: 124; CHECK: ch %r2, 4094({{%r4,%r3|%r3,%r4}}) 125; CHECK: br %r14 126 %add1 = add i64 %base, %index 127 %add2 = add i64 %add1, 4094 128 %ptr = inttoptr i64 %add2 to i16 * 129 %half = load i16, i16 *%ptr 130 %rhs = sext i16 %half to i32 131 %cond = icmp slt i32 %lhs, %rhs 132 %res = select i1 %cond, i32 100, i32 200 133 store i32 %res, i32 *%dst 134 ret void 135} 136 137; Check that CHY allows an index. 138define void @f10(i32 %lhs, i64 %base, i64 %index, i32 *%dst) { 139; CHECK-LABEL: f10: 140; CHECK: chy %r2, 4096({{%r4,%r3|%r3,%r4}}) 141; CHECK: br %r14 142 %add1 = add i64 %base, %index 143 %add2 = add i64 %add1, 4096 144 %ptr = inttoptr i64 %add2 to i16 * 145 %half = load i16, i16 *%ptr 146 %rhs = sext i16 %half to i32 147 %cond = icmp slt i32 %lhs, %rhs 148 %res = select i1 %cond, i32 100, i32 200 149 store i32 %res, i32 *%dst 150 ret void 151} 152 153; Check the comparison can be reversed if that allows CH to be used. 154define double @f11(double %a, double %b, i32 %rhs, i16 *%src) { 155; CHECK-LABEL: f11: 156; CHECK: ch %r2, 0(%r3) 157; CHECK-NEXT: bhr %r14 158; CHECK: ldr %f0, %f2 159; CHECK: br %r14 160 %half = load i16, i16 *%src 161 %lhs = sext i16 %half to i32 162 %cond = icmp slt i32 %lhs, %rhs 163 %res = select i1 %cond, double %a, double %b 164 ret double %res 165} 166