@@ -520,3 +520,352 @@ define i1 @fshl_or_ne_2(i32 %x, i32 %y) {
520
520
%r = icmp ne i32 %f , 2
521
521
ret i1 %r
522
522
}
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