@@ -217,12 +217,7 @@ define i1 @f32_fczero_strictfp(float %a) strictfp {
217
217
define i1 @f32_fcnan (float %a ) {
218
218
; CHECK-LABEL: define i1 @f32_fcnan(
219
219
; CHECK-SAME: float [[A:%.*]]) {
220
- ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
221
- ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[I32]], 2139095040
222
- ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 2139095040
223
- ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[I32]], 8388607
224
- ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[AND2]], 0
225
- ; CHECK-NEXT: [[RES:%.*]] = and i1 [[CMP1]], [[CMP2]]
220
+ ; CHECK-NEXT: [[RES:%.*]] = fcmp uno float [[A]], 0.000000e+00
226
221
; CHECK-NEXT: ret i1 [[RES]]
227
222
;
228
223
%i32 = bitcast float %a to i32
@@ -647,6 +642,241 @@ define i1 @f32_fcposinf_multiuse_strictfp(float %a) strictfp {
647
642
ret i1 %cmp
648
643
}
649
644
645
+ define i1 @isnan_idiom (double %x ) {
646
+ ; CHECK-LABEL: define i1 @isnan_idiom(
647
+ ; CHECK-SAME: double [[X:%.*]]) {
648
+ ; CHECK-NEXT: [[RET:%.*]] = fcmp uno double [[X]], 0.000000e+00
649
+ ; CHECK-NEXT: ret i1 [[RET]]
650
+ ;
651
+ %bits = bitcast double %x to i64
652
+ %mask1 = and i64 %bits , 9218868437227405312
653
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405312
654
+ %mask2 = and i64 %bits , 4503599627370495
655
+ %cond2 = icmp ne i64 %mask2 , 0
656
+ %ret = and i1 %cond1 , %cond2
657
+ ret i1 %ret
658
+ }
659
+
660
+ define <2 x i1 > @isnan_idiom_vec (<2 x double > %x ) {
661
+ ; CHECK-LABEL: define <2 x i1> @isnan_idiom_vec(
662
+ ; CHECK-SAME: <2 x double> [[X:%.*]]) {
663
+ ; CHECK-NEXT: [[RET:%.*]] = fcmp uno <2 x double> [[X]], zeroinitializer
664
+ ; CHECK-NEXT: ret <2 x i1> [[RET]]
665
+ ;
666
+ %bits = bitcast <2 x double > %x to <2 x i64 >
667
+ %mask1 = and <2 x i64 > %bits , splat(i64 9218868437227405312 )
668
+ %cond1 = icmp eq <2 x i64 > %mask1 , splat(i64 9218868437227405312 )
669
+ %mask2 = and <2 x i64 > %bits , splat(i64 4503599627370495 )
670
+ %cond2 = icmp ne <2 x i64 > %mask2 , zeroinitializer
671
+ %ret = and <2 x i1 > %cond1 , %cond2
672
+ ret <2 x i1 > %ret
673
+ }
674
+
675
+ define i1 @isnan_idiom_commuted (double %x ) {
676
+ ; CHECK-LABEL: define i1 @isnan_idiom_commuted(
677
+ ; CHECK-SAME: double [[X:%.*]]) {
678
+ ; CHECK-NEXT: [[RET:%.*]] = fcmp uno double [[X]], 0.000000e+00
679
+ ; CHECK-NEXT: ret i1 [[RET]]
680
+ ;
681
+ %bits = bitcast double %x to i64
682
+ %mask1 = and i64 %bits , 9218868437227405312
683
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405312
684
+ %mask2 = and i64 %bits , 4503599627370495
685
+ %cond2 = icmp ne i64 %mask2 , 0
686
+ %ret = and i1 %cond2 , %cond1
687
+ ret i1 %ret
688
+ }
689
+
690
+ define i1 @isnotnan_idiom (double %x ) {
691
+ ; CHECK-LABEL: define i1 @isnotnan_idiom(
692
+ ; CHECK-SAME: double [[X:%.*]]) {
693
+ ; CHECK-NEXT: [[RET:%.*]] = fcmp ord double [[X]], 0.000000e+00
694
+ ; CHECK-NEXT: ret i1 [[RET]]
695
+ ;
696
+ %bits = bitcast double %x to i64
697
+ %mask1 = and i64 %bits , 9218868437227405312
698
+ %cond1 = icmp ne i64 %mask1 , 9218868437227405312
699
+ %mask2 = and i64 %bits , 4503599627370495
700
+ %cond2 = icmp eq i64 %mask2 , 0
701
+ %ret = or i1 %cond1 , %cond2
702
+ ret i1 %ret
703
+ }
704
+
705
+ ; negative tests
706
+
707
+ define i1 @isnan_idiom_strictfp (double %x ) strictfp {
708
+ ; CHECK-LABEL: define i1 @isnan_idiom_strictfp(
709
+ ; CHECK-SAME: double [[X:%.*]]) #[[ATTR0]] {
710
+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64
711
+ ; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
712
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
713
+ ; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
714
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
715
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
716
+ ; CHECK-NEXT: ret i1 [[RET]]
717
+ ;
718
+ %bits = bitcast double %x to i64
719
+ %mask1 = and i64 %bits , 9218868437227405312
720
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405312
721
+ %mask2 = and i64 %bits , 4503599627370495
722
+ %cond2 = icmp ne i64 %mask2 , 0
723
+ %ret = and i1 %cond1 , %cond2
724
+ ret i1 %ret
725
+ }
726
+
727
+ define i1 @isnan_idiom_wrong_pred1 (double %x ) {
728
+ ; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred1(
729
+ ; CHECK-SAME: double [[X:%.*]]) {
730
+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64
731
+ ; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
732
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[MASK1]], 9218868437227405312
733
+ ; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
734
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
735
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
736
+ ; CHECK-NEXT: ret i1 [[RET]]
737
+ ;
738
+ %bits = bitcast double %x to i64
739
+ %mask1 = and i64 %bits , 9218868437227405312
740
+ %cond1 = icmp ne i64 %mask1 , 9218868437227405312
741
+ %mask2 = and i64 %bits , 4503599627370495
742
+ %cond2 = icmp ne i64 %mask2 , 0
743
+ %ret = and i1 %cond1 , %cond2
744
+ ret i1 %ret
745
+ }
746
+
747
+ define i1 @isnan_idiom_wrong_pred2 (double %x ) {
748
+ ; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred2(
749
+ ; CHECK-SAME: double [[X:%.*]]) {
750
+ ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]])
751
+ ; CHECK-NEXT: [[RET:%.*]] = fcmp oeq double [[TMP1]], 0x7FF0000000000000
752
+ ; CHECK-NEXT: ret i1 [[RET]]
753
+ ;
754
+ %bits = bitcast double %x to i64
755
+ %mask1 = and i64 %bits , 9218868437227405312
756
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405312
757
+ %mask2 = and i64 %bits , 4503599627370495
758
+ %cond2 = icmp eq i64 %mask2 , 0
759
+ %ret = and i1 %cond1 , %cond2
760
+ ret i1 %ret
761
+ }
762
+
763
+ define i1 @isnan_idiom_wrong_pred3 (double %x ) {
764
+ ; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred3(
765
+ ; CHECK-SAME: double [[X:%.*]]) {
766
+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64
767
+ ; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
768
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
769
+ ; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
770
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
771
+ ; CHECK-NEXT: [[RET:%.*]] = or i1 [[COND1]], [[COND2]]
772
+ ; CHECK-NEXT: ret i1 [[RET]]
773
+ ;
774
+ %bits = bitcast double %x to i64
775
+ %mask1 = and i64 %bits , 9218868437227405312
776
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405312
777
+ %mask2 = and i64 %bits , 4503599627370495
778
+ %cond2 = icmp ne i64 %mask2 , 0
779
+ %ret = or i1 %cond1 , %cond2
780
+ ret i1 %ret
781
+ }
782
+
783
+ define i1 @isnan_idiom_wrong_mask1 (double %x ) {
784
+ ; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask1(
785
+ ; CHECK-SAME: double [[X:%.*]]) {
786
+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64
787
+ ; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405311
788
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405311
789
+ ; CHECK-NEXT: ret i1 [[COND1]]
790
+ ;
791
+ %bits = bitcast double %x to i64
792
+ %mask1 = and i64 %bits , 9218868437227405311
793
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405311
794
+ %mask2 = and i64 %bits , 4503599627370495
795
+ %cond2 = icmp ne i64 %mask2 , 0
796
+ %ret = and i1 %cond1 , %cond2
797
+ ret i1 %ret
798
+ }
799
+
800
+ define i1 @isnan_idiom_wrong_mask2 (double %x ) {
801
+ ; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask2(
802
+ ; CHECK-SAME: double [[X:%.*]]) {
803
+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64
804
+ ; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
805
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
806
+ ; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370494
807
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
808
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
809
+ ; CHECK-NEXT: ret i1 [[RET]]
810
+ ;
811
+ %bits = bitcast double %x to i64
812
+ %mask1 = and i64 %bits , 9218868437227405312
813
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405312
814
+ %mask2 = and i64 %bits , 4503599627370494
815
+ %cond2 = icmp ne i64 %mask2 , 0
816
+ %ret = and i1 %cond1 , %cond2
817
+ ret i1 %ret
818
+ }
819
+
820
+ define i1 @isnan_idiom_wrong_mask3 (double %x ) {
821
+ ; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask3(
822
+ ; CHECK-SAME: double [[X:%.*]]) {
823
+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64
824
+ ; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
825
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
826
+ ; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
827
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 4503599627370495
828
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
829
+ ; CHECK-NEXT: ret i1 [[RET]]
830
+ ;
831
+ %bits = bitcast double %x to i64
832
+ %mask1 = and i64 %bits , 9218868437227405312
833
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405312
834
+ %mask2 = and i64 %bits , 4503599627370495
835
+ %cond2 = icmp ne i64 %mask2 , 4503599627370495
836
+ %ret = and i1 %cond1 , %cond2
837
+ ret i1 %ret
838
+ }
839
+
840
+ define i1 @isnan_idiom_invalid_bitcast (<2 x float > %x ) {
841
+ ; CHECK-LABEL: define i1 @isnan_idiom_invalid_bitcast(
842
+ ; CHECK-SAME: <2 x float> [[X:%.*]]) {
843
+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast <2 x float> [[X]] to i64
844
+ ; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312
845
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312
846
+ ; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495
847
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0
848
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
849
+ ; CHECK-NEXT: ret i1 [[RET]]
850
+ ;
851
+ %bits = bitcast <2 x float > %x to i64
852
+ %mask1 = and i64 %bits , 9218868437227405312
853
+ %cond1 = icmp eq i64 %mask1 , 9218868437227405312
854
+ %mask2 = and i64 %bits , 4503599627370495
855
+ %cond2 = icmp ne i64 %mask2 , 0
856
+ %ret = and i1 %cond1 , %cond2
857
+ ret i1 %ret
858
+ }
859
+
860
+ define i1 @isnan_idiom_ppc_fp128 (ppc_fp128 %x ) {
861
+ ; CHECK-LABEL: define i1 @isnan_idiom_ppc_fp128(
862
+ ; CHECK-SAME: ppc_fp128 [[X:%.*]]) {
863
+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast ppc_fp128 [[X]] to i128
864
+ ; CHECK-NEXT: [[MASK1:%.*]] = and i128 [[BITS]], 170058106710732674489630815774616584192
865
+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i128 [[MASK1]], 170058106710732674489630815774616584192
866
+ ; CHECK-NEXT: [[MASK2:%.*]] = and i128 [[BITS]], 83076749736557242056487941267521535
867
+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i128 [[MASK2]], 0
868
+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]
869
+ ; CHECK-NEXT: ret i1 [[RET]]
870
+ ;
871
+ %bits = bitcast ppc_fp128 %x to i128
872
+ %mask1 = and i128 %bits , 170058106710732674489630815774616584192
873
+ %cond1 = icmp eq i128 %mask1 , 170058106710732674489630815774616584192
874
+ %mask2 = and i128 %bits , 83076749736557242056487941267521535
875
+ %cond2 = icmp ne i128 %mask2 , 0
876
+ %ret = and i1 %cond1 , %cond2
877
+ ret i1 %ret
878
+ }
879
+
650
880
declare void @usei32 (i32 )
651
881
652
882
attributes #0 = { noimplicitfloat }
0 commit comments