@@ -566,6 +566,142 @@ define i1 @f32_fcnan_fcinf_noimplicitfloat_strictfp(float %a) strictfp #0 {
566566 ret i1 %cmp
567567}
568568
569+ define i1 @f32_fcsubnormal_fczero (float %a ) {
570+ ; CHECK-LABEL: define i1 @f32_fcsubnormal_fczero(
571+ ; CHECK-SAME: float [[A:%.*]]) {
572+ ; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 240)
573+ ; CHECK-NEXT: ret i1 [[CMP]]
574+ ;
575+ %i32 = bitcast float %a to i32
576+ %and = and i32 %i32 , 2139095040
577+ %cmp = icmp eq i32 %and , 0
578+ ret i1 %cmp
579+ }
580+
581+ define i1 @f32_not_fcsubnormal_fczero (float %a ) {
582+ ; CHECK-LABEL: define i1 @f32_not_fcsubnormal_fczero(
583+ ; CHECK-SAME: float [[A:%.*]]) {
584+ ; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 783)
585+ ; CHECK-NEXT: ret i1 [[CMP]]
586+ ;
587+ %i32 = bitcast float %a to i32
588+ %and = and i32 %i32 , 2139095040
589+ %cmp = icmp ne i32 %and , 0
590+ ret i1 %cmp
591+ }
592+
593+ define <2 x i1 > @f64_fcsubnormal_fczero_vec (<2 x double > %a ) {
594+ ; CHECK-LABEL: define <2 x i1> @f64_fcsubnormal_fczero_vec(
595+ ; CHECK-SAME: <2 x double> [[A:%.*]]) {
596+ ; CHECK-NEXT: [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f64(<2 x double> [[A]], i32 240)
597+ ; CHECK-NEXT: ret <2 x i1> [[CMP]]
598+ ;
599+ %i64 = bitcast <2 x double > %a to <2 x i64 >
600+ %and = and <2 x i64 > %i64 , splat(i64 9218868437227405312 )
601+ %cmp = icmp eq <2 x i64 > %and , zeroinitializer
602+ ret <2 x i1 > %cmp
603+ }
604+
605+ define <2 x i1 > @f64_no_fcsubnormal_fczero_vec (<2 x double > %a ) {
606+ ; CHECK-LABEL: define <2 x i1> @f64_no_fcsubnormal_fczero_vec(
607+ ; CHECK-SAME: <2 x double> [[A:%.*]]) {
608+ ; CHECK-NEXT: [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f64(<2 x double> [[A]], i32 783)
609+ ; CHECK-NEXT: ret <2 x i1> [[CMP]]
610+ ;
611+ %i64 = bitcast <2 x double > %a to <2 x i64 >
612+ %and = and <2 x i64 > %i64 , splat(i64 9218868437227405312 )
613+ %cmp = icmp ne <2 x i64 > %and , zeroinitializer
614+ ret <2 x i1 > %cmp
615+ }
616+
617+ define i1 @f32_fcsubnormal_fczero_no_implicit_fp (float %a ) #0 {
618+ ; CHECK-LABEL: define i1 @f32_fcsubnormal_fczero_no_implicit_fp(
619+ ; CHECK-SAME: float [[A:%.*]]) #[[ATTR1]] {
620+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
621+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040
622+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
623+ ; CHECK-NEXT: ret i1 [[CMP]]
624+ ;
625+ %i32 = bitcast float %a to i32
626+ %and = and i32 %i32 , 2139095040
627+ %cmp = icmp eq i32 %and , 0
628+ ret i1 %cmp
629+ }
630+
631+ define i1 @f32_fcsubnormal_fczero_invalid_constant1 (float %a ) {
632+ ; CHECK-LABEL: define i1 @f32_fcsubnormal_fczero_invalid_constant1(
633+ ; CHECK-SAME: float [[A:%.*]]) {
634+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
635+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095039
636+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
637+ ; CHECK-NEXT: ret i1 [[CMP]]
638+ ;
639+ %i32 = bitcast float %a to i32
640+ %and = and i32 %i32 , 2139095039
641+ %cmp = icmp eq i32 %and , 0
642+ ret i1 %cmp
643+ }
644+
645+ define i1 @f32_fcsubnormal_fczero_invalid_constant2 (float %a ) {
646+ ; CHECK-LABEL: define i1 @f32_fcsubnormal_fczero_invalid_constant2(
647+ ; CHECK-SAME: float [[A:%.*]]) {
648+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
649+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040
650+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2130706432
651+ ; CHECK-NEXT: ret i1 [[CMP]]
652+ ;
653+ %i32 = bitcast float %a to i32
654+ %and = and i32 %i32 , 2139095040
655+ %cmp = icmp eq i32 %and , 2130706432
656+ ret i1 %cmp
657+ }
658+
659+ define i1 @ppc128_fcsubnormal_fczero (ppc_fp128 %a ) {
660+ ; CHECK-LABEL: define i1 @ppc128_fcsubnormal_fczero(
661+ ; CHECK-SAME: ppc_fp128 [[A:%.*]]) {
662+ ; CHECK-NEXT: [[I128:%.*]] = bitcast ppc_fp128 [[A]] to i128
663+ ; CHECK-NEXT: [[AND:%.*]] = and i128 [[I128]], 170058106710732674489630815774616584192
664+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i128 [[AND]], 0
665+ ; CHECK-NEXT: ret i1 [[CMP]]
666+ ;
667+ %i128 = bitcast ppc_fp128 %a to i128
668+ %and = and i128 %i128 , 170058106710732674489630815774616584192
669+ %cmp = icmp eq i128 %and , 0
670+ ret i1 %cmp
671+ }
672+
673+ define i1 @f32_fcsubnormal_fczero_multiuse1 (float %a ) {
674+ ; CHECK-LABEL: define i1 @f32_fcsubnormal_fczero_multiuse1(
675+ ; CHECK-SAME: float [[A:%.*]]) {
676+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
677+ ; CHECK-NEXT: call void @usei32(i32 [[I32]])
678+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040
679+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
680+ ; CHECK-NEXT: ret i1 [[CMP]]
681+ ;
682+ %i32 = bitcast float %a to i32
683+ call void @usei32 (i32 %i32 )
684+ %and = and i32 %i32 , 2139095040
685+ %cmp = icmp eq i32 %and , 0
686+ ret i1 %cmp
687+ }
688+
689+ define i1 @f32_fcsubnormal_fczero_multiuse2 (float %a ) {
690+ ; CHECK-LABEL: define i1 @f32_fcsubnormal_fczero_multiuse2(
691+ ; CHECK-SAME: float [[A:%.*]]) {
692+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
693+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040
694+ ; CHECK-NEXT: call void @usei32(i32 [[AND]])
695+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
696+ ; CHECK-NEXT: ret i1 [[CMP]]
697+ ;
698+ %i32 = bitcast float %a to i32
699+ %and = and i32 %i32 , 2139095040
700+ call void @usei32 (i32 %and )
701+ %cmp = icmp eq i32 %and , 0
702+ ret i1 %cmp
703+ }
704+
569705define i1 @f32_fcposinf_noimplicitfloat (float %a ) #0 {
570706; CHECK-LABEL: define i1 @f32_fcposinf_noimplicitfloat(
571707; CHECK-SAME: float [[A:%.*]]) #[[ATTR1]] {
0 commit comments