@@ -1013,6 +1013,215 @@ define i1 @isnan_idiom_ppc_fp128(ppc_fp128 %x) {
1013
1013
ret i1 %ret
1014
1014
}
1015
1015
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
+
1016
1224
declare void @usei32 (i32 )
1225
+ declare void @usei1 (i1 )
1017
1226
1018
1227
attributes #0 = { noimplicitfloat }
0 commit comments