1; Test 64-bit ordered comparisons that are really between a memory halfword 2; and a constant. 3; 4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 5 6; Check unsigned comparison near the low end of the CLHHSI range, using zero 7; extension. 8define double @f1(double %a, double %b, i16 *%ptr) { 9; CHECK-LABEL: f1: 10; CHECK: clhhsi 0(%r2), 1 11; CHECK-NEXT: bhr %r14 12; CHECK: br %r14 13 %val = load i16 , i16 *%ptr 14 %ext = zext i16 %val to i64 15 %cond = icmp ugt i64 %ext, 1 16 %res = select i1 %cond, double %a, double %b 17 ret double %res 18} 19 20; Check unsigned comparison near the low end of the CLHHSI range, using sign 21; extension. 22define double @f2(double %a, double %b, i16 *%ptr) { 23; CHECK-LABEL: f2: 24; CHECK: clhhsi 0(%r2), 1 25; CHECK-NEXT: bhr %r14 26; CHECK: br %r14 27 %val = load i16 , i16 *%ptr 28 %ext = sext i16 %val to i64 29 %cond = icmp ugt i64 %ext, 1 30 %res = select i1 %cond, double %a, double %b 31 ret double %res 32} 33 34; Check unsigned comparison near the high end of the CLHHSI range, using zero 35; extension. 36define double @f3(double %a, double %b, i16 *%ptr) { 37; CHECK-LABEL: f3: 38; CHECK: clhhsi 0(%r2), 65534 39; CHECK-NEXT: blr %r14 40; CHECK: br %r14 41 %val = load i16 , i16 *%ptr 42 %ext = zext i16 %val to i64 43 %cond = icmp ult i64 %ext, 65534 44 %res = select i1 %cond, double %a, double %b 45 ret double %res 46} 47 48; Check unsigned comparison near the high end of the CLHHSI range, using sign 49; extension. 50define double @f4(double %a, double %b, i16 *%ptr) { 51; CHECK-LABEL: f4: 52; CHECK: clhhsi 0(%r2), 65534 53; CHECK-NEXT: blr %r14 54; CHECK: br %r14 55 %val = load i16 , i16 *%ptr 56 %ext = sext i16 %val to i64 57 %cond = icmp ult i64 %ext, -2 58 %res = select i1 %cond, double %a, double %b 59 ret double %res 60} 61 62; Check unsigned comparison above the high end of the CLHHSI range, using zero 63; extension. The condition is always true. 64define double @f5(double %a, double %b, i16 *%ptr) { 65; CHECK-LABEL: f5: 66; CHECK-NOT: clhhsi 67; CHECK: br %r14 68 %val = load i16 , i16 *%ptr 69 %ext = zext i16 %val to i64 70 %cond = icmp ult i64 %ext, 65536 71 %res = select i1 %cond, double %a, double %b 72 ret double %res 73} 74 75; When using unsigned comparison with sign extension, equality with values 76; in the range [32768, MAX-32769] is impossible, and ordered comparisons with 77; those values are effectively sign tests. Since such comparisons are 78; unlikely to occur in practice, we don't bother optimizing the second case, 79; and simply ignore CLHHSI for this range. First check the low end of the 80; range. 81define double @f6(double %a, double %b, i16 *%ptr) { 82; CHECK-LABEL: f6: 83; CHECK-NOT: clhhsi 84; CHECK: br %r14 85 %val = load i16 , i16 *%ptr 86 %ext = sext i16 %val to i64 87 %cond = icmp ult i64 %ext, 32768 88 %res = select i1 %cond, double %a, double %b 89 ret double %res 90} 91 92; ...and then the high end. 93define double @f7(double %a, double %b, i16 *%ptr) { 94; CHECK-LABEL: f7: 95; CHECK-NOT: clhhsi 96; CHECK: br %r14 97 %val = load i16 , i16 *%ptr 98 %ext = sext i16 %val to i64 99 %cond = icmp ult i64 %ext, -32769 100 %res = select i1 %cond, double %a, double %b 101 ret double %res 102} 103 104; Check signed comparison near the low end of the CLHHSI range, using zero 105; extension. This is equivalent to unsigned comparison. 106define double @f8(double %a, double %b, i16 *%ptr) { 107; CHECK-LABEL: f8: 108; CHECK: clhhsi 0(%r2), 1 109; CHECK-NEXT: bhr %r14 110; CHECK: br %r14 111 %val = load i16 , i16 *%ptr 112 %ext = zext i16 %val to i64 113 %cond = icmp sgt i64 %ext, 1 114 %res = select i1 %cond, double %a, double %b 115 ret double %res 116} 117 118; Check signed comparison near the low end of the CLHHSI range, using sign 119; extension. This should use CHHSI instead. 120define double @f9(double %a, double %b, i16 *%ptr) { 121; CHECK-LABEL: f9: 122; CHECK: chhsi 0(%r2), 1 123; CHECK-NEXT: bhr %r14 124; CHECK: br %r14 125 %val = load i16 , i16 *%ptr 126 %ext = sext i16 %val to i64 127 %cond = icmp sgt i64 %ext, 1 128 %res = select i1 %cond, double %a, double %b 129 ret double %res 130} 131 132; Check signed comparison near the high end of the CLHHSI range, using zero 133; extension. This is equivalent to unsigned comparison. 134define double @f10(double %a, double %b, i16 *%ptr) { 135; CHECK-LABEL: f10: 136; CHECK: clhhsi 0(%r2), 65534 137; CHECK-NEXT: blr %r14 138; CHECK: br %r14 139 %val = load i16 , i16 *%ptr 140 %ext = zext i16 %val to i64 141 %cond = icmp slt i64 %ext, 65534 142 %res = select i1 %cond, double %a, double %b 143 ret double %res 144} 145 146; Check signed comparison near the high end of the CLHHSI range, using sign 147; extension. This should use CHHSI instead. 148define double @f11(double %a, double %b, i16 *%ptr) { 149; CHECK-LABEL: f11: 150; CHECK: chhsi 0(%r2), -2 151; CHECK-NEXT: blr %r14 152; CHECK: br %r14 153 %val = load i16 , i16 *%ptr 154 %ext = sext i16 %val to i64 155 %cond = icmp slt i64 %ext, -2 156 %res = select i1 %cond, double %a, double %b 157 ret double %res 158} 159 160; Check signed comparison above the high end of the CLHHSI range, using zero 161; extension. The condition is always true. 162define double @f12(double %a, double %b, i16 *%ptr) { 163; CHECK-LABEL: f12: 164; CHECK-NOT: cli 165; CHECK: br %r14 166 %val = load i16 , i16 *%ptr 167 %ext = zext i16 %val to i64 168 %cond = icmp slt i64 %ext, 65536 169 %res = select i1 %cond, double %a, double %b 170 ret double %res 171} 172 173; Check signed comparison near the high end of the CHHSI range, using sign 174; extension. 175define double @f13(double %a, double %b, i16 *%ptr) { 176; CHECK-LABEL: f13: 177; CHECK: chhsi 0(%r2), 32766 178; CHECK-NEXT: blr %r14 179; CHECK: br %r14 180 %val = load i16 , i16 *%ptr 181 %ext = sext i16 %val to i64 182 %cond = icmp slt i64 %ext, 32766 183 %res = select i1 %cond, double %a, double %b 184 ret double %res 185} 186 187; Check signed comparison above the high end of the CHHSI range, using sign 188; extension. This condition is always true. 189define double @f14(double %a, double %b, i16 *%ptr) { 190; CHECK-LABEL: f14: 191; CHECK-NOT: chhsi 192; CHECK: br %r14 193 %val = load i16 , i16 *%ptr 194 %ext = sext i16 %val to i64 195 %cond = icmp slt i64 %ext, 32768 196 %res = select i1 %cond, double %a, double %b 197 ret double %res 198} 199 200; Check signed comparison near the low end of the CHHSI range, using sign 201; extension. 202define double @f15(double %a, double %b, i16 *%ptr) { 203; CHECK-LABEL: f15: 204; CHECK: chhsi 0(%r2), -32767 205; CHECK-NEXT: bhr %r14 206; CHECK: br %r14 207 %val = load i16 , i16 *%ptr 208 %ext = sext i16 %val to i64 209 %cond = icmp sgt i64 %ext, -32767 210 %res = select i1 %cond, double %a, double %b 211 ret double %res 212} 213 214; Check signed comparison below the low end of the CHHSI range, using sign 215; extension. This condition is always true. 216define double @f16(double %a, double %b, i16 *%ptr) { 217; CHECK-LABEL: f16: 218; CHECK-NOT: chhsi 219; CHECK: br %r14 220 %val = load i16 , i16 *%ptr 221 %ext = sext i16 %val to i64 222 %cond = icmp sgt i64 %ext, -32769 223 %res = select i1 %cond, double %a, double %b 224 ret double %res 225} 226