@@ -423,6 +423,95 @@ 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 slt 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: [[NE_NOT:%.*]] = icmp eq i32 [[X]], 5
471+ ; CHECK-NEXT: [[GT:%.*]] = icmp slt i32 [[X]], 4
472+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
473+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[NE_NOT]], i8 0, i8 [[SEL1]]
474+ ; CHECK-NEXT: ret i8 [[R]]
475+ ;
476+ %ne = icmp ne i32 %x , 5
477+ %gt = icmp slt i32 %x , 4
478+ %sel1 = select i1 %gt , i8 1 , i8 -1
479+ %r = select i1 %ne , i8 %sel1 , i8 0
480+ ret i8 %r
481+ }
482+
483+ define i8 @scmp_from_select_ne_const_and_gt_commuted2 (i32 %x ) {
484+ ; CHECK-LABEL: define i8 @scmp_from_select_ne_const_and_gt_commuted2(
485+ ; CHECK-SAME: i32 [[X:%.*]]) {
486+ ; CHECK-NEXT: [[NE_NOT:%.*]] = icmp eq i32 [[X]], 5
487+ ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], 4
488+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 -1, i8 1
489+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[NE_NOT]], i8 0, i8 [[SEL1]]
490+ ; CHECK-NEXT: ret i8 [[R]]
491+ ;
492+ %ne = icmp ne i32 %x , 5
493+ %gt = icmp sgt i32 %x , 4
494+ %sel1 = select i1 %gt , i8 -1 , i8 1
495+ %r = select i1 %ne , i8 %sel1 , i8 0
496+ ret i8 %r
497+ }
498+
499+ define i8 @scmp_from_select_ne_const_and_gt_commuted3 (i32 %x ) {
500+ ; CHECK-LABEL: define i8 @scmp_from_select_ne_const_and_gt_commuted3(
501+ ; CHECK-SAME: i32 [[X:%.*]]) {
502+ ; CHECK-NEXT: [[NE_NOT:%.*]] = icmp eq i32 [[X]], 5
503+ ; CHECK-NEXT: [[GT:%.*]] = icmp slt i32 [[X]], 4
504+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 -1, i8 1
505+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[NE_NOT]], i8 0, i8 [[SEL1]]
506+ ; CHECK-NEXT: ret i8 [[R]]
507+ ;
508+ %ne = icmp ne i32 %x , 5
509+ %gt = icmp slt i32 %x , 4
510+ %sel1 = select i1 %gt , i8 -1 , i8 1
511+ %r = select i1 %ne , i8 %sel1 , i8 0
512+ ret i8 %r
513+ }
514+
426515define <3 x i2 > @scmp_unary_shuffle_ops (<3 x i8 > %x , <3 x i8 > %y ) {
427516; CHECK-LABEL: define <3 x i2> @scmp_unary_shuffle_ops(
428517; CHECK-SAME: <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]) {
@@ -436,6 +525,213 @@ define <3 x i2> @scmp_unary_shuffle_ops(<3 x i8> %x, <3 x i8> %y) {
436525 ret <3 x i2 > %r
437526}
438527
528+ define i32 @scmp_ashr (i32 %a ) {
529+ ; CHECK-LABEL: define i32 @scmp_ashr(
530+ ; CHECK-SAME: i32 [[A:%.*]]) {
531+ ; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i32 [[A]], 31
532+ ; CHECK-NEXT: [[CMP_INV:%.*]] = icmp slt i32 [[A]], 1
533+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP_INV]], i32 [[A_LOBIT]], i32 1
534+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
535+ ;
536+ %a.lobit = ashr i32 %a , 31
537+ %cmp.inv = icmp slt i32 %a , 1
538+ %retval.0 = select i1 %cmp.inv , i32 %a.lobit , i32 1
539+ ret i32 %retval.0
540+ }
541+
542+ define i32 @scmp_sgt_slt (i32 %a ) {
543+ ; CHECK-LABEL: define i32 @scmp_sgt_slt(
544+ ; CHECK-SAME: i32 [[A:%.*]]) {
545+ ; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i32 [[A]], 31
546+ ; CHECK-NEXT: [[CMP_INV:%.*]] = icmp slt i32 [[A]], 1
547+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP_INV]], i32 [[A_LOBIT]], i32 1
548+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
549+ ;
550+ %cmp = icmp sgt i32 %a , 0
551+ %cmp1 = icmp slt i32 %a , 0
552+ %. = select i1 %cmp1 , i32 -1 , i32 0
553+ %retval.0 = select i1 %cmp , i32 1 , i32 %.
554+ ret i32 %retval.0
555+ }
556+
557+ define i32 @scmp_zero_slt (i32 %a ) {
558+ ; CHECK-LABEL: define i32 @scmp_zero_slt(
559+ ; CHECK-SAME: i32 [[A:%.*]]) {
560+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
561+ ; CHECK-NEXT: [[CMP1_INV:%.*]] = icmp slt i32 [[A]], 1
562+ ; CHECK-NEXT: [[DOT:%.*]] = select i1 [[CMP1_INV]], i32 -1, i32 1
563+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i32 0, i32 [[DOT]]
564+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
565+ ;
566+ %cmp = icmp eq i32 %a , 0
567+ %cmp1.inv = icmp slt i32 %a , 1
568+ %. = select i1 %cmp1.inv , i32 -1 , i32 1
569+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
570+ ret i32 %retval.0
571+ }
572+
573+ define i32 @scmp_zero_sgt (i32 %a ) {
574+ ; CHECK-LABEL: define i32 @scmp_zero_sgt(
575+ ; CHECK-SAME: i32 [[A:%.*]]) {
576+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
577+ ; CHECK-NEXT: [[CMP1_INV:%.*]] = icmp sgt i32 [[A]], -1
578+ ; CHECK-NEXT: [[DOT:%.*]] = select i1 [[CMP1_INV]], i32 1, i32 -1
579+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i32 0, i32 [[DOT]]
580+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
581+ ;
582+ %cmp = icmp eq i32 %a , 0
583+ %cmp1.inv = icmp sgt i32 %a , -1
584+ %. = select i1 %cmp1.inv , i32 1 , i32 -1
585+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
586+ ret i32 %retval.0
587+ }
588+
589+
590+ define i32 @scmp_zero_sgt_1 (i32 %a ) {
591+ ; CHECK-LABEL: define i32 @scmp_zero_sgt_1(
592+ ; CHECK-SAME: i32 [[A:%.*]]) {
593+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
594+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], -1
595+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], i32 1, i32 -1
596+ ; CHECK-NEXT: [[COND2:%.*]] = select i1 [[CMP]], i32 0, i32 [[COND]]
597+ ; CHECK-NEXT: ret i32 [[COND2]]
598+ ;
599+ %cmp = icmp eq i32 %a , 0
600+ %cmp1 = icmp sgt i32 %a , -1
601+ %cond = select i1 %cmp1 , i32 1 , i32 -1
602+ %cond2 = select i1 %cmp , i32 0 , i32 %cond
603+ ret i32 %cond2
604+ }
605+
606+ define i32 @scmp_zero_slt_1 (i32 %a ) {
607+ ; CHECK-LABEL: define i32 @scmp_zero_slt_1(
608+ ; CHECK-SAME: i32 [[A:%.*]]) {
609+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
610+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 1
611+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], i32 -1, i32 1
612+ ; CHECK-NEXT: [[COND2:%.*]] = select i1 [[CMP]], i32 0, i32 [[COND]]
613+ ; CHECK-NEXT: ret i32 [[COND2]]
614+ ;
615+ %cmp = icmp eq i32 %a , 0
616+ %cmp1 = icmp slt i32 %a , 1
617+ %cond = select i1 %cmp1 , i32 -1 , i32 1
618+ %cond2 = select i1 %cmp , i32 0 , i32 %cond
619+ ret i32 %cond2
620+ }
621+
622+ define i32 @scmp_zero_slt_neg (i32 %a ) {
623+ ; CHECK-LABEL: define i32 @scmp_zero_slt_neg(
624+ ; CHECK-SAME: i32 [[A:%.*]]) {
625+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
626+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -1
627+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], i32 -1, i32 1
628+ ; CHECK-NEXT: [[COND2:%.*]] = select i1 [[CMP]], i32 0, i32 [[COND]]
629+ ; CHECK-NEXT: ret i32 [[COND2]]
630+ ;
631+ %cmp = icmp eq i32 %a , 0
632+ %cmp1 = icmp slt i32 %a , -1
633+ %cond = select i1 %cmp1 , i32 -1 , i32 1
634+ %cond2 = select i1 %cmp , i32 0 , i32 %cond
635+ ret i32 %cond2
636+ }
637+
638+ define i32 @scmp_zero_sgt_neg (i32 %a ) {
639+ ; CHECK-LABEL: define i32 @scmp_zero_sgt_neg(
640+ ; CHECK-SAME: i32 [[A:%.*]]) {
641+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
642+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], 1
643+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], i32 1, i32 -1
644+ ; CHECK-NEXT: [[COND2:%.*]] = select i1 [[CMP]], i32 0, i32 [[COND]]
645+ ; CHECK-NEXT: ret i32 [[COND2]]
646+ ;
647+ %cmp = icmp eq i32 %a , 0
648+ %cmp1 = icmp sgt i32 %a , 1
649+ %cond = select i1 %cmp1 , i32 1 , i32 -1
650+ %cond2 = select i1 %cmp , i32 0 , i32 %cond
651+ ret i32 %cond2
652+ }
653+
654+ define i32 @ucmp_ugt_ult_neg (i32 %a ) {
655+ ; CHECK-LABEL: define i32 @ucmp_ugt_ult_neg(
656+ ; CHECK-SAME: i32 [[A:%.*]]) {
657+ ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ne i32 [[A]], 0
658+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = zext i1 [[CMP_NOT]] to i32
659+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
660+ ;
661+ %cmp = icmp ugt i32 %a , 0
662+ %cmp1 = icmp ult i32 %a , 0
663+ %. = select i1 %cmp1 , i32 -1 , i32 0
664+ %retval.0 = select i1 %cmp , i32 1 , i32 %.
665+ ret i32 %retval.0
666+ }
667+
668+ define i32 @ucmp_zero_ult_neg (i32 %a ) {
669+ ; CHECK-LABEL: define i32 @ucmp_zero_ult_neg(
670+ ; CHECK-SAME: i32 [[A:%.*]]) {
671+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A]], 0
672+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = zext i1 [[CMP]] to i32
673+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
674+ ;
675+ %cmp = icmp eq i32 %a , 0
676+ %cmp1.inv = icmp ult i32 %a , 1
677+ %. = select i1 %cmp1.inv , i32 -1 , i32 1
678+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
679+ ret i32 %retval.0
680+ }
681+
682+ define i32 @ucmp_zero_ugt_neg (i32 %a ) {
683+ ; CHECK-LABEL: define i32 @ucmp_zero_ugt_neg(
684+ ; CHECK-SAME: i32 [[A:%.*]]) {
685+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A]], 0
686+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = sext i1 [[CMP]] to i32
687+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
688+ ;
689+ %cmp = icmp eq i32 %a , 0
690+ %cmp1.inv = icmp ugt i32 %a , -1
691+ %. = select i1 %cmp1.inv , i32 1 , i32 -1
692+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
693+ ret i32 %retval.0
694+ }
695+
696+ define i32 @scmp_sgt_slt_ab (i32 %a , i32 %b ) {
697+ ; CHECK-LABEL: define i32 @scmp_sgt_slt_ab(
698+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
699+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])
700+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
701+ ;
702+ %cmp = icmp sgt i32 %a , %b
703+ %cmp1 = icmp slt i32 %a , %b
704+ %. = select i1 %cmp1 , i32 -1 , i32 0
705+ %retval.0 = select i1 %cmp , i32 1 , i32 %.
706+ ret i32 %retval.0
707+ }
708+
709+ define i32 @scmp_zero_slt_ab (i32 %a , i32 %b ) {
710+ ; CHECK-LABEL: define i32 @scmp_zero_slt_ab(
711+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
712+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])
713+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
714+ ;
715+ %cmp = icmp eq i32 %a , %b
716+ %cmp1.inv = icmp slt i32 %a , %b
717+ %. = select i1 %cmp1.inv , i32 -1 , i32 1
718+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
719+ ret i32 %retval.0
720+ }
721+
722+ define i32 @scmp_zero_sgt_ab (i32 %a , i32 %b ) {
723+ ; CHECK-LABEL: define i32 @scmp_zero_sgt_ab(
724+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
725+ ; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])
726+ ; CHECK-NEXT: ret i32 [[RETVAL_0]]
727+ ;
728+ %cmp = icmp eq i32 %a , %b
729+ %cmp1.inv = icmp sgt i32 %a , %b
730+ %. = select i1 %cmp1.inv , i32 1 , i32 -1
731+ %retval.0 = select i1 %cmp , i32 0 , i32 %.
732+ ret i32 %retval.0
733+ }
734+
439735; Negative test: true value of outer select is not zero
440736define i8 @scmp_from_select_eq_and_gt_neg1 (i32 %x , i32 %y ) {
441737; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg1(
0 commit comments