@@ -520,3 +520,352 @@ define i1 @fshl_or_ne_2(i32 %x, i32 %y) {
520520 %r = icmp ne i32 %f , 2
521521 ret i1 %r
522522}
523+
524+ define i1 @and_rotl_eq_neg_1 (i8 %x , i8 %y , i8 %z ) nounwind {
525+ ; CHECK-LABEL: and_rotl_eq_neg_1:
526+ ; CHECK: # %bb.0:
527+ ; CHECK-NEXT: movl %edx, %ecx
528+ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
529+ ; CHECK-NEXT: rolb %cl, %dil
530+ ; CHECK-NEXT: andb %sil, %dil
531+ ; CHECK-NEXT: cmpb $-1, %dil
532+ ; CHECK-NEXT: sete %al
533+ ; CHECK-NEXT: retq
534+ %rot = tail call i8 @llvm.fshl.i8 (i8 %x , i8 %x , i8 %z )
535+ %and = and i8 %rot , %y
536+ %r = icmp eq i8 %and , -1
537+ ret i1 %r
538+ }
539+
540+ define i1 @and_rotr_ne_neg_1 (i64 %x , i64 %y , i64 %z ) nounwind {
541+ ; CHECK-LABEL: and_rotr_ne_neg_1:
542+ ; CHECK: # %bb.0:
543+ ; CHECK-NEXT: movq %rdx, %rcx
544+ ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
545+ ; CHECK-NEXT: rorq %cl, %rdi
546+ ; CHECK-NEXT: testq %rdi, %rsi
547+ ; CHECK-NEXT: setne %al
548+ ; CHECK-NEXT: retq
549+ %rot = tail call i64 @llvm.fshr.i64 (i64 %x , i64 %x , i64 %z )
550+ %and = and i64 %y , %rot
551+ %r = icmp ne i64 %and , 0
552+ ret i1 %r
553+ }
554+
555+ ; negative test - wrong constant
556+
557+ define i1 @or_rotl_ne_neg_1 (i32 %x , i32 %y , i32 %z ) nounwind {
558+ ; CHECK-LABEL: or_rotl_ne_neg_1:
559+ ; CHECK: # %bb.0:
560+ ; CHECK-NEXT: movl %edx, %ecx
561+ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
562+ ; CHECK-NEXT: roll %cl, %edi
563+ ; CHECK-NEXT: testl %edi, %esi
564+ ; CHECK-NEXT: setne %al
565+ ; CHECK-NEXT: retq
566+ %rot = tail call i32 @llvm.fshl.i32 (i32 %x , i32 %x , i32 %z )
567+ %and = and i32 %y , %rot
568+ %r = icmp ne i32 %and , 0
569+ ret i1 %r
570+ }
571+
572+ ; negative test - extra use
573+
574+ define i1 @and_rotl_ne_neg_1_use (i32 %x , i32 %y , i32 %z ) nounwind {
575+ ; CHECK-LABEL: and_rotl_ne_neg_1_use:
576+ ; CHECK: # %bb.0:
577+ ; CHECK-NEXT: pushq %rbx
578+ ; CHECK-NEXT: movl %edx, %ecx
579+ ; CHECK-NEXT: movl %edi, %ebx
580+ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
581+ ; CHECK-NEXT: roll %cl, %ebx
582+ ; CHECK-NEXT: andl %esi, %ebx
583+ ; CHECK-NEXT: movl %ebx, %edi
584+ ; CHECK-NEXT: callq use32@PLT
585+ ; CHECK-NEXT: cmpl $-1, %ebx
586+ ; CHECK-NEXT: setne %al
587+ ; CHECK-NEXT: popq %rbx
588+ ; CHECK-NEXT: retq
589+ %rot = tail call i32 @llvm.fshl.i32 (i32 %x , i32 %x , i32 %z )
590+ %and = and i32 %y , %rot
591+ call void @use32 (i32 %and )
592+ %r = icmp ne i32 %and , -1
593+ ret i1 %r
594+ }
595+
596+ define <4 x i1 > @and_rotl_ne_eq_neg_1 (<4 x i32 > %x , <4 x i32 > %y ) nounwind {
597+ ; CHECK-LABEL: and_rotl_ne_eq_neg_1:
598+ ; CHECK: # %bb.0:
599+ ; CHECK-NEXT: movdqa %xmm1, %xmm2
600+ ; CHECK-NEXT: pslld $23, %xmm2
601+ ; CHECK-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
602+ ; CHECK-NEXT: paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
603+ ; CHECK-NEXT: cvttps2dq %xmm2, %xmm2
604+ ; CHECK-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
605+ ; CHECK-NEXT: pmuludq %xmm2, %xmm0
606+ ; CHECK-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,3,2,3]
607+ ; CHECK-NEXT: pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
608+ ; CHECK-NEXT: pmuludq %xmm3, %xmm2
609+ ; CHECK-NEXT: pshufd {{.*#+}} xmm3 = xmm2[1,3,2,3]
610+ ; CHECK-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1]
611+ ; CHECK-NEXT: pshufd {{.*#+}} xmm3 = xmm0[0,2,2,3]
612+ ; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
613+ ; CHECK-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1]
614+ ; CHECK-NEXT: por %xmm4, %xmm3
615+ ; CHECK-NEXT: pand %xmm1, %xmm3
616+ ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0
617+ ; CHECK-NEXT: pcmpeqd %xmm3, %xmm0
618+ ; CHECK-NEXT: retq
619+ %rot = tail call <4 x i32 > @llvm.fshl.v4i32 (<4 x i32 >%x , <4 x i32 > %x , <4 x i32 > %y )
620+ %and = and <4 x i32 > %y , %rot
621+ %r = icmp eq <4 x i32 > %and , <i32 -1 , i32 -1 , i32 -1 , i32 poison>
622+ ret <4 x i1 > %r
623+ }
624+
625+ define i1 @fshl_or_eq_neg_1 (i32 %x , i32 %y ) {
626+ ; CHECK-LABEL: fshl_or_eq_neg_1:
627+ ; CHECK: # %bb.0:
628+ ; CHECK-NEXT: andl %edi, %esi
629+ ; CHECK-NEXT: shldl $5, %edi, %esi
630+ ; CHECK-NEXT: cmpl $-1, %esi
631+ ; CHECK-NEXT: sete %al
632+ ; CHECK-NEXT: retq
633+ %and = and i32 %x , %y
634+ %f = call i32 @llvm.fshl.i32 (i32 %and , i32 %x , i32 5 )
635+ %r = icmp eq i32 %f , -1
636+ ret i1 %r
637+ }
638+
639+ define i1 @fshl_and_commute_eq_neg_1 (i32 %x , i32 %y ) {
640+ ; CHECK-LABEL: fshl_and_commute_eq_neg_1:
641+ ; CHECK: # %bb.0:
642+ ; CHECK-NEXT: andl %edi, %esi
643+ ; CHECK-NEXT: shldl $5, %edi, %esi
644+ ; CHECK-NEXT: cmpl $-1, %esi
645+ ; CHECK-NEXT: sete %al
646+ ; CHECK-NEXT: retq
647+ %and = and i32 %y , %x
648+ %f = call i32 @llvm.fshl.i32 (i32 %and , i32 %x , i32 5 )
649+ %r = icmp eq i32 %f , -1
650+ ret i1 %r
651+ }
652+
653+ define <4 x i1 > @fshl_and2_eq_neg_1 (<4 x i32 > %x , <4 x i32 > %y ) {
654+ ; CHECK-LABEL: fshl_and2_eq_neg_1:
655+ ; CHECK: # %bb.0:
656+ ; CHECK-NEXT: pand %xmm0, %xmm1
657+ ; CHECK-NEXT: psrld $7, %xmm1
658+ ; CHECK-NEXT: pslld $25, %xmm0
659+ ; CHECK-NEXT: por %xmm1, %xmm0
660+ ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
661+ ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
662+ ; CHECK-NEXT: retq
663+ %and = and <4 x i32 > %x , %y
664+ %f = call <4 x i32 > @llvm.fshl.v4i32 (<4 x i32 > %x , <4 x i32 > %and , <4 x i32 > <i32 25 , i32 25 , i32 25 , i32 25 >)
665+ %r = icmp eq <4 x i32 > %f , <i32 -1 , i32 -1 , i32 -1 , i32 -1 >
666+ ret <4 x i1 > %r
667+ }
668+
669+ define <4 x i1 > @fshl_and2_commute_eq_neg_1 (<4 x i32 > %x , <4 x i32 > %y ) {
670+ ; CHECK-LABEL: fshl_and2_commute_eq_neg_1:
671+ ; CHECK: # %bb.0:
672+ ; CHECK-NEXT: pand %xmm0, %xmm1
673+ ; CHECK-NEXT: psrld $7, %xmm1
674+ ; CHECK-NEXT: pslld $25, %xmm0
675+ ; CHECK-NEXT: por %xmm1, %xmm0
676+ ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
677+ ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
678+ ; CHECK-NEXT: retq
679+ %and = and <4 x i32 > %y , %x
680+ %f = call <4 x i32 > @llvm.fshl.v4i32 (<4 x i32 > %x , <4 x i32 > %and , <4 x i32 > <i32 25 , i32 25 , i32 25 , i32 25 >)
681+ %r = icmp eq <4 x i32 > %f , <i32 -1 , i32 -1 , i32 -1 , i32 -1 >
682+ ret <4 x i1 > %r
683+ }
684+
685+ define i1 @fshr_and_eq_neg_1 (i16 %x , i16 %y ) {
686+ ; CHECK-LABEL: fshr_and_eq_neg_1:
687+ ; CHECK: # %bb.0:
688+ ; CHECK-NEXT: andl %edi, %esi
689+ ; CHECK-NEXT: shldw $8, %di, %si
690+ ; CHECK-NEXT: cmpw $-1, %si
691+ ; CHECK-NEXT: sete %al
692+ ; CHECK-NEXT: retq
693+ %and = and i16 %x , %y
694+ %f = call i16 @llvm.fshr.i16 (i16 %and , i16 %x , i16 8 )
695+ %r = icmp eq i16 %f , -1
696+ ret i1 %r
697+ }
698+
699+ define i1 @fshr_and_commute_eq_neg_1 (i16 %x , i16 %y ) {
700+ ; CHECK-LABEL: fshr_and_commute_eq_neg_1:
701+ ; CHECK: # %bb.0:
702+ ; CHECK-NEXT: andl %edi, %esi
703+ ; CHECK-NEXT: shldw $8, %di, %si
704+ ; CHECK-NEXT: cmpw $-1, %si
705+ ; CHECK-NEXT: sete %al
706+ ; CHECK-NEXT: retq
707+ %and = and i16 %y , %x
708+ %f = call i16 @llvm.fshr.i16 (i16 %and , i16 %x , i16 8 )
709+ %r = icmp eq i16 %f , -1
710+ ret i1 %r
711+ }
712+
713+ define i1 @fshr_and2_eq_neg_1 (i64 %x , i64 %y ) {
714+ ; CHECK-LABEL: fshr_and2_eq_neg_1:
715+ ; CHECK: # %bb.0:
716+ ; CHECK-NEXT: andq %rdi, %rsi
717+ ; CHECK-NEXT: shrdq $3, %rdi, %rsi
718+ ; CHECK-NEXT: sete %al
719+ ; CHECK-NEXT: retq
720+ %and = and i64 %x , %y
721+ %f = call i64 @llvm.fshr.i64 (i64 %x , i64 %and , i64 3 )
722+ %r = icmp eq i64 %f , 0
723+ ret i1 %r
724+ }
725+
726+ define i1 @fshr_and2_commute_eq_neg_1 (i64 %x , i64 %y ) {
727+ ; CHECK-LABEL: fshr_and2_commute_eq_neg_1:
728+ ; CHECK: # %bb.0:
729+ ; CHECK-NEXT: andq %rdi, %rsi
730+ ; CHECK-NEXT: shrdq $3, %rdi, %rsi
731+ ; CHECK-NEXT: cmpq $-1, %rsi
732+ ; CHECK-NEXT: sete %al
733+ ; CHECK-NEXT: retq
734+ %and = and i64 %y , %x
735+ %f = call i64 @llvm.fshr.i64 (i64 %x , i64 %and , i64 3 )
736+ %r = icmp eq i64 %f , -1
737+ ret i1 %r
738+ }
739+
740+ define i1 @fshl_and_ne_neg_1 (i32 %x , i32 %y ) {
741+ ; CHECK-LABEL: fshl_and_ne_neg_1:
742+ ; CHECK: # %bb.0:
743+ ; CHECK-NEXT: andl %edi, %esi
744+ ; CHECK-NEXT: shldl $7, %edi, %esi
745+ ; CHECK-NEXT: cmpl $-1, %esi
746+ ; CHECK-NEXT: setne %al
747+ ; CHECK-NEXT: retq
748+ %and = and i32 %x , %y
749+ %f = call i32 @llvm.fshl.i32 (i32 %and , i32 %x , i32 7 )
750+ %r = icmp ne i32 %f , -1
751+ ret i1 %r
752+ }
753+
754+ define i1 @fshl_and_commute_ne_neg_1 (i32 %x , i32 %y ) {
755+ ; CHECK-LABEL: fshl_and_commute_ne_neg_1:
756+ ; CHECK: # %bb.0:
757+ ; CHECK-NEXT: andl %edi, %esi
758+ ; CHECK-NEXT: shldl $7, %edi, %esi
759+ ; CHECK-NEXT: cmpl $-1, %esi
760+ ; CHECK-NEXT: setne %al
761+ ; CHECK-NEXT: retq
762+ %and = and i32 %y , %x
763+ %f = call i32 @llvm.fshl.i32 (i32 %and , i32 %x , i32 7 )
764+ %r = icmp ne i32 %f , -1
765+ ret i1 %r
766+ }
767+
768+ define <4 x i1 > @fshl_and2_ne_neg_1 (<4 x i32 > %x , <4 x i32 > %y ) {
769+ ; CHECK-LABEL: fshl_and2_ne_neg_1:
770+ ; CHECK: # %bb.0:
771+ ; CHECK-NEXT: pand %xmm0, %xmm1
772+ ; CHECK-NEXT: psrld $27, %xmm1
773+ ; CHECK-NEXT: pslld $5, %xmm0
774+ ; CHECK-NEXT: por %xmm1, %xmm0
775+ ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
776+ ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
777+ ; CHECK-NEXT: pxor %xmm1, %xmm0
778+ ; CHECK-NEXT: retq
779+ %and = and <4 x i32 > %x , %y
780+ %f = call <4 x i32 > @llvm.fshl.v4i32 (<4 x i32 > %x , <4 x i32 > %and , <4 x i32 > <i32 5 , i32 5 , i32 5 , i32 5 >)
781+ %r = icmp ne <4 x i32 > %f , <i32 -1 , i32 -1 , i32 -1 , i32 -1 >
782+ ret <4 x i1 > %r
783+ }
784+
785+ define <4 x i1 > @fshl_and2_commute_ne_neg_1 (<4 x i32 > %x , <4 x i32 > %y ) {
786+ ; CHECK-LABEL: fshl_and2_commute_ne_neg_1:
787+ ; CHECK: # %bb.0:
788+ ; CHECK-NEXT: pand %xmm0, %xmm1
789+ ; CHECK-NEXT: psrld $27, %xmm1
790+ ; CHECK-NEXT: pslld $5, %xmm0
791+ ; CHECK-NEXT: por %xmm1, %xmm0
792+ ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
793+ ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
794+ ; CHECK-NEXT: pxor %xmm1, %xmm0
795+ ; CHECK-NEXT: retq
796+ %and = and <4 x i32 > %y , %x
797+ %f = call <4 x i32 > @llvm.fshl.v4i32 (<4 x i32 > %x , <4 x i32 > %and , <4 x i32 > <i32 5 , i32 5 , i32 5 , i32 5 >)
798+ %r = icmp ne <4 x i32 > %f , <i32 -1 , i32 -1 , i32 -1 , i32 -1 >
799+ ret <4 x i1 > %r
800+ }
801+
802+ define i1 @fshr_and_ne_neg_1 (i64 %x , i64 %y ) {
803+ ; CHECK-LABEL: fshr_and_ne_neg_1:
804+ ; CHECK: # %bb.0:
805+ ; CHECK-NEXT: andl %edi, %esi
806+ ; CHECK-NEXT: shldq $63, %rdi, %rsi
807+ ; CHECK-NEXT: cmpq $-1, %rsi
808+ ; CHECK-NEXT: setne %al
809+ ; CHECK-NEXT: retq
810+ %and = and i64 %x , %y
811+ %f = call i64 @llvm.fshr.i64 (i64 %and , i64 %x , i64 1 )
812+ %r = icmp ne i64 %f , -1
813+ ret i1 %r
814+ }
815+
816+ define i1 @fshr_and_commute_ne_neg_1 (i64 %x , i64 %y ) {
817+ ; CHECK-LABEL: fshr_and_commute_ne_neg_1:
818+ ; CHECK: # %bb.0:
819+ ; CHECK-NEXT: andl %edi, %esi
820+ ; CHECK-NEXT: shldq $63, %rdi, %rsi
821+ ; CHECK-NEXT: cmpq $-1, %rsi
822+ ; CHECK-NEXT: setne %al
823+ ; CHECK-NEXT: retq
824+ %and = and i64 %y , %x
825+ %f = call i64 @llvm.fshr.i64 (i64 %and , i64 %x , i64 1 )
826+ %r = icmp ne i64 %f , -1
827+ ret i1 %r
828+ }
829+
830+ define i1 @fshr_and2_ne_neg_1 (i16 %x , i16 %y ) {
831+ ; CHECK-LABEL: fshr_and2_ne_neg_1:
832+ ; CHECK: # %bb.0:
833+ ; CHECK-NEXT: andl %edi, %esi
834+ ; CHECK-NEXT: shrdw $2, %di, %si
835+ ; CHECK-NEXT: cmpw $-1, %si
836+ ; CHECK-NEXT: setne %al
837+ ; CHECK-NEXT: retq
838+ %and = and i16 %x , %y
839+ %f = call i16 @llvm.fshr.i16 (i16 %x , i16 %and , i16 2 )
840+ %r = icmp ne i16 %f , -1
841+ ret i1 %r
842+ }
843+
844+ define i1 @fshr_and2_commute_ne_neg_1 (i16 %x , i16 %y ) {
845+ ; CHECK-LABEL: fshr_and2_commute_ne_neg_1:
846+ ; CHECK: # %bb.0:
847+ ; CHECK-NEXT: andl %edi, %esi
848+ ; CHECK-NEXT: shrdw $2, %di, %si
849+ ; CHECK-NEXT: cmpw $-1, %si
850+ ; CHECK-NEXT: setne %al
851+ ; CHECK-NEXT: retq
852+ %and = and i16 %y , %x
853+ %f = call i16 @llvm.fshr.i16 (i16 %x , i16 %and , i16 2 )
854+ %r = icmp ne i16 %f , -1
855+ ret i1 %r
856+ }
857+
858+ define i1 @fshl_and_ne_neg_1_2 (i32 %x , i32 %y ) {
859+ ; CHECK-LABEL: fshl_and_ne_neg_1_2:
860+ ; CHECK: # %bb.0:
861+ ; CHECK-NEXT: andl %edi, %esi
862+ ; CHECK-NEXT: shldl $2, %edi, %esi
863+ ; CHECK-NEXT: cmpl $2, %esi
864+ ; CHECK-NEXT: setne %al
865+ ; CHECK-NEXT: retq
866+ %and = and i32 %x , %y
867+ %f = call i32 @llvm.fshl.i32 (i32 %and , i32 %x , i32 2 )
868+ %r = icmp ne i32 %f , 2
869+ ret i1 %r
870+ }
871+
0 commit comments