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