1 ; Test 64-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. 8 define double @f1(double %a, double %b, i8 *%ptr) { 9 ; CHECK-LABEL: f1: 10 ; CHECK: cli 0(%r2), 1 11 ; CHECK-NEXT: jh 12 ; CHECK: br %r14 13 %val = load i8 *%ptr 14 %ext = zext i8 %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 CLI range, using sign 21 ; extension. 22 define double @f2(double %a, double %b, i8 *%ptr) { 23 ; CHECK-LABEL: f2: 24 ; CHECK: cli 0(%r2), 1 25 ; CHECK-NEXT: jh 26 ; CHECK: br %r14 27 %val = load i8 *%ptr 28 %ext = sext i8 %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 CLI range, using zero 35 ; extension. 36 define double @f3(double %a, double %b, i8 *%ptr) { 37 ; CHECK-LABEL: f3: 38 ; CHECK: cli 0(%r2), 254 39 ; CHECK-NEXT: jl 40 ; CHECK: br %r14 41 %val = load i8 *%ptr 42 %ext = zext i8 %val to i64 43 %cond = icmp ult i64 %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. 50 define double @f4(double %a, double %b, i8 *%ptr) { 51 ; CHECK-LABEL: f4: 52 ; CHECK: cli 0(%r2), 254 53 ; CHECK-NEXT: jl 54 ; CHECK: br %r14 55 %val = load i8 *%ptr 56 %ext = sext i8 %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 CLI range, using zero 63 ; extension. The condition is always true. 64 define double @f5(double %a, double %b, i8 *%ptr) { 65 ; CHECK-LABEL: f5: 66 ; CHECK-NOT: cli 67 ; CHECK: br %r14 68 %val = load i8 *%ptr 69 %ext = zext i8 %val to i64 70 %cond = icmp ult i64 %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. 80 define double @f6(double %a, double %b, i8 *%ptr) { 81 ; CHECK-LABEL: f6: 82 ; CHECK-NOT: cli 83 ; CHECK: br %r14 84 %val = load i8 *%ptr 85 %ext = sext i8 %val to i64 86 %cond = icmp ult i64 %ext, 128 87 %res = select i1 %cond, double %a, double %b 88 ret double %res 89 } 90 91 ; ...and then the high end. 92 define double @f7(double %a, double %b, i8 *%ptr) { 93 ; CHECK-LABEL: f7: 94 ; CHECK-NOT: cli 95 ; CHECK: br %r14 96 %val = load i8 *%ptr 97 %ext = sext i8 %val to i64 98 %cond = icmp ult i64 %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. 105 define double @f8(double %a, double %b, i8 *%ptr) { 106 ; CHECK-LABEL: f8: 107 ; CHECK: cli 0(%r2), 1 108 ; CHECK-NEXT: jh 109 ; CHECK: br %r14 110 %val = load i8 *%ptr 111 %ext = zext i8 %val to i64 112 %cond = icmp sgt i64 %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. 119 define double @f9(double %a, double %b, i8 *%ptr) { 120 ; CHECK-LABEL: f9: 121 ; CHECK-NOT: cli 122 ; CHECK: br %r14 123 %val = load i8 *%ptr 124 %ext = sext i8 %val to i64 125 %cond = icmp sgt i64 %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. 132 define double @f10(double %a, double %b, i8 *%ptr) { 133 ; CHECK-LABEL: f10: 134 ; CHECK: cli 0(%r2), 254 135 ; CHECK-NEXT: jl 136 ; CHECK: br %r14 137 %val = load i8 *%ptr 138 %ext = zext i8 %val to i64 139 %cond = icmp slt i64 %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. 146 define double @f11(double %a, double %b, i8 *%ptr) { 147 ; CHECK-LABEL: f11: 148 ; CHECK-NOT: cli 149 ; CHECK: br %r14 150 %val = load i8 *%ptr 151 %ext = sext i8 %val to i64 152 %cond = icmp slt i64 %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. 159 define double @f12(double %a, double %b, i8 *%ptr) { 160 ; CHECK-LABEL: f12: 161 ; CHECK-NOT: cli 162 ; CHECK: br %r14 163 %val = load i8 *%ptr 164 %ext = zext i8 %val to i64 165 %cond = icmp slt i64 %ext, 256 166 %res = select i1 %cond, double %a, double %b 167 ret double %res 168 } 169 170 ; Check tests for nonnegative values. 171 define double @f13(double %a, double %b, i8 *%ptr) { 172 ; CHECK-LABEL: f13: 173 ; CHECK: cli 0(%r2), 128 174 ; CHECK-NEXT: jl 175 ; CHECK: br %r14 176 %val = load i8 *%ptr 177 %ext = sext i8 %val to i64 178 %cond = icmp sge i64 %ext, 0 179 %res = select i1 %cond, double %a, double %b 180 ret double %res 181 } 182 183 ; ...and another form 184 define double @f14(double %a, double %b, i8 *%ptr) { 185 ; CHECK-LABEL: f14: 186 ; CHECK: cli 0(%r2), 128 187 ; CHECK-NEXT: jl 188 ; CHECK: br %r14 189 %val = load i8 *%ptr 190 %ext = sext i8 %val to i64 191 %cond = icmp sgt i64 %ext, -1 192 %res = select i1 %cond, double %a, double %b 193 ret double %res 194 } 195 196 ; Check tests for negative values. 197 define double @f15(double %a, double %b, i8 *%ptr) { 198 ; CHECK-LABEL: f15: 199 ; CHECK: cli 0(%r2), 127 200 ; CHECK-NEXT: jh 201 ; CHECK: br %r14 202 %val = load i8 *%ptr 203 %ext = sext i8 %val to i64 204 %cond = icmp slt i64 %ext, 0 205 %res = select i1 %cond, double %a, double %b 206 ret double %res 207 } 208 209 ; ...and another form 210 define double @f16(double %a, double %b, i8 *%ptr) { 211 ; CHECK-LABEL: f16: 212 ; CHECK: cli 0(%r2), 127 213 ; CHECK-NEXT: jh 214 ; CHECK: br %r14 215 %val = load i8 *%ptr 216 %ext = sext i8 %val to i64 217 %cond = icmp sle i64 %ext, -1 218 %res = select i1 %cond, double %a, double %b 219 ret double %res 220 } 221