1; Test 32-bit ordered comparisons that are really between a memory byte 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 CLI range, using zero 7; extension. 8define double @f1(double %a, double %b, i8 *%ptr) { 9; CHECK-LABEL: f1: 10; CHECK: cli 0(%r2), 1 11; CHECK-NEXT: bhr %r14 12; CHECK: br %r14 13 %val = load i8, i8 *%ptr 14 %ext = zext i8 %val to i32 15 %cond = icmp ugt i32 %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 CLI range, using sign 21; extension. 22define double @f2(double %a, double %b, i8 *%ptr) { 23; CHECK-LABEL: f2: 24; CHECK: cli 0(%r2), 1 25; CHECK-NEXT: bhr %r14 26; CHECK: br %r14 27 %val = load i8, i8 *%ptr 28 %ext = sext i8 %val to i32 29 %cond = icmp ugt i32 %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 CLI range, using zero 35; extension. 36define double @f3(double %a, double %b, i8 *%ptr) { 37; CHECK-LABEL: f3: 38; CHECK: cli 0(%r2), 254 39; CHECK-NEXT: blr %r14 40; CHECK: br %r14 41 %val = load i8, i8 *%ptr 42 %ext = zext i8 %val to i32 43 %cond = icmp ult i32 %ext, 254 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 CLI range, using sign 49; extension. 50define double @f4(double %a, double %b, i8 *%ptr) { 51; CHECK-LABEL: f4: 52; CHECK: cli 0(%r2), 254 53; CHECK-NEXT: blr %r14 54; CHECK: br %r14 55 %val = load i8, i8 *%ptr 56 %ext = sext i8 %val to i32 57 %cond = icmp ult i32 %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 CLI range, using zero 63; extension. The condition is always true. 64define double @f5(double %a, double %b, i8 *%ptr) { 65; CHECK-LABEL: f5: 66; CHECK-NOT: cli {{.*}} 67; CHECK: br %r14 68 %val = load i8, i8 *%ptr 69 %ext = zext i8 %val to i32 70 %cond = icmp ult i32 %ext, 256 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 [128, MAX-129] 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 CLI for this range. First check the low end of the range. 80define double @f6(double %a, double %b, i8 *%ptr) { 81; CHECK-LABEL: f6: 82; CHECK-NOT: cli {{.*}} 83; CHECK: br %r14 84 %val = load i8, i8 *%ptr 85 %ext = sext i8 %val to i32 86 %cond = icmp ult i32 %ext, 128 87 %res = select i1 %cond, double %a, double %b 88 ret double %res 89} 90 91; ...and then the high end. 92define double @f7(double %a, double %b, i8 *%ptr) { 93; CHECK-LABEL: f7: 94; CHECK-NOT: cli {{.*}} 95; CHECK: br %r14 96 %val = load i8, i8 *%ptr 97 %ext = sext i8 %val to i32 98 %cond = icmp ult i32 %ext, -129 99 %res = select i1 %cond, double %a, double %b 100 ret double %res 101} 102 103; Check signed comparison near the low end of the CLI range, using zero 104; extension. This is equivalent to unsigned comparison. 105define double @f8(double %a, double %b, i8 *%ptr) { 106; CHECK-LABEL: f8: 107; CHECK: cli 0(%r2), 1 108; CHECK-NEXT: bhr %r14 109; CHECK: br %r14 110 %val = load i8, i8 *%ptr 111 %ext = zext i8 %val to i32 112 %cond = icmp sgt i32 %ext, 1 113 %res = select i1 %cond, double %a, double %b 114 ret double %res 115} 116 117; Check signed comparison near the low end of the CLI range, using sign 118; extension. This cannot use CLI. 119define double @f9(double %a, double %b, i8 *%ptr) { 120; CHECK-LABEL: f9: 121; CHECK-NOT: cli {{.*}} 122; CHECK: br %r14 123 %val = load i8, i8 *%ptr 124 %ext = sext i8 %val to i32 125 %cond = icmp sgt i32 %ext, 1 126 %res = select i1 %cond, double %a, double %b 127 ret double %res 128} 129 130; Check signed comparison near the high end of the CLI range, using zero 131; extension. This is equivalent to unsigned comparison. 132define double @f10(double %a, double %b, i8 *%ptr) { 133; CHECK-LABEL: f10: 134; CHECK: cli 0(%r2), 254 135; CHECK-NEXT: blr %r14 136; CHECK: br %r14 137 %val = load i8, i8 *%ptr 138 %ext = zext i8 %val to i32 139 %cond = icmp slt i32 %ext, 254 140 %res = select i1 %cond, double %a, double %b 141 ret double %res 142} 143 144; Check signed comparison near the high end of the CLI range, using sign 145; extension. This cannot use CLI. 146define double @f11(double %a, double %b, i8 *%ptr) { 147; CHECK-LABEL: f11: 148; CHECK-NOT: cli {{.*}} 149; CHECK: br %r14 150 %val = load i8, i8 *%ptr 151 %ext = sext i8 %val to i32 152 %cond = icmp slt i32 %ext, -2 153 %res = select i1 %cond, double %a, double %b 154 ret double %res 155} 156 157; Check signed comparison above the high end of the CLI range, using zero 158; extension. The condition is always true. 159define double @f12(double %a, double %b, i8 *%ptr) { 160; CHECK-LABEL: f12: 161; CHECK-NOT: cli {{.*}} 162; CHECK: br %r14 163 %val = load i8, i8 *%ptr 164 %ext = zext i8 %val to i32 165 %cond = icmp slt i32 %ext, 256 166 %res = select i1 %cond, double %a, double %b 167 ret double %res 168} 169 170; Check tests for nonnegative values. 171define double @f13(double %a, double %b, i8 *%ptr) { 172; CHECK-LABEL: f13: 173; CHECK: cli 0(%r2), 128 174; CHECK-NEXT: blr %r14 175; CHECK: br %r14 176 %val = load i8, i8 *%ptr 177 %ext = sext i8 %val to i32 178 %cond = icmp sge i32 %ext, 0 179 %res = select i1 %cond, double %a, double %b 180 ret double %res 181} 182 183; ...and another form 184define double @f14(double %a, double %b, i8 *%ptr) { 185; CHECK-LABEL: f14: 186; CHECK: cli 0(%r2), 128 187; CHECK-NEXT: blr %r14 188; CHECK: br %r14 189 %val = load i8, i8 *%ptr 190 %ext = sext i8 %val to i32 191 %cond = icmp sgt i32 %ext, -1 192 %res = select i1 %cond, double %a, double %b 193 ret double %res 194} 195 196; Check tests for negative values. 197define double @f15(double %a, double %b, i8 *%ptr) { 198; CHECK-LABEL: f15: 199; CHECK: cli 0(%r2), 127 200; CHECK-NEXT: bhr %r14 201; CHECK: br %r14 202 %val = load i8, i8 *%ptr 203 %ext = sext i8 %val to i32 204 %cond = icmp slt i32 %ext, 0 205 %res = select i1 %cond, double %a, double %b 206 ret double %res 207} 208 209; ...and another form 210define double @f16(double %a, double %b, i8 *%ptr) { 211; CHECK-LABEL: f16: 212; CHECK: cli 0(%r2), 127 213; CHECK-NEXT: bhr %r14 214; CHECK: br %r14 215 %val = load i8, i8 *%ptr 216 %ext = sext i8 %val to i32 217 %cond = icmp sle i32 %ext, -1 218 %res = select i1 %cond, double %a, double %b 219 ret double %res 220} 221