@@ -1013,6 +1013,215 @@ define i1 @isnan_idiom_ppc_fp128(ppc_fp128 %x) {
10131013 ret i1 %ret
10141014}
10151015
1016+ define i1 @fpclass_test_normal (float %num ) {
1017+ ; CHECK-LABEL: define i1 @fpclass_test_normal(
1018+ ; CHECK-SAME: float [[NUM:%.*]]) {
1019+ ; CHECK-NEXT: [[RES:%.*]] = call i1 @llvm.is.fpclass.f32(float [[NUM]], i32 264)
1020+ ; CHECK-NEXT: ret i1 [[RES]]
1021+ ;
1022+ %cast = bitcast float %num to i32
1023+ %masked = and i32 %cast , 2139095040
1024+ %test1 = icmp ne i32 %masked , 2139095040
1025+ %test2 = icmp ne i32 %masked , 0
1026+ %res = and i1 %test1 , %test2
1027+ ret i1 %res
1028+ }
1029+
1030+ define i1 @fpclass_test_normal_half (half %num ) {
1031+ ; CHECK-LABEL: define i1 @fpclass_test_normal_half(
1032+ ; CHECK-SAME: half [[NUM:%.*]]) {
1033+ ; CHECK-NEXT: [[RES:%.*]] = call i1 @llvm.is.fpclass.f16(half [[NUM]], i32 264)
1034+ ; CHECK-NEXT: ret i1 [[RES]]
1035+ ;
1036+ %cast = bitcast half %num to i16
1037+ %masked = and i16 %cast , 31744
1038+ %test1 = icmp ne i16 %masked , 31744
1039+ %test2 = icmp ne i16 %masked , 0
1040+ %res = and i1 %test1 , %test2
1041+ ret i1 %res
1042+ }
1043+
1044+ define <2 x i1 > @fpclass_test_normal_half_vec (<2 x half > %num ) {
1045+ ; CHECK-LABEL: define <2 x i1> @fpclass_test_normal_half_vec(
1046+ ; CHECK-SAME: <2 x half> [[NUM:%.*]]) {
1047+ ; CHECK-NEXT: [[RES:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[NUM]], i32 264)
1048+ ; CHECK-NEXT: ret <2 x i1> [[RES]]
1049+ ;
1050+ %cast = bitcast <2 x half > %num to <2 x i16 >
1051+ %masked = and <2 x i16 > %cast , splat(i16 31744 )
1052+ %test1 = icmp ne <2 x i16 > %masked , splat(i16 31744 )
1053+ %test2 = icmp ne <2 x i16 > %masked , zeroinitializer
1054+ %res = and <2 x i1 > %test1 , %test2
1055+ ret <2 x i1 > %res
1056+ }
1057+
1058+ define i1 @fpclass_test_not_normal (float %num ) {
1059+ ; CHECK-LABEL: define i1 @fpclass_test_not_normal(
1060+ ; CHECK-SAME: float [[NUM:%.*]]) {
1061+ ; CHECK-NEXT: [[RES:%.*]] = call i1 @llvm.is.fpclass.f32(float [[NUM]], i32 759)
1062+ ; CHECK-NEXT: ret i1 [[RES]]
1063+ ;
1064+ %cast = bitcast float %num to i32
1065+ %masked = and i32 %cast , 2139095040
1066+ %test1 = icmp eq i32 %masked , 2139095040
1067+ %test2 = icmp eq i32 %masked , 0
1068+ %res = or i1 %test1 , %test2
1069+ ret i1 %res
1070+ }
1071+
1072+ define <2 x i1 > @fpclass_test_not_normal_vec (<2 x float > %num ) {
1073+ ; CHECK-LABEL: define <2 x i1> @fpclass_test_not_normal_vec(
1074+ ; CHECK-SAME: <2 x float> [[NUM:%.*]]) {
1075+ ; CHECK-NEXT: [[RES:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[NUM]], i32 759)
1076+ ; CHECK-NEXT: ret <2 x i1> [[RES]]
1077+ ;
1078+ %cast = bitcast <2 x float > %num to <2 x i32 >
1079+ %masked = and <2 x i32 > %cast , splat(i32 2139095040 )
1080+ %test1 = icmp eq <2 x i32 > %masked , splat(i32 2139095040 )
1081+ %test2 = icmp eq <2 x i32 > %masked , zeroinitializer
1082+ %res = or <2 x i1 > %test1 , %test2
1083+ ret <2 x i1 > %res
1084+ }
1085+
1086+ define i1 @fpclass_test_normal_commuted (float %num ) {
1087+ ; CHECK-LABEL: define i1 @fpclass_test_normal_commuted(
1088+ ; CHECK-SAME: float [[NUM:%.*]]) {
1089+ ; CHECK-NEXT: [[RES:%.*]] = call i1 @llvm.is.fpclass.f32(float [[NUM]], i32 264)
1090+ ; CHECK-NEXT: ret i1 [[RES]]
1091+ ;
1092+ %cast = bitcast float %num to i32
1093+ %masked = and i32 %cast , 2139095040
1094+ %test1 = icmp ne i32 %masked , 2139095040
1095+ %test2 = icmp ne i32 %masked , 0
1096+ %res = and i1 %test2 , %test1
1097+ ret i1 %res
1098+ }
1099+
1100+ ; Negative tests
1101+
1102+ define i1 @fpclass_test_normal_fp128 (ppc_fp128 %x ) {
1103+ ; CHECK-LABEL: define i1 @fpclass_test_normal_fp128(
1104+ ; CHECK-SAME: ppc_fp128 [[X:%.*]]) {
1105+ ; CHECK-NEXT: [[BITS:%.*]] = bitcast ppc_fp128 [[X]] to i128
1106+ ; CHECK-NEXT: [[MASKED:%.*]] = and i128 [[BITS]], 170058106710732674489630815774616584192
1107+ ; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i128 [[MASKED]], 170058106710732674489630815774616584192
1108+ ; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i128 [[MASKED]], 0
1109+ ; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST2]], [[TEST1]]
1110+ ; CHECK-NEXT: ret i1 [[RES]]
1111+ ;
1112+ %bits = bitcast ppc_fp128 %x to i128
1113+ %masked = and i128 %bits , 170058106710732674489630815774616584192
1114+ %test1 = icmp ne i128 %masked , 170058106710732674489630815774616584192
1115+ %test2 = icmp ne i128 %masked , 0
1116+ %res = and i1 %test2 , %test1
1117+ ret i1 %res
1118+ }
1119+
1120+ define i1 @fpclass_test_normal_mismatch_pred (float %num ) {
1121+ ; CHECK-LABEL: define i1 @fpclass_test_normal_mismatch_pred(
1122+ ; CHECK-SAME: float [[NUM:%.*]]) {
1123+ ; CHECK-NEXT: [[TEST2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[NUM]], i32 240)
1124+ ; CHECK-NEXT: ret i1 [[TEST2]]
1125+ ;
1126+ %cast = bitcast float %num to i32
1127+ %masked = and i32 %cast , 2139095040
1128+ %test1 = icmp ne i32 %masked , 2139095040
1129+ %test2 = icmp eq i32 %masked , 0
1130+ %res = and i1 %test1 , %test2
1131+ ret i1 %res
1132+ }
1133+
1134+ define i1 @fpclass_test_normal_no_implicit_fp (float %num ) #0 {
1135+ ; CHECK-LABEL: define i1 @fpclass_test_normal_no_implicit_fp(
1136+ ; CHECK-SAME: float [[NUM:%.*]]) #[[ATTR1]] {
1137+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[NUM]] to i32
1138+ ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[CAST]], 2139095040
1139+ ; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i32 [[MASKED]], 2139095040
1140+ ; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i32 [[MASKED]], 0
1141+ ; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST1]], [[TEST2]]
1142+ ; CHECK-NEXT: ret i1 [[RES]]
1143+ ;
1144+ %cast = bitcast float %num to i32
1145+ %masked = and i32 %cast , 2139095040
1146+ %test1 = icmp ne i32 %masked , 2139095040
1147+ %test2 = icmp ne i32 %masked , 0
1148+ %res = and i1 %test1 , %test2
1149+ ret i1 %res
1150+ }
1151+
1152+ define i1 @fpclass_test_normal_invalid_constant1 (float %num ) {
1153+ ; CHECK-LABEL: define i1 @fpclass_test_normal_invalid_constant1(
1154+ ; CHECK-SAME: float [[NUM:%.*]]) {
1155+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[NUM]] to i32
1156+ ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[CAST]], 2139095039
1157+ ; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i32 [[MASKED]], 2139095039
1158+ ; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i32 [[MASKED]], 0
1159+ ; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST1]], [[TEST2]]
1160+ ; CHECK-NEXT: ret i1 [[RES]]
1161+ ;
1162+ %cast = bitcast float %num to i32
1163+ %masked = and i32 %cast , 2139095039
1164+ %test1 = icmp ne i32 %masked , 2139095039
1165+ %test2 = icmp ne i32 %masked , 0
1166+ %res = and i1 %test1 , %test2
1167+ ret i1 %res
1168+ }
1169+
1170+ define i1 @fpclass_test_normal_invalid_constant2 (float %num ) {
1171+ ; CHECK-LABEL: define i1 @fpclass_test_normal_invalid_constant2(
1172+ ; CHECK-SAME: float [[NUM:%.*]]) {
1173+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[NUM]] to i32
1174+ ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[CAST]], 2139095040
1175+ ; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i32 [[MASKED]], 2130706432
1176+ ; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i32 [[MASKED]], 0
1177+ ; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST1]], [[TEST2]]
1178+ ; CHECK-NEXT: ret i1 [[RES]]
1179+ ;
1180+ %cast = bitcast float %num to i32
1181+ %masked = and i32 %cast , 2139095040
1182+ %test1 = icmp ne i32 %masked , 2130706432
1183+ %test2 = icmp ne i32 %masked , 0
1184+ %res = and i1 %test1 , %test2
1185+ ret i1 %res
1186+ }
1187+
1188+ define i1 @fpclass_test_normal_invalid_constant3 (float %num ) {
1189+ ; CHECK-LABEL: define i1 @fpclass_test_normal_invalid_constant3(
1190+ ; CHECK-SAME: float [[NUM:%.*]]) {
1191+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[NUM]] to i32
1192+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CAST]], 2130706432
1193+ ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[TMP1]], 2130706432
1194+ ; CHECK-NEXT: ret i1 [[RES]]
1195+ ;
1196+ %cast = bitcast float %num to i32
1197+ %masked = and i32 %cast , 2139095040
1198+ %test1 = icmp ne i32 %masked , 2139095040
1199+ %test2 = icmp ne i32 %masked , 2130706432
1200+ %res = and i1 %test1 , %test2
1201+ ret i1 %res
1202+ }
1203+
1204+ define i1 @fpclass_test_normal_multiuse (float %num ) {
1205+ ; CHECK-LABEL: define i1 @fpclass_test_normal_multiuse(
1206+ ; CHECK-SAME: float [[NUM:%.*]]) {
1207+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[NUM]] to i32
1208+ ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[CAST]], 2139095040
1209+ ; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i32 [[MASKED]], 2139095040
1210+ ; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i32 [[MASKED]], 0
1211+ ; CHECK-NEXT: call void @usei1(i1 [[TEST1]])
1212+ ; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST1]], [[TEST2]]
1213+ ; CHECK-NEXT: ret i1 [[RES]]
1214+ ;
1215+ %cast = bitcast float %num to i32
1216+ %masked = and i32 %cast , 2139095040
1217+ %test1 = icmp ne i32 %masked , 2139095040
1218+ %test2 = icmp ne i32 %masked , 0
1219+ call void @usei1 (i1 %test1 )
1220+ %res = and i1 %test1 , %test2
1221+ ret i1 %res
1222+ }
1223+
10161224declare void @usei32 (i32 )
1225+ declare void @usei1 (i1 )
10171226
10181227attributes #0 = { noimplicitfloat }
0 commit comments