1; Test 64-bit comparison in which the second operand is a zero-extended i32. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5declare i64 @foo() 6 7; Check unsigned register comparison. 8define double @f1(double %a, double %b, i64 %i1, i32 %unext) { 9; CHECK-LABEL: f1: 10; CHECK: clgfr %r2, %r3 11; CHECK-NEXT: blr %r14 12; CHECK: ldr %f0, %f2 13; CHECK: br %r14 14 %i2 = zext i32 %unext to i64 15 %cond = icmp ult i64 %i1, %i2 16 %res = select i1 %cond, double %a, double %b 17 ret double %res 18} 19 20; ...and again with a different representation. 21define double @f2(double %a, double %b, i64 %i1, i64 %unext) { 22; CHECK-LABEL: f2: 23; CHECK: clgfr %r2, %r3 24; CHECK-NEXT: blr %r14 25; CHECK: ldr %f0, %f2 26; CHECK: br %r14 27 %i2 = and i64 %unext, 4294967295 28 %cond = icmp ult i64 %i1, %i2 29 %res = select i1 %cond, double %a, double %b 30 ret double %res 31} 32 33; Check signed register comparison, which can't use CLGFR. 34define double @f3(double %a, double %b, i64 %i1, i32 %unext) { 35; CHECK-LABEL: f3: 36; CHECK-NOT: clgfr 37; CHECK: br %r14 38 %i2 = zext i32 %unext to i64 39 %cond = icmp slt i64 %i1, %i2 40 %res = select i1 %cond, double %a, double %b 41 ret double %res 42} 43 44; ...and again with a different representation 45define double @f4(double %a, double %b, i64 %i1, i64 %unext) { 46; CHECK-LABEL: f4: 47; CHECK-NOT: clgfr 48; CHECK: br %r14 49 %i2 = and i64 %unext, 4294967295 50 %cond = icmp slt i64 %i1, %i2 51 %res = select i1 %cond, double %a, double %b 52 ret double %res 53} 54 55; Check register equality. 56define double @f5(double %a, double %b, i64 %i1, i32 %unext) { 57; CHECK-LABEL: f5: 58; CHECK: clgfr %r2, %r3 59; CHECK-NEXT: ber %r14 60; CHECK: ldr %f0, %f2 61; CHECK: br %r14 62 %i2 = zext i32 %unext to i64 63 %cond = icmp eq i64 %i1, %i2 64 %res = select i1 %cond, double %a, double %b 65 ret double %res 66} 67 68; ...and again with a different representation 69define double @f6(double %a, double %b, i64 %i1, i64 %unext) { 70; CHECK-LABEL: f6: 71; CHECK: clgfr %r2, %r3 72; CHECK-NEXT: ber %r14 73; CHECK: ldr %f0, %f2 74; CHECK: br %r14 75 %i2 = and i64 %unext, 4294967295 76 %cond = icmp eq i64 %i1, %i2 77 %res = select i1 %cond, double %a, double %b 78 ret double %res 79} 80 81; Check register inequality. 82define double @f7(double %a, double %b, i64 %i1, i32 %unext) { 83; CHECK-LABEL: f7: 84; CHECK: clgfr %r2, %r3 85; CHECK-NEXT: blhr %r14 86; CHECK: ldr %f0, %f2 87; CHECK: br %r14 88 %i2 = zext i32 %unext to i64 89 %cond = icmp ne i64 %i1, %i2 90 %res = select i1 %cond, double %a, double %b 91 ret double %res 92} 93 94; ...and again with a different representation 95define double @f8(double %a, double %b, i64 %i1, i64 %unext) { 96; CHECK-LABEL: f8: 97; CHECK: clgfr %r2, %r3 98; CHECK-NEXT: blhr %r14 99; CHECK: ldr %f0, %f2 100; CHECK: br %r14 101 %i2 = and i64 %unext, 4294967295 102 %cond = icmp ne i64 %i1, %i2 103 %res = select i1 %cond, double %a, double %b 104 ret double %res 105} 106 107; Check unsigned comparison with memory. 108define double @f9(double %a, double %b, i64 %i1, i32 *%ptr) { 109; CHECK-LABEL: f9: 110; CHECK: clgf %r2, 0(%r3) 111; CHECK-NEXT: blr %r14 112; CHECK: ldr %f0, %f2 113; CHECK: br %r14 114 %unext = load i32, i32 *%ptr 115 %i2 = zext i32 %unext to i64 116 %cond = icmp ult i64 %i1, %i2 117 %res = select i1 %cond, double %a, double %b 118 ret double %res 119} 120 121; Check signed comparison with memory. 122define double @f10(double %a, double %b, i64 %i1, i32 *%ptr) { 123; CHECK-LABEL: f10: 124; CHECK-NOT: clgf 125; CHECK: br %r14 126 %unext = load i32, i32 *%ptr 127 %i2 = zext i32 %unext to i64 128 %cond = icmp slt i64 %i1, %i2 129 %res = select i1 %cond, double %a, double %b 130 ret double %res 131} 132 133; Check memory equality. 134define double @f11(double %a, double %b, i64 %i1, i32 *%ptr) { 135; CHECK-LABEL: f11: 136; CHECK: clgf %r2, 0(%r3) 137; CHECK-NEXT: ber %r14 138; CHECK: ldr %f0, %f2 139; CHECK: br %r14 140 %unext = load i32, i32 *%ptr 141 %i2 = zext i32 %unext to i64 142 %cond = icmp eq i64 %i1, %i2 143 %res = select i1 %cond, double %a, double %b 144 ret double %res 145} 146 147; Check memory inequality. 148define double @f12(double %a, double %b, i64 %i1, i32 *%ptr) { 149; CHECK-LABEL: f12: 150; CHECK: clgf %r2, 0(%r3) 151; CHECK-NEXT: blhr %r14 152; CHECK: ldr %f0, %f2 153; CHECK: br %r14 154 %unext = load i32, i32 *%ptr 155 %i2 = zext i32 %unext to i64 156 %cond = icmp ne i64 %i1, %i2 157 %res = select i1 %cond, double %a, double %b 158 ret double %res 159} 160 161; Check the high end of the aligned CLGF range. 162define double @f13(double %a, double %b, i64 %i1, i32 *%base) { 163; CHECK-LABEL: f13: 164; CHECK: clgf %r2, 524284(%r3) 165; CHECK-NEXT: blr %r14 166; CHECK: ldr %f0, %f2 167; CHECK: br %r14 168 %ptr = getelementptr i32, i32 *%base, i64 131071 169 %unext = load i32, i32 *%ptr 170 %i2 = zext i32 %unext to i64 171 %cond = icmp ult i64 %i1, %i2 172 %res = select i1 %cond, double %a, double %b 173 ret double %res 174} 175 176; Check the next word up, which needs separate address logic. 177; Other sequences besides this one would be OK. 178define double @f14(double %a, double %b, i64 %i1, i32 *%base) { 179; CHECK-LABEL: f14: 180; CHECK: agfi %r3, 524288 181; CHECK: clgf %r2, 0(%r3) 182; CHECK-NEXT: blr %r14 183; CHECK: ldr %f0, %f2 184; CHECK: br %r14 185 %ptr = getelementptr i32, i32 *%base, i64 131072 186 %unext = load i32, i32 *%ptr 187 %i2 = zext i32 %unext to i64 188 %cond = icmp ult i64 %i1, %i2 189 %res = select i1 %cond, double %a, double %b 190 ret double %res 191} 192 193; Check the high end of the negative aligned CLGF range. 194define double @f15(double %a, double %b, i64 %i1, i32 *%base) { 195; CHECK-LABEL: f15: 196; CHECK: clgf %r2, -4(%r3) 197; CHECK-NEXT: blr %r14 198; CHECK: ldr %f0, %f2 199; CHECK: br %r14 200 %ptr = getelementptr i32, i32 *%base, i64 -1 201 %unext = load i32, i32 *%ptr 202 %i2 = zext i32 %unext to i64 203 %cond = icmp ult i64 %i1, %i2 204 %res = select i1 %cond, double %a, double %b 205 ret double %res 206} 207 208; Check the low end of the CLGF range. 209define double @f16(double %a, double %b, i64 %i1, i32 *%base) { 210; CHECK-LABEL: f16: 211; CHECK: clgf %r2, -524288(%r3) 212; CHECK-NEXT: blr %r14 213; CHECK: ldr %f0, %f2 214; CHECK: br %r14 215 %ptr = getelementptr i32, i32 *%base, i64 -131072 216 %unext = load i32, i32 *%ptr 217 %i2 = zext i32 %unext to i64 218 %cond = icmp ult i64 %i1, %i2 219 %res = select i1 %cond, double %a, double %b 220 ret double %res 221} 222 223; Check the next word down, which needs separate address logic. 224; Other sequences besides this one would be OK. 225define double @f17(double %a, double %b, i64 %i1, i32 *%base) { 226; CHECK-LABEL: f17: 227; CHECK: agfi %r3, -524292 228; CHECK: clgf %r2, 0(%r3) 229; CHECK-NEXT: blr %r14 230; CHECK: ldr %f0, %f2 231; CHECK: br %r14 232 %ptr = getelementptr i32, i32 *%base, i64 -131073 233 %unext = load i32, i32 *%ptr 234 %i2 = zext i32 %unext to i64 235 %cond = icmp ult i64 %i1, %i2 236 %res = select i1 %cond, double %a, double %b 237 ret double %res 238} 239 240; Check that CLGF allows an index. 241define double @f18(double %a, double %b, i64 %i1, i64 %base, i64 %index) { 242; CHECK-LABEL: f18: 243; CHECK: clgf %r2, 524284({{%r4,%r3|%r3,%r4}}) 244; CHECK-NEXT: blr %r14 245; CHECK: ldr %f0, %f2 246; CHECK: br %r14 247 %add1 = add i64 %base, %index 248 %add2 = add i64 %add1, 524284 249 %ptr = inttoptr i64 %add2 to i32 * 250 %unext = load i32, i32 *%ptr 251 %i2 = zext i32 %unext to i64 252 %cond = icmp ult i64 %i1, %i2 253 %res = select i1 %cond, double %a, double %b 254 ret double %res 255} 256 257; Check that comparisons of spilled values can use CLGF rather than CLGFR. 258define i64 @f19(i32 *%ptr0) { 259; CHECK-LABEL: f19: 260; CHECK: brasl %r14, foo@PLT 261; CHECK: clgf {{%r[0-9]+}}, 16{{[04]}}(%r15) 262; CHECK: br %r14 263 %ptr1 = getelementptr i32, i32 *%ptr0, i64 2 264 %ptr2 = getelementptr i32, i32 *%ptr0, i64 4 265 %ptr3 = getelementptr i32, i32 *%ptr0, i64 6 266 %ptr4 = getelementptr i32, i32 *%ptr0, i64 8 267 %ptr5 = getelementptr i32, i32 *%ptr0, i64 10 268 %ptr6 = getelementptr i32, i32 *%ptr0, i64 12 269 %ptr7 = getelementptr i32, i32 *%ptr0, i64 14 270 %ptr8 = getelementptr i32, i32 *%ptr0, i64 16 271 %ptr9 = getelementptr i32, i32 *%ptr0, i64 18 272 273 %val0 = load i32, i32 *%ptr0 274 %val1 = load i32, i32 *%ptr1 275 %val2 = load i32, i32 *%ptr2 276 %val3 = load i32, i32 *%ptr3 277 %val4 = load i32, i32 *%ptr4 278 %val5 = load i32, i32 *%ptr5 279 %val6 = load i32, i32 *%ptr6 280 %val7 = load i32, i32 *%ptr7 281 %val8 = load i32, i32 *%ptr8 282 %val9 = load i32, i32 *%ptr9 283 284 %frob0 = add i32 %val0, 100 285 %frob1 = add i32 %val1, 100 286 %frob2 = add i32 %val2, 100 287 %frob3 = add i32 %val3, 100 288 %frob4 = add i32 %val4, 100 289 %frob5 = add i32 %val5, 100 290 %frob6 = add i32 %val6, 100 291 %frob7 = add i32 %val7, 100 292 %frob8 = add i32 %val8, 100 293 %frob9 = add i32 %val9, 100 294 295 store i32 %frob0, i32 *%ptr0 296 store i32 %frob1, i32 *%ptr1 297 store i32 %frob2, i32 *%ptr2 298 store i32 %frob3, i32 *%ptr3 299 store i32 %frob4, i32 *%ptr4 300 store i32 %frob5, i32 *%ptr5 301 store i32 %frob6, i32 *%ptr6 302 store i32 %frob7, i32 *%ptr7 303 store i32 %frob8, i32 *%ptr8 304 store i32 %frob9, i32 *%ptr9 305 306 %ret = call i64 @foo() 307 308 %ext0 = zext i32 %frob0 to i64 309 %ext1 = zext i32 %frob1 to i64 310 %ext2 = zext i32 %frob2 to i64 311 %ext3 = zext i32 %frob3 to i64 312 %ext4 = zext i32 %frob4 to i64 313 %ext5 = zext i32 %frob5 to i64 314 %ext6 = zext i32 %frob6 to i64 315 %ext7 = zext i32 %frob7 to i64 316 %ext8 = zext i32 %frob8 to i64 317 %ext9 = zext i32 %frob9 to i64 318 319 %cmp0 = icmp ult i64 %ret, %ext0 320 %cmp1 = icmp ult i64 %ret, %ext1 321 %cmp2 = icmp ult i64 %ret, %ext2 322 %cmp3 = icmp ult i64 %ret, %ext3 323 %cmp4 = icmp ult i64 %ret, %ext4 324 %cmp5 = icmp ult i64 %ret, %ext5 325 %cmp6 = icmp ult i64 %ret, %ext6 326 %cmp7 = icmp ult i64 %ret, %ext7 327 %cmp8 = icmp ult i64 %ret, %ext8 328 %cmp9 = icmp ult i64 %ret, %ext9 329 330 %sel0 = select i1 %cmp0, i64 %ret, i64 0 331 %sel1 = select i1 %cmp1, i64 %sel0, i64 1 332 %sel2 = select i1 %cmp2, i64 %sel1, i64 2 333 %sel3 = select i1 %cmp3, i64 %sel2, i64 3 334 %sel4 = select i1 %cmp4, i64 %sel3, i64 4 335 %sel5 = select i1 %cmp5, i64 %sel4, i64 5 336 %sel6 = select i1 %cmp6, i64 %sel5, i64 6 337 %sel7 = select i1 %cmp7, i64 %sel6, i64 7 338 %sel8 = select i1 %cmp8, i64 %sel7, i64 8 339 %sel9 = select i1 %cmp9, i64 %sel8, i64 9 340 341 ret i64 %sel9 342} 343 344; Check the comparison can be reversed if that allows CLGFR to be used. 345define double @f20(double %a, double %b, i64 %i1, i32 %unext) { 346; CHECK-LABEL: f20: 347; CHECK: clgfr %r2, %r3 348; CHECK-NEXT: bhr %r14 349; CHECK: ldr %f0, %f2 350; CHECK: br %r14 351 %i2 = zext i32 %unext to i64 352 %cond = icmp ult i64 %i2, %i1 353 %res = select i1 %cond, double %a, double %b 354 ret double %res 355} 356 357; ...and again with the AND representation. 358define double @f21(double %a, double %b, i64 %i1, i64 %unext) { 359; CHECK-LABEL: f21: 360; CHECK: clgfr %r2, %r3 361; CHECK-NEXT: bhr %r14 362; CHECK: ldr %f0, %f2 363; CHECK: br %r14 364 %i2 = and i64 %unext, 4294967295 365 %cond = icmp ult i64 %i2, %i1 366 %res = select i1 %cond, double %a, double %b 367 ret double %res 368} 369 370; Check the comparison can be reversed if that allows CLGF to be used. 371define double @f22(double %a, double %b, i64 %i2, i32 *%ptr) { 372; CHECK-LABEL: f22: 373; CHECK: clgf %r2, 0(%r3) 374; CHECK-NEXT: bhr %r14 375; CHECK: ldr %f0, %f2 376; CHECK: br %r14 377 %unext = load i32, i32 *%ptr 378 %i1 = zext i32 %unext to i64 379 %cond = icmp ult i64 %i1, %i2 380 %res = select i1 %cond, double %a, double %b 381 ret double %res 382} 383