@@ -423,6 +423,86 @@ define i8 @scmp_from_select_eq_and_gt_commuted3(i32 %x, i32 %y) {
423423 ret i8 %r
424424}
425425
426+ ; Commutative tests for (x != y) ? (x > y ? 1 : -1) : 0
427+ define i8 @scmp_from_select_ne_and_gt_commuted1 (i32 %x , i32 %y ) {
428+ ; CHECK-LABEL: define i8 @scmp_from_select_ne_and_gt_commuted1(
429+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
430+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
431+ ; CHECK-NEXT: ret i8 [[R]]
432+ ;
433+ %ne = icmp ne i32 %x , %y
434+ %gt = icmp slt i32 %x , %y
435+ %sel1 = select i1 %gt , i8 1 , i8 -1
436+ %r = select i1 %ne , i8 %sel1 , i8 0
437+ ret i8 %r
438+ }
439+
440+ define i8 @scmp_from_select_ne_and_gt_commuted2 (i32 %x , i32 %y ) {
441+ ; CHECK-LABEL: define i8 @scmp_from_select_ne_and_gt_commuted2(
442+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
443+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
444+ ; CHECK-NEXT: ret i8 [[R]]
445+ ;
446+ %ne = icmp ne i32 %x , %y
447+ %gt = icmp sgt i32 %x , %y
448+ %sel1 = select i1 %gt , i8 -1 , i8 1
449+ %r = select i1 %ne , i8 %sel1 , i8 0
450+ ret i8 %r
451+ }
452+
453+ define i8 @scmp_from_select_ne_and_gt_commuted3 (i32 %x , i32 %y ) {
454+ ; CHECK-LABEL: define i8 @scmp_from_select_ne_and_gt_commuted3(
455+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
456+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
457+ ; CHECK-NEXT: ret i8 [[R]]
458+ ;
459+ %ne = icmp ne i32 %x , %y
460+ %gt = icmp sgt i32 %x , %y
461+ %sel1 = select i1 %gt , i8 1 , i8 -1
462+ %r = select i1 %ne , i8 %sel1 , i8 0
463+ ret i8 %r
464+ }
465+
466+ ; Commutative tests for x != C ? (x > C - 1 ? 1 : -1) : 0
467+ define i8 @scmp_from_select_ne_const_and_gt_commuted1 (i32 %x ) {
468+ ; CHECK-LABEL: define i8 @scmp_from_select_ne_const_and_gt_commuted1(
469+ ; CHECK-SAME: i32 [[X:%.*]]) {
470+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 5)
471+ ; CHECK-NEXT: ret i8 [[R]]
472+ ;
473+ %ne = icmp ne i32 %x , 5
474+ %gt = icmp sgt i32 %x , 4
475+ %sel1 = select i1 %gt , i8 1 , i8 -1
476+ %r = select i1 %ne , i8 %sel1 , i8 0
477+ ret i8 %r
478+ }
479+
480+ define i8 @scmp_from_select_ne_const_and_gt_commuted2 (i32 %x ) {
481+ ; CHECK-LABEL: define i8 @scmp_from_select_ne_const_and_gt_commuted2(
482+ ; CHECK-SAME: i32 [[X:%.*]]) {
483+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 5)
484+ ; CHECK-NEXT: ret i8 [[R]]
485+ ;
486+ %ne = icmp ne i32 %x , 5
487+ %gt = icmp sgt i32 %x , 4
488+ %sel1 = select i1 %gt , i8 1 , i8 -1
489+ %r = select i1 %ne , i8 %sel1 , i8 0
490+ ret i8 %r
491+ }
492+
493+ define i8 @scmp_from_select_ne_const_and_gt_commuted3 (i32 %x ) {
494+ ; CHECK-LABEL: define i8 @scmp_from_select_ne_const_and_gt_commuted3(
495+ ; CHECK-SAME: i32 [[X:%.*]]) {
496+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 5)
497+ ; CHECK-NEXT: ret i8 [[R]]
498+ ;
499+ %ne = icmp ne i32 %x , 5
500+ %gt = icmp sgt i32 %x , 4
501+ %sel1 = select i1 %gt , i8 1 , i8 -1
502+ %r = select i1 %ne , i8 %sel1 , i8 0
503+ ret i8 %r
504+ }
505+
426506define <3 x i2 > @scmp_unary_shuffle_ops (<3 x i8 > %x , <3 x i8 > %y ) {
427507; CHECK-LABEL: define <3 x i2> @scmp_unary_shuffle_ops(
428508; CHECK-SAME: <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]) {
@@ -436,6 +516,187 @@ define <3 x i2> @scmp_unary_shuffle_ops(<3 x i8> %x, <3 x i8> %y) {
436516 ret <3 x i2 > %r
437517}
438518
519+ define i32 @scmp_sgt_slt (i32 %a ) {
520+ ; CHECK-LABEL: define i32 @scmp_sgt_slt(
521+ ; CHECK-SAME: i32 [[A:%.*]]) {
522+ ; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i32 [[A]], 31
523+ ; CHECK-NEXT: [[CMP_INV:%.*]] = icmp slt i32 [[A]], 1
524+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP_INV]], i32 [[A_LOBIT]], i32 1
525+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
526+ ;
527+ %cmp = icmp sgt i32 %a , 0
528+ %cmp1 = icmp slt i32 %a , 0
529+ %. = select i1 %cmp1 , i32 -1 , i32 0
530+ %retval.0 = select i1 %cmp , i32 1 , i32 %.
531+ ret i32 %retval.0
532+ }
533+
534+ define i32 @scmp_zero_slt (i32 %a ) {
535+ ; CHECK-LABEL: define i32 @scmp_zero_slt(
536+ ; CHECK-SAME: i32 [[A:%.*]]) {
537+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)
538+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
539+ ;
540+ %cmp = icmp eq i32 %a , 0
541+ %cmp1.inv = icmp slt i32 %a , 1
542+ %. = select i1 %cmp1.inv , i32 -1 , i32 1
543+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
544+ ret i32 %retval.0
545+ }
546+
547+ define i32 @scmp_zero_sgt (i32 %a ) {
548+ ; CHECK-LABEL: define i32 @scmp_zero_sgt(
549+ ; CHECK-SAME: i32 [[A:%.*]]) {
550+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)
551+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
552+ ;
553+ %cmp = icmp eq i32 %a , 0
554+ %cmp1.inv = icmp sgt i32 %a , -1
555+ %. = select i1 %cmp1.inv , i32 1 , i32 -1
556+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
557+ ret i32 %retval.0
558+ }
559+
560+
561+ define i32 @scmp_zero_sgt_1 (i32 %a ) {
562+ ; CHECK-LABEL: define i32 @scmp_zero_sgt_1(
563+ ; CHECK-SAME: i32 [[A:%.*]]) {
564+ ; CHECK-NEXT: [[COND2:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)
565+ ; CHECK-NEXT: ret i32 [[COND2]]
566+ ;
567+ %cmp = icmp eq i32 %a , 0
568+ %cmp1 = icmp sgt i32 %a , -1
569+ %cond = select i1 %cmp1 , i32 1 , i32 -1
570+ %cond2 = select i1 %cmp , i32 0 , i32 %cond
571+ ret i32 %cond2
572+ }
573+
574+ define i32 @scmp_zero_slt_1 (i32 %a ) {
575+ ; CHECK-LABEL: define i32 @scmp_zero_slt_1(
576+ ; CHECK-SAME: i32 [[A:%.*]]) {
577+ ; CHECK-NEXT: [[COND2:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)
578+ ; CHECK-NEXT: ret i32 [[COND2]]
579+ ;
580+ %cmp = icmp eq i32 %a , 0
581+ %cmp1 = icmp slt i32 %a , 1
582+ %cond = select i1 %cmp1 , i32 -1 , i32 1
583+ %cond2 = select i1 %cmp , i32 0 , i32 %cond
584+ ret i32 %cond2
585+ }
586+
587+ define i32 @scmp_zero_slt_neg (i32 %a ) {
588+ ; CHECK-LABEL: define i32 @scmp_zero_slt_neg(
589+ ; CHECK-SAME: i32 [[A:%.*]]) {
590+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
591+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -1
592+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], i32 -1, i32 1
593+ ; CHECK-NEXT: [[COND2:%.*]] = select i1 [[CMP]], i32 0, i32 [[COND]]
594+ ; CHECK-NEXT: ret i32 [[COND2]]
595+ ;
596+ %cmp = icmp eq i32 %a , 0
597+ %cmp1 = icmp slt i32 %a , -1
598+ %cond = select i1 %cmp1 , i32 -1 , i32 1
599+ %cond2 = select i1 %cmp , i32 0 , i32 %cond
600+ ret i32 %cond2
601+ }
602+
603+ define i32 @scmp_zero_sgt_neg (i32 %a ) {
604+ ; CHECK-LABEL: define i32 @scmp_zero_sgt_neg(
605+ ; CHECK-SAME: i32 [[A:%.*]]) {
606+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
607+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], 1
608+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], i32 1, i32 -1
609+ ; CHECK-NEXT: [[COND2:%.*]] = select i1 [[CMP]], i32 0, i32 [[COND]]
610+ ; CHECK-NEXT: ret i32 [[COND2]]
611+ ;
612+ %cmp = icmp eq i32 %a , 0
613+ %cmp1 = icmp sgt i32 %a , 1
614+ %cond = select i1 %cmp1 , i32 1 , i32 -1
615+ %cond2 = select i1 %cmp , i32 0 , i32 %cond
616+ ret i32 %cond2
617+ }
618+
619+ define i32 @ucmp_ugt_ult_neg (i32 %a ) {
620+ ; CHECK-LABEL: define i32 @ucmp_ugt_ult_neg(
621+ ; CHECK-SAME: i32 [[A:%.*]]) {
622+ ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ne i32 [[A]], 0
623+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = zext i1 [[CMP_NOT]] to i32
624+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
625+ ;
626+ %cmp = icmp ugt i32 %a , 0
627+ %cmp1 = icmp ult i32 %a , 0
628+ %. = select i1 %cmp1 , i32 -1 , i32 0
629+ %retval.0 = select i1 %cmp , i32 1 , i32 %.
630+ ret i32 %retval.0
631+ }
632+
633+ define i32 @ucmp_zero_ult_neg (i32 %a ) {
634+ ; CHECK-LABEL: define i32 @ucmp_zero_ult_neg(
635+ ; CHECK-SAME: i32 [[A:%.*]]) {
636+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A]], 0
637+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = zext i1 [[CMP]] to i32
638+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
639+ ;
640+ %cmp = icmp eq i32 %a , 0
641+ %cmp1.inv = icmp ult i32 %a , 1
642+ %. = select i1 %cmp1.inv , i32 -1 , i32 1
643+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
644+ ret i32 %retval.0
645+ }
646+
647+ define i32 @ucmp_zero_ugt_neg (i32 %a ) {
648+ ; CHECK-LABEL: define i32 @ucmp_zero_ugt_neg(
649+ ; CHECK-SAME: i32 [[A:%.*]]) {
650+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A]], 0
651+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = sext i1 [[CMP]] to i32
652+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
653+ ;
654+ %cmp = icmp eq i32 %a , 0
655+ %cmp1.inv = icmp ugt i32 %a , -1
656+ %. = select i1 %cmp1.inv , i32 1 , i32 -1
657+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
658+ ret i32 %retval.0
659+ }
660+
661+ define i32 @scmp_sgt_slt_ab (i32 %a , i32 %b ) {
662+ ; CHECK-LABEL: define i32 @scmp_sgt_slt_ab(
663+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
664+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])
665+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
666+ ;
667+ %cmp = icmp sgt i32 %a , %b
668+ %cmp1 = icmp slt i32 %a , %b
669+ %. = select i1 %cmp1 , i32 -1 , i32 0
670+ %retval.0 = select i1 %cmp , i32 1 , i32 %.
671+ ret i32 %retval.0
672+ }
673+
674+ define i32 @scmp_zero_slt_ab (i32 %a , i32 %b ) {
675+ ; CHECK-LABEL: define i32 @scmp_zero_slt_ab(
676+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
677+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])
678+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
679+ ;
680+ %cmp = icmp eq i32 %a , %b
681+ %cmp1.inv = icmp slt i32 %a , %b
682+ %. = select i1 %cmp1.inv , i32 -1 , i32 1
683+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
684+ ret i32 %retval.0
685+ }
686+
687+ define i32 @scmp_zero_sgt_ab (i32 %a , i32 %b ) {
688+ ; CHECK-LABEL: define i32 @scmp_zero_sgt_ab(
689+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
690+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])
691+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
692+ ;
693+ %cmp = icmp eq i32 %a , %b
694+ %cmp1.inv = icmp sgt i32 %a , %b
695+ %. = select i1 %cmp1.inv , i32 1 , i32 -1
696+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
697+ ret i32 %retval.0
698+ }
699+
439700; Negative test: true value of outer select is not zero
440701define i8 @scmp_from_select_eq_and_gt_neg1 (i32 %x , i32 %y ) {
441702; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg1(
0 commit comments