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. 7 define 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. 20 define 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. 34 define 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. 48 define 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. 63 define 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. 78 define 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. 92 define 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. 107 define 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. 122 define 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. 138 define 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. 154 define double @f11(double %a, double %b, i32 %rhs, i16 *%src) { 155 ; CHECK-LABEL: f11: 156 ; CHECK: ch %r2, 0(%r3) 157 ; CHECK-NEXT: jh {{\.L.*}} 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