@@ -343,3 +343,133 @@ define i8 @scmp_from_select_gt_and_lt(i32 %x, i32 %y) {
343
343
%r = select i1 %gt , i8 1 , i8 %lt
344
344
ret i8 %r
345
345
}
346
+
347
+ ; (x == y) ? 0 : (x s> y ? 1 : -1) into scmp(x, y)
348
+ define i8 @scmp_from_select_eq_and_gt (i32 %x , i32 %y ) {
349
+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(
350
+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
351
+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
352
+ ; CHECK-NEXT: ret i8 [[R]]
353
+ ;
354
+ %eq = icmp eq i32 %x , %y
355
+ %gt = icmp sgt i32 %x , %y
356
+ %sel1 = select i1 %gt , i8 1 , i8 -1
357
+ %r = select i1 %eq , i8 0 , i8 %sel1
358
+ ret i8 %r
359
+ }
360
+
361
+ define i8 @scmp_from_select_eq_and_gt_inverse (i32 %x , i32 %y ) {
362
+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_inverse(
363
+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
364
+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
365
+ ; CHECK-NEXT: ret i8 [[R]]
366
+ ;
367
+ %ne = icmp ne i32 %x , %y
368
+ %gt = icmp sgt i32 %x , %y
369
+ %sel1 = select i1 %gt , i8 1 , i8 -1
370
+ %r = select i1 %ne , i8 %sel1 , i8 0
371
+ ret i8 %r
372
+ }
373
+
374
+ define <4 x i8 > @scmp_from_select_eq_and_gt_vec (<4 x i32 > %x , <4 x i32 > %y ) {
375
+ ; CHECK-LABEL: define <4 x i8> @scmp_from_select_eq_and_gt_vec(
376
+ ; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
377
+ ; CHECK-NEXT: [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])
378
+ ; CHECK-NEXT: ret <4 x i8> [[R]]
379
+ ;
380
+ %eq = icmp eq <4 x i32 > %x , %y
381
+ %gt = icmp sgt <4 x i32 > %x , %y
382
+ %sel1 = select <4 x i1 > %gt , <4 x i8 > splat(i8 1 ), <4 x i8 > splat(i8 -1 )
383
+ %r = select <4 x i1 > %eq , <4 x i8 > splat(i8 0 ), <4 x i8 > %sel1
384
+ ret <4 x i8 > %r
385
+ }
386
+
387
+ define i8 @scmp_from_select_eq_and_gt_commuted1 (i32 %x , i32 %y ) {
388
+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted1(
389
+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
390
+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
391
+ ; CHECK-NEXT: ret i8 [[R]]
392
+ ;
393
+ %eq = icmp eq i32 %x , %y
394
+ %gt = icmp slt i32 %x , %y
395
+ %sel1 = select i1 %gt , i8 1 , i8 -1
396
+ %r = select i1 %eq , i8 0 , i8 %sel1
397
+ ret i8 %r
398
+ }
399
+
400
+ define i8 @scmp_from_select_eq_and_gt_commuted2 (i32 %x , i32 %y ) {
401
+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted2(
402
+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
403
+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
404
+ ; CHECK-NEXT: ret i8 [[R]]
405
+ ;
406
+ %eq = icmp eq i32 %x , %y
407
+ %gt = icmp sgt i32 %x , %y
408
+ %sel1 = select i1 %gt , i8 -1 , i8 1
409
+ %r = select i1 %eq , i8 0 , i8 %sel1
410
+ ret i8 %r
411
+ }
412
+
413
+ define i8 @scmp_from_select_eq_and_gt_commuted3 (i32 %x , i32 %y ) {
414
+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted3(
415
+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
416
+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
417
+ ; CHECK-NEXT: ret i8 [[R]]
418
+ ;
419
+ %eq = icmp eq i32 %x , %y
420
+ %gt = icmp slt i32 %x , %y
421
+ %sel1 = select i1 %gt , i8 -1 , i8 1
422
+ %r = select i1 %eq , i8 0 , i8 %sel1
423
+ ret i8 %r
424
+ }
425
+
426
+ ; Negative test: true value of outer select is not zero
427
+ define i8 @scmp_from_select_eq_and_gt_neg1 (i32 %x , i32 %y ) {
428
+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg1(
429
+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
430
+ ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
431
+ ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
432
+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
433
+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 5, i8 [[SEL1]]
434
+ ; CHECK-NEXT: ret i8 [[R]]
435
+ ;
436
+ %eq = icmp eq i32 %x , %y
437
+ %gt = icmp sgt i32 %x , %y
438
+ %sel1 = select i1 %gt , i8 1 , i8 -1
439
+ %r = select i1 %eq , i8 5 , i8 %sel1
440
+ ret i8 %r
441
+ }
442
+
443
+ ; Negative test: true value of inner select is not 1 or -1
444
+ define i8 @scmp_from_select_eq_and_gt_neg2 (i32 %x , i32 %y ) {
445
+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg2(
446
+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
447
+ ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
448
+ ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
449
+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 2, i8 -1
450
+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
451
+ ; CHECK-NEXT: ret i8 [[R]]
452
+ ;
453
+ %eq = icmp eq i32 %x , %y
454
+ %gt = icmp sgt i32 %x , %y
455
+ %sel1 = select i1 %gt , i8 2 , i8 -1
456
+ %r = select i1 %eq , i8 0 , i8 %sel1
457
+ ret i8 %r
458
+ }
459
+
460
+ ; Negative test: false value of inner select is not 1 or -1
461
+ define i8 @scmp_from_select_eq_and_gt_neg3 (i32 %x , i32 %y ) {
462
+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg3(
463
+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
464
+ ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
465
+ ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
466
+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 22
467
+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
468
+ ; CHECK-NEXT: ret i8 [[R]]
469
+ ;
470
+ %eq = icmp eq i32 %x , %y
471
+ %gt = icmp sgt i32 %x , %y
472
+ %sel1 = select i1 %gt , i8 1 , i8 22
473
+ %r = select i1 %eq , i8 0 , i8 %sel1
474
+ ret i8 %r
475
+ }
0 commit comments