1228 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4define i1 @f32_fcnan_fcinf(float %a) {5; CHECK-LABEL: define i1 @f32_fcnan_fcinf(6; CHECK-SAME: float [[A:%.*]]) {7; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])8; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[TMP1]], 0x7FF00000000000009; CHECK-NEXT: ret i1 [[CMP]]10;11 %i32 = bitcast float %a to i3212 %and = and i32 %i32, 213909504013 %cmp = icmp eq i32 %and, 213909504014 ret i1 %cmp15}16 17define i1 @f32_fcnan_fcinf_strictfp(float %a) strictfp {18; CHECK-LABEL: define i1 @f32_fcnan_fcinf_strictfp(19; CHECK-SAME: float [[A:%.*]]) #[[ATTR0:[0-9]+]] {20; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 519)21; CHECK-NEXT: ret i1 [[CMP]]22;23 %i32 = bitcast float %a to i3224 %and = and i32 %i32, 213909504025 %cmp = icmp eq i32 %and, 213909504026 ret i1 %cmp27}28 29define i1 @f32_not_fcnan_fcinf(float %a) {30; CHECK-LABEL: define i1 @f32_not_fcnan_fcinf(31; CHECK-SAME: float [[A:%.*]]) {32; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])33; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[TMP1]], 0x7FF000000000000034; CHECK-NEXT: ret i1 [[CMP]]35;36 %i32 = bitcast float %a to i3237 %and = and i32 %i32, 213909504038 %cmp = icmp ne i32 %and, 213909504039 ret i1 %cmp40}41 42define i1 @f32_not_fcnan_fcinf_strictfp(float %a) strictfp {43; CHECK-LABEL: define i1 @f32_not_fcnan_fcinf_strictfp(44; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {45; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 504)46; CHECK-NEXT: ret i1 [[CMP]]47;48 %i32 = bitcast float %a to i3249 %and = and i32 %i32, 213909504050 %cmp = icmp ne i32 %and, 213909504051 ret i1 %cmp52}53 54define i1 @f64_fcnan_fcinf(double %a) {55; CHECK-LABEL: define i1 @f64_fcnan_fcinf(56; CHECK-SAME: double [[A:%.*]]) {57; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[A]])58; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[TMP1]], 0x7FF000000000000059; CHECK-NEXT: ret i1 [[CMP]]60;61 %i64 = bitcast double %a to i6462 %and = and i64 %i64, 921886843722740531263 %cmp = icmp eq i64 %and, 921886843722740531264 ret i1 %cmp65}66 67define i1 @f64_fcnan_fcinf_strictfp(double %a) strictfp {68; CHECK-LABEL: define i1 @f64_fcnan_fcinf_strictfp(69; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] {70; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f64(double [[A]], i32 519)71; CHECK-NEXT: ret i1 [[CMP]]72;73 %i64 = bitcast double %a to i6474 %and = and i64 %i64, 921886843722740531275 %cmp = icmp eq i64 %and, 921886843722740531276 ret i1 %cmp77}78 79define i1 @f32_fcinf(float %a) {80; CHECK-LABEL: define i1 @f32_fcinf(81; CHECK-SAME: float [[A:%.*]]) {82; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])83; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[TMP1]], 0x7FF000000000000084; CHECK-NEXT: ret i1 [[CMP]]85;86 %i32 = bitcast float %a to i3287 %and = and i32 %i32, 214748364788 %cmp = icmp eq i32 %and, 213909504089 ret i1 %cmp90}91 92define i1 @f32_fcinf_strictfp(float %a) strictfp {93; CHECK-LABEL: define i1 @f32_fcinf_strictfp(94; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {95; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 516)96; CHECK-NEXT: ret i1 [[CMP]]97;98 %i32 = bitcast float %a to i3299 %and = and i32 %i32, 2147483647100 %cmp = icmp eq i32 %and, 2139095040101 ret i1 %cmp102}103 104define i1 @f32_fcposinf(float %a) {105; CHECK-LABEL: define i1 @f32_fcposinf(106; CHECK-SAME: float [[A:%.*]]) {107; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0x7FF0000000000000108; CHECK-NEXT: ret i1 [[CMP]]109;110 %i32 = bitcast float %a to i32111 %cmp = icmp eq i32 %i32, 2139095040112 ret i1 %cmp113}114 115define i1 @f32_fcposinf_strictfp(float %a) strictfp {116; CHECK-LABEL: define i1 @f32_fcposinf_strictfp(117; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {118; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 512)119; CHECK-NEXT: ret i1 [[CMP]]120;121 %i32 = bitcast float %a to i32122 %cmp = icmp eq i32 %i32, 2139095040123 ret i1 %cmp124}125 126define i1 @f32_fcneginf(float %a) {127; CHECK-LABEL: define i1 @f32_fcneginf(128; CHECK-SAME: float [[A:%.*]]) {129; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0xFFF0000000000000130; CHECK-NEXT: ret i1 [[CMP]]131;132 %i32 = bitcast float %a to i32133 %cmp = icmp eq i32 %i32, 4286578688134 ret i1 %cmp135}136 137define i1 @f32_fcneginf_strictfp(float %a) strictfp {138; CHECK-LABEL: define i1 @f32_fcneginf_strictfp(139; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {140; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 4)141; CHECK-NEXT: ret i1 [[CMP]]142;143 %i32 = bitcast float %a to i32144 %cmp = icmp eq i32 %i32, 4286578688145 ret i1 %cmp146}147 148define i1 @f32_fcposzero(float %a) {149; CHECK-LABEL: define i1 @f32_fcposzero(150; CHECK-SAME: float [[A:%.*]]) {151; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 64)152; CHECK-NEXT: ret i1 [[CMP]]153;154 %i32 = bitcast float %a to i32155 %cmp = icmp eq i32 %i32, 0156 ret i1 %cmp157}158 159define i1 @f32_fcposzero_strictfp(float %a) strictfp {160; CHECK-LABEL: define i1 @f32_fcposzero_strictfp(161; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {162; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 64)163; CHECK-NEXT: ret i1 [[CMP]]164;165 %i32 = bitcast float %a to i32166 %cmp = icmp eq i32 %i32, 0167 ret i1 %cmp168}169 170define i1 @f32_fcnegzero(float %a) {171; CHECK-LABEL: define i1 @f32_fcnegzero(172; CHECK-SAME: float [[A:%.*]]) {173; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 32)174; CHECK-NEXT: ret i1 [[CMP]]175;176 %i32 = bitcast float %a to i32177 %cmp = icmp eq i32 %i32, 2147483648178 ret i1 %cmp179}180 181define i1 @f32_fcnegzero_strictfp(float %a) strictfp {182; CHECK-LABEL: define i1 @f32_fcnegzero_strictfp(183; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {184; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 32)185; CHECK-NEXT: ret i1 [[CMP]]186;187 %i32 = bitcast float %a to i32188 %cmp = icmp eq i32 %i32, 2147483648189 ret i1 %cmp190}191 192define i1 @f32_fczero(float %a) {193; CHECK-LABEL: define i1 @f32_fczero(194; CHECK-SAME: float [[A:%.*]]) {195; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0.000000e+00196; CHECK-NEXT: ret i1 [[CMP]]197;198 %i32 = bitcast float %a to i32199 %and = and i32 %i32, 2147483647200 %cmp = icmp eq i32 %and, 0201 ret i1 %cmp202}203 204define i1 @f32_fczero_strictfp(float %a) strictfp {205; CHECK-LABEL: define i1 @f32_fczero_strictfp(206; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {207; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 96)208; CHECK-NEXT: ret i1 [[CMP]]209;210 %i32 = bitcast float %a to i32211 %and = and i32 %i32, 2147483647212 %cmp = icmp eq i32 %and, 0213 ret i1 %cmp214}215 216; TODO: handle more fpclass check idioms217define i1 @f32_fcnan(float %a) {218; CHECK-LABEL: define i1 @f32_fcnan(219; CHECK-SAME: float [[A:%.*]]) {220; CHECK-NEXT: [[RES:%.*]] = fcmp uno float [[A]], 0.000000e+00221; CHECK-NEXT: ret i1 [[RES]]222;223 %i32 = bitcast float %a to i32224 %and1 = and i32 %i32, 2139095040225 %cmp1 = icmp eq i32 %and1, 2139095040226 %and2 = and i32 %i32, 8388607227 %cmp2 = icmp ne i32 %and2, 0228 %res = and i1 %cmp1, %cmp2229 ret i1 %res230}231 232define i1 @f32_fcnan_strictfp(float %a) strictfp {233; CHECK-LABEL: define i1 @f32_fcnan_strictfp(234; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {235; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32236; CHECK-NEXT: [[AND1:%.*]] = and i32 [[I32]], 2139095040237; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 2139095040238; CHECK-NEXT: [[AND2:%.*]] = and i32 [[I32]], 8388607239; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[AND2]], 0240; CHECK-NEXT: [[RES:%.*]] = and i1 [[CMP1]], [[CMP2]]241; CHECK-NEXT: ret i1 [[RES]]242;243 %i32 = bitcast float %a to i32244 %and1 = and i32 %i32, 2139095040245 %cmp1 = icmp eq i32 %and1, 2139095040246 %and2 = and i32 %i32, 8388607247 %cmp2 = icmp ne i32 %and2, 0248 %res = and i1 %cmp1, %cmp2249 ret i1 %res250}251 252define <2 x i1> @f32_fcnan_fcinf_vec(<2 x float> %a) {253; CHECK-LABEL: define <2 x i1> @f32_fcnan_fcinf_vec(254; CHECK-SAME: <2 x float> [[A:%.*]]) {255; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[A]])256; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq <2 x float> [[TMP1]], splat (float 0x7FF0000000000000)257; CHECK-NEXT: ret <2 x i1> [[CMP]]258;259 %i32 = bitcast <2 x float> %a to <2 x i32>260 %and = and <2 x i32> %i32, <i32 2139095040, i32 2139095040>261 %cmp = icmp eq <2 x i32> %and, <i32 2139095040, i32 2139095040>262 ret <2 x i1> %cmp263}264 265define <2 x i1> @f32_fcnan_fcinf_vec_strictfp(<2 x float> %a) strictfp {266; CHECK-LABEL: define <2 x i1> @f32_fcnan_fcinf_vec_strictfp(267; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] {268; CHECK-NEXT: [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A]], i32 519)269; CHECK-NEXT: ret <2 x i1> [[CMP]]270;271 %i32 = bitcast <2 x float> %a to <2 x i32>272 %and = and <2 x i32> %i32, <i32 2139095040, i32 2139095040>273 %cmp = icmp eq <2 x i32> %and, <i32 2139095040, i32 2139095040>274 ret <2 x i1> %cmp275}276 277define <2 x i1> @f32_fcinf_vec(<2 x float> %a) {278; CHECK-LABEL: define <2 x i1> @f32_fcinf_vec(279; CHECK-SAME: <2 x float> [[A:%.*]]) {280; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[A]])281; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <2 x float> [[TMP1]], splat (float 0x7FF0000000000000)282; CHECK-NEXT: ret <2 x i1> [[CMP]]283;284 %i32 = bitcast <2 x float> %a to <2 x i32>285 %and = and <2 x i32> %i32, <i32 2147483647, i32 2147483647>286 %cmp = icmp eq <2 x i32> %and, <i32 2139095040, i32 2139095040>287 ret <2 x i1> %cmp288}289 290define <2 x i1> @f32_fcinf_vec_strictfp(<2 x float> %a) strictfp {291; CHECK-LABEL: define <2 x i1> @f32_fcinf_vec_strictfp(292; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] {293; CHECK-NEXT: [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A]], i32 516)294; CHECK-NEXT: ret <2 x i1> [[CMP]]295;296 %i32 = bitcast <2 x float> %a to <2 x i32>297 %and = and <2 x i32> %i32, <i32 2147483647, i32 2147483647>298 %cmp = icmp eq <2 x i32> %and, <i32 2139095040, i32 2139095040>299 ret <2 x i1> %cmp300}301 302; Negative tests303 304define i1 @f32_fcnan_fcinf_wrong_mask1(float %a) {305; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask1(306; CHECK-SAME: float [[A:%.*]]) {307; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32308; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095041309; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040310; CHECK-NEXT: ret i1 [[CMP]]311;312 %i32 = bitcast float %a to i32313 %and = and i32 %i32, 2139095041314 %cmp = icmp eq i32 %and, 2139095040315 ret i1 %cmp316}317 318define i1 @f32_fcnan_fcinf_wrong_mask1_strictfp(float %a) strictfp {319; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask1_strictfp(320; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {321; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32322; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095041323; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040324; CHECK-NEXT: ret i1 [[CMP]]325;326 %i32 = bitcast float %a to i32327 %and = and i32 %i32, 2139095041328 %cmp = icmp eq i32 %and, 2139095040329 ret i1 %cmp330}331 332define i1 @f32_fcnan_fcinf_wrong_mask2(float %a) {333; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask2(334; CHECK-SAME: float [[A:%.*]]) {335; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32336; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040337; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2130706432338; CHECK-NEXT: ret i1 [[CMP]]339;340 %i32 = bitcast float %a to i32341 %and = and i32 %i32, 2139095040342 %cmp = icmp eq i32 %and, 2130706432343 ret i1 %cmp344}345 346define i1 @f32_fcnan_fcinf_wrong_mask2_strictfp(float %a) strictfp {347; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask2_strictfp(348; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {349; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32350; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040351; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2130706432352; CHECK-NEXT: ret i1 [[CMP]]353;354 %i32 = bitcast float %a to i32355 %and = and i32 %i32, 2139095040356 %cmp = icmp eq i32 %and, 2130706432357 ret i1 %cmp358}359 360define i1 @f64_fcnan_fcinf_wrong_mask3(double %a) {361; CHECK-LABEL: define i1 @f64_fcnan_fcinf_wrong_mask3(362; CHECK-SAME: double [[A:%.*]]) {363; CHECK-NEXT: [[I64:%.*]] = bitcast double [[A]] to i64364; CHECK-NEXT: [[AND:%.*]] = and i64 [[I64]], 2139095040365; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040366; CHECK-NEXT: ret i1 [[CMP]]367;368 %i64 = bitcast double %a to i64369 %and = and i64 %i64, 2139095040370 %cmp = icmp eq i64 %and, 2139095040371 ret i1 %cmp372}373 374define i1 @f64_fcnan_fcinf_wrong_mask3_strictfp(double %a) strictfp {375; CHECK-LABEL: define i1 @f64_fcnan_fcinf_wrong_mask3_strictfp(376; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] {377; CHECK-NEXT: [[I64:%.*]] = bitcast double [[A]] to i64378; CHECK-NEXT: [[AND:%.*]] = and i64 [[I64]], 2139095040379; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040380; CHECK-NEXT: ret i1 [[CMP]]381;382 %i64 = bitcast double %a to i64383 %and = and i64 %i64, 2139095040384 %cmp = icmp eq i64 %and, 2139095040385 ret i1 %cmp386}387 388define i1 @f32_fcnan_fcinf_wrong_pred(float %a) {389; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_pred(390; CHECK-SAME: float [[A:%.*]]) {391; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])392; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[TMP1]], 0x7FF0000000000000393; CHECK-NEXT: ret i1 [[CMP]]394;395 %i32 = bitcast float %a to i32396 %and = and i32 %i32, 2139095040397 %cmp = icmp slt i32 %and, 2139095040398 ret i1 %cmp399}400 401define i1 @f32_fcnan_fcinf_wrong_pred_strictfp(float %a) strictfp {402; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_pred_strictfp(403; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {404; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 504)405; CHECK-NEXT: ret i1 [[CMP]]406;407 %i32 = bitcast float %a to i32408 %and = and i32 %i32, 2139095040409 %cmp = icmp slt i32 %and, 2139095040410 ret i1 %cmp411}412 413define i1 @f32_fcposzero_wrong_pred(float %a) {414; CHECK-LABEL: define i1 @f32_fcposzero_wrong_pred(415; CHECK-SAME: float [[A:%.*]]) {416; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32417; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I32]], 0418; CHECK-NEXT: ret i1 [[CMP]]419;420 %i32 = bitcast float %a to i32421 %cmp = icmp slt i32 %i32, 0422 ret i1 %cmp423}424 425define i1 @f32_fcposzero_wrong_pred_strictfp(float %a) strictfp {426; CHECK-LABEL: define i1 @f32_fcposzero_wrong_pred_strictfp(427; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {428; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32429; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I32]], 0430; CHECK-NEXT: ret i1 [[CMP]]431;432 %i32 = bitcast float %a to i32433 %cmp = icmp slt i32 %i32, 0434 ret i1 %cmp435}436 437define i1 @f32_fcnan_fcinf_wrong_type1(<2 x float> %a) {438; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type1(439; CHECK-SAME: <2 x float> [[A:%.*]]) {440; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x float> [[A]] to i64441; CHECK-NEXT: [[AND:%.*]] = and i64 [[I64]], 2139095040442; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040443; CHECK-NEXT: ret i1 [[CMP]]444;445 %i64 = bitcast <2 x float> %a to i64446 %and = and i64 %i64, 2139095040447 %cmp = icmp eq i64 %and, 2139095040448 ret i1 %cmp449}450 451define i1 @f32_fcnan_fcinf_wrong_type1_strictfp(<2 x float> %a) strictfp {452; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type1_strictfp(453; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] {454; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x float> [[A]] to i64455; CHECK-NEXT: [[AND:%.*]] = and i64 [[I64]], 2139095040456; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040457; CHECK-NEXT: ret i1 [[CMP]]458;459 %i64 = bitcast <2 x float> %a to i64460 %and = and i64 %i64, 2139095040461 %cmp = icmp eq i64 %and, 2139095040462 ret i1 %cmp463}464 465define i1 @f32_fcposinf_wrong_type1(<2 x float> %a) {466; CHECK-LABEL: define i1 @f32_fcposinf_wrong_type1(467; CHECK-SAME: <2 x float> [[A:%.*]]) {468; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x float> [[A]] to i64469; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[I64]], 2139095040470; CHECK-NEXT: ret i1 [[CMP]]471;472 %i64 = bitcast <2 x float> %a to i64473 %cmp = icmp eq i64 %i64, 2139095040474 ret i1 %cmp475}476 477define i1 @f32_fcposinf_wrong_type1_strictfp(<2 x float> %a) strictfp {478; CHECK-LABEL: define i1 @f32_fcposinf_wrong_type1_strictfp(479; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] {480; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x float> [[A]] to i64481; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[I64]], 2139095040482; CHECK-NEXT: ret i1 [[CMP]]483;484 %i64 = bitcast <2 x float> %a to i64485 %cmp = icmp eq i64 %i64, 2139095040486 ret i1 %cmp487}488 489define i1 @f32_fcnan_fcinf_wrong_type2(x86_fp80 %a) {490; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type2(491; CHECK-SAME: x86_fp80 [[A:%.*]]) {492; CHECK-NEXT: [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80493; CHECK-NEXT: [[AND:%.*]] = and i80 [[I80]], 2139095040494; CHECK-NEXT: [[CMP:%.*]] = icmp eq i80 [[AND]], 2139095040495; CHECK-NEXT: ret i1 [[CMP]]496;497 %i80 = bitcast x86_fp80 %a to i80498 %and = and i80 %i80, 2139095040499 %cmp = icmp eq i80 %and, 2139095040500 ret i1 %cmp501}502 503define i1 @f32_fcnan_fcinf_wrong_type2_strictfp(x86_fp80 %a) strictfp {504; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type2_strictfp(505; CHECK-SAME: x86_fp80 [[A:%.*]]) #[[ATTR0]] {506; CHECK-NEXT: [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80507; CHECK-NEXT: [[AND:%.*]] = and i80 [[I80]], 2139095040508; CHECK-NEXT: [[CMP:%.*]] = icmp eq i80 [[AND]], 2139095040509; CHECK-NEXT: ret i1 [[CMP]]510;511 %i80 = bitcast x86_fp80 %a to i80512 %and = and i80 %i80, 2139095040513 %cmp = icmp eq i80 %and, 2139095040514 ret i1 %cmp515}516 517define i1 @f32_fcposzero_wrong_type2(x86_fp80 %a) {518; CHECK-LABEL: define i1 @f32_fcposzero_wrong_type2(519; CHECK-SAME: x86_fp80 [[A:%.*]]) {520; CHECK-NEXT: [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80521; CHECK-NEXT: [[CMP:%.*]] = icmp eq i80 [[I80]], 0522; CHECK-NEXT: ret i1 [[CMP]]523;524 %i80 = bitcast x86_fp80 %a to i80525 %cmp = icmp eq i80 %i80, 0526 ret i1 %cmp527}528 529define i1 @f32_fcposzero_wrong_type2_strictfp(x86_fp80 %a) strictfp {530; CHECK-LABEL: define i1 @f32_fcposzero_wrong_type2_strictfp(531; CHECK-SAME: x86_fp80 [[A:%.*]]) #[[ATTR0]] {532; CHECK-NEXT: [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80533; CHECK-NEXT: [[CMP:%.*]] = icmp eq i80 [[I80]], 0534; CHECK-NEXT: ret i1 [[CMP]]535;536 %i80 = bitcast x86_fp80 %a to i80537 %cmp = icmp eq i80 %i80, 0538 ret i1 %cmp539}540 541define i1 @f32_fcnan_fcinf_noimplicitfloat(float %a) #0 {542; CHECK-LABEL: define i1 @f32_fcnan_fcinf_noimplicitfloat(543; CHECK-SAME: float [[A:%.*]]) #[[ATTR1:[0-9]+]] {544; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32545; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040546; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040547; CHECK-NEXT: ret i1 [[CMP]]548;549 %i32 = bitcast float %a to i32550 %and = and i32 %i32, 2139095040551 %cmp = icmp eq i32 %and, 2139095040552 ret i1 %cmp553}554 555define i1 @f32_fcnan_fcinf_noimplicitfloat_strictfp(float %a) strictfp #0 {556; CHECK-LABEL: define i1 @f32_fcnan_fcinf_noimplicitfloat_strictfp(557; CHECK-SAME: float [[A:%.*]]) #[[ATTR2:[0-9]+]] {558; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32559; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040560; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040561; CHECK-NEXT: ret i1 [[CMP]]562;563 %i32 = bitcast float %a to i32564 %and = and i32 %i32, 2139095040565 %cmp = icmp eq i32 %and, 2139095040566 ret i1 %cmp567}568 569define 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 i32576 %and = and i32 %i32, 2139095040577 %cmp = icmp eq i32 %and, 0578 ret i1 %cmp579}580 581define 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 i32588 %and = and i32 %i32, 2139095040589 %cmp = icmp ne i32 %and, 0590 ret i1 %cmp591}592 593define <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, zeroinitializer602 ret <2 x i1> %cmp603}604 605define <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, zeroinitializer614 ret <2 x i1> %cmp615}616 617define 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 i32621; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040622; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0623; CHECK-NEXT: ret i1 [[CMP]]624;625 %i32 = bitcast float %a to i32626 %and = and i32 %i32, 2139095040627 %cmp = icmp eq i32 %and, 0628 ret i1 %cmp629}630 631define 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 i32635; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095039636; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0637; CHECK-NEXT: ret i1 [[CMP]]638;639 %i32 = bitcast float %a to i32640 %and = and i32 %i32, 2139095039641 %cmp = icmp eq i32 %and, 0642 ret i1 %cmp643}644 645define 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 i32649; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040650; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2130706432651; CHECK-NEXT: ret i1 [[CMP]]652;653 %i32 = bitcast float %a to i32654 %and = and i32 %i32, 2139095040655 %cmp = icmp eq i32 %and, 2130706432656 ret i1 %cmp657}658 659define 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 i128663; CHECK-NEXT: [[AND:%.*]] = and i128 [[I128]], 170058106710732674489630815774616584192664; CHECK-NEXT: [[CMP:%.*]] = icmp eq i128 [[AND]], 0665; CHECK-NEXT: ret i1 [[CMP]]666;667 %i128 = bitcast ppc_fp128 %a to i128668 %and = and i128 %i128, 170058106710732674489630815774616584192669 %cmp = icmp eq i128 %and, 0670 ret i1 %cmp671}672 673define 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 i32677; CHECK-NEXT: call void @usei32(i32 [[I32]])678; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040679; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0680; CHECK-NEXT: ret i1 [[CMP]]681;682 %i32 = bitcast float %a to i32683 call void @usei32(i32 %i32)684 %and = and i32 %i32, 2139095040685 %cmp = icmp eq i32 %and, 0686 ret i1 %cmp687}688 689define 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 i32693; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040694; CHECK-NEXT: call void @usei32(i32 [[AND]])695; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0696; CHECK-NEXT: ret i1 [[CMP]]697;698 %i32 = bitcast float %a to i32699 %and = and i32 %i32, 2139095040700 call void @usei32(i32 %and)701 %cmp = icmp eq i32 %and, 0702 ret i1 %cmp703}704 705define i1 @f32_fcposinf_noimplicitfloat(float %a) #0 {706; CHECK-LABEL: define i1 @f32_fcposinf_noimplicitfloat(707; CHECK-SAME: float [[A:%.*]]) #[[ATTR1]] {708; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32709; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040710; CHECK-NEXT: ret i1 [[CMP]]711;712 %i32 = bitcast float %a to i32713 %cmp = icmp eq i32 %i32, 2139095040714 ret i1 %cmp715}716 717define i1 @f32_fcposinf_noimplicitfloat_strictfp(float %a) strictfp #0 {718; CHECK-LABEL: define i1 @f32_fcposinf_noimplicitfloat_strictfp(719; CHECK-SAME: float [[A:%.*]]) #[[ATTR2]] {720; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32721; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040722; CHECK-NEXT: ret i1 [[CMP]]723;724 %i32 = bitcast float %a to i32725 %cmp = icmp eq i32 %i32, 2139095040726 ret i1 %cmp727}728 729define i1 @f32_fcposnan(float %a) {730; CHECK-LABEL: define i1 @f32_fcposnan(731; CHECK-SAME: float [[A:%.*]]) {732; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32733; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095041734; CHECK-NEXT: ret i1 [[CMP]]735;736 %i32 = bitcast float %a to i32737 %cmp = icmp eq i32 %i32, 2139095041738 ret i1 %cmp739}740 741define i1 @f32_fcposnan_strictfp(float %a) strictfp {742; CHECK-LABEL: define i1 @f32_fcposnan_strictfp(743; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {744; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32745; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095041746; CHECK-NEXT: ret i1 [[CMP]]747;748 %i32 = bitcast float %a to i32749 %cmp = icmp eq i32 %i32, 2139095041750 ret i1 %cmp751}752 753define i1 @f32_fcposinf_multiuse(float %a) {754; CHECK-LABEL: define i1 @f32_fcposinf_multiuse(755; CHECK-SAME: float [[A:%.*]]) {756; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32757; CHECK-NEXT: call void @usei32(i32 [[I32]])758; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040759; CHECK-NEXT: ret i1 [[CMP]]760;761 %i32 = bitcast float %a to i32762 call void @usei32(i32 %i32)763 %cmp = icmp eq i32 %i32, 2139095040764 ret i1 %cmp765}766 767define i1 @f32_fcposinf_multiuse_strictfp(float %a) strictfp {768; CHECK-LABEL: define i1 @f32_fcposinf_multiuse_strictfp(769; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] {770; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32771; CHECK-NEXT: call void @usei32(i32 [[I32]])772; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040773; CHECK-NEXT: ret i1 [[CMP]]774;775 %i32 = bitcast float %a to i32776 call void @usei32(i32 %i32)777 %cmp = icmp eq i32 %i32, 2139095040778 ret i1 %cmp779}780 781define i1 @isnan_idiom(double %x) {782; CHECK-LABEL: define i1 @isnan_idiom(783; CHECK-SAME: double [[X:%.*]]) {784; CHECK-NEXT: [[RET:%.*]] = fcmp uno double [[X]], 0.000000e+00785; CHECK-NEXT: ret i1 [[RET]]786;787 %bits = bitcast double %x to i64788 %mask1 = and i64 %bits, 9218868437227405312789 %cond1 = icmp eq i64 %mask1, 9218868437227405312790 %mask2 = and i64 %bits, 4503599627370495791 %cond2 = icmp ne i64 %mask2, 0792 %ret = and i1 %cond1, %cond2793 ret i1 %ret794}795 796define <2 x i1> @isnan_idiom_vec(<2 x double> %x) {797; CHECK-LABEL: define <2 x i1> @isnan_idiom_vec(798; CHECK-SAME: <2 x double> [[X:%.*]]) {799; CHECK-NEXT: [[RET:%.*]] = fcmp uno <2 x double> [[X]], zeroinitializer800; CHECK-NEXT: ret <2 x i1> [[RET]]801;802 %bits = bitcast <2 x double> %x to <2 x i64>803 %mask1 = and <2 x i64> %bits, splat(i64 9218868437227405312)804 %cond1 = icmp eq <2 x i64> %mask1, splat(i64 9218868437227405312)805 %mask2 = and <2 x i64> %bits, splat(i64 4503599627370495)806 %cond2 = icmp ne <2 x i64> %mask2, zeroinitializer807 %ret = and <2 x i1> %cond1, %cond2808 ret <2 x i1> %ret809}810 811define i1 @isnan_idiom_commuted(double %x) {812; CHECK-LABEL: define i1 @isnan_idiom_commuted(813; CHECK-SAME: double [[X:%.*]]) {814; CHECK-NEXT: [[RET:%.*]] = fcmp uno double [[X]], 0.000000e+00815; CHECK-NEXT: ret i1 [[RET]]816;817 %bits = bitcast double %x to i64818 %mask1 = and i64 %bits, 9218868437227405312819 %cond1 = icmp eq i64 %mask1, 9218868437227405312820 %mask2 = and i64 %bits, 4503599627370495821 %cond2 = icmp ne i64 %mask2, 0822 %ret = and i1 %cond2, %cond1823 ret i1 %ret824}825 826define i1 @isnotnan_idiom(double %x) {827; CHECK-LABEL: define i1 @isnotnan_idiom(828; CHECK-SAME: double [[X:%.*]]) {829; CHECK-NEXT: [[RET:%.*]] = fcmp ord double [[X]], 0.000000e+00830; CHECK-NEXT: ret i1 [[RET]]831;832 %bits = bitcast double %x to i64833 %mask1 = and i64 %bits, 9218868437227405312834 %cond1 = icmp ne i64 %mask1, 9218868437227405312835 %mask2 = and i64 %bits, 4503599627370495836 %cond2 = icmp eq i64 %mask2, 0837 %ret = or i1 %cond1, %cond2838 ret i1 %ret839}840 841; negative tests842 843define i1 @isnan_idiom_strictfp(double %x) strictfp {844; CHECK-LABEL: define i1 @isnan_idiom_strictfp(845; CHECK-SAME: double [[X:%.*]]) #[[ATTR0]] {846; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64847; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312848; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312849; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495850; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0851; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]852; CHECK-NEXT: ret i1 [[RET]]853;854 %bits = bitcast double %x to i64855 %mask1 = and i64 %bits, 9218868437227405312856 %cond1 = icmp eq i64 %mask1, 9218868437227405312857 %mask2 = and i64 %bits, 4503599627370495858 %cond2 = icmp ne i64 %mask2, 0859 %ret = and i1 %cond1, %cond2860 ret i1 %ret861}862 863define i1 @isnan_idiom_wrong_pred1(double %x) {864; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred1(865; CHECK-SAME: double [[X:%.*]]) {866; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64867; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312868; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[MASK1]], 9218868437227405312869; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495870; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0871; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]872; CHECK-NEXT: ret i1 [[RET]]873;874 %bits = bitcast double %x to i64875 %mask1 = and i64 %bits, 9218868437227405312876 %cond1 = icmp ne i64 %mask1, 9218868437227405312877 %mask2 = and i64 %bits, 4503599627370495878 %cond2 = icmp ne i64 %mask2, 0879 %ret = and i1 %cond1, %cond2880 ret i1 %ret881}882 883define i1 @isnan_idiom_wrong_pred2(double %x) {884; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred2(885; CHECK-SAME: double [[X:%.*]]) {886; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]])887; CHECK-NEXT: [[RET:%.*]] = fcmp oeq double [[TMP1]], 0x7FF0000000000000888; CHECK-NEXT: ret i1 [[RET]]889;890 %bits = bitcast double %x to i64891 %mask1 = and i64 %bits, 9218868437227405312892 %cond1 = icmp eq i64 %mask1, 9218868437227405312893 %mask2 = and i64 %bits, 4503599627370495894 %cond2 = icmp eq i64 %mask2, 0895 %ret = and i1 %cond1, %cond2896 ret i1 %ret897}898 899define i1 @isnan_idiom_wrong_pred3(double %x) {900; CHECK-LABEL: define i1 @isnan_idiom_wrong_pred3(901; CHECK-SAME: double [[X:%.*]]) {902; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64903; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312904; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312905; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495906; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0907; CHECK-NEXT: [[RET:%.*]] = or i1 [[COND1]], [[COND2]]908; CHECK-NEXT: ret i1 [[RET]]909;910 %bits = bitcast double %x to i64911 %mask1 = and i64 %bits, 9218868437227405312912 %cond1 = icmp eq i64 %mask1, 9218868437227405312913 %mask2 = and i64 %bits, 4503599627370495914 %cond2 = icmp ne i64 %mask2, 0915 %ret = or i1 %cond1, %cond2916 ret i1 %ret917}918 919define i1 @isnan_idiom_wrong_mask1(double %x) {920; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask1(921; CHECK-SAME: double [[X:%.*]]) {922; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64923; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405311924; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405311925; CHECK-NEXT: ret i1 [[COND1]]926;927 %bits = bitcast double %x to i64928 %mask1 = and i64 %bits, 9218868437227405311929 %cond1 = icmp eq i64 %mask1, 9218868437227405311930 %mask2 = and i64 %bits, 4503599627370495931 %cond2 = icmp ne i64 %mask2, 0932 %ret = and i1 %cond1, %cond2933 ret i1 %ret934}935 936define i1 @isnan_idiom_wrong_mask2(double %x) {937; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask2(938; CHECK-SAME: double [[X:%.*]]) {939; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64940; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312941; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312942; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370494943; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0944; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]945; CHECK-NEXT: ret i1 [[RET]]946;947 %bits = bitcast double %x to i64948 %mask1 = and i64 %bits, 9218868437227405312949 %cond1 = icmp eq i64 %mask1, 9218868437227405312950 %mask2 = and i64 %bits, 4503599627370494951 %cond2 = icmp ne i64 %mask2, 0952 %ret = and i1 %cond1, %cond2953 ret i1 %ret954}955 956define i1 @isnan_idiom_wrong_mask3(double %x) {957; CHECK-LABEL: define i1 @isnan_idiom_wrong_mask3(958; CHECK-SAME: double [[X:%.*]]) {959; CHECK-NEXT: [[BITS:%.*]] = bitcast double [[X]] to i64960; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312961; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312962; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495963; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 4503599627370495964; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]965; CHECK-NEXT: ret i1 [[RET]]966;967 %bits = bitcast double %x to i64968 %mask1 = and i64 %bits, 9218868437227405312969 %cond1 = icmp eq i64 %mask1, 9218868437227405312970 %mask2 = and i64 %bits, 4503599627370495971 %cond2 = icmp ne i64 %mask2, 4503599627370495972 %ret = and i1 %cond1, %cond2973 ret i1 %ret974}975 976define i1 @isnan_idiom_invalid_bitcast(<2 x float> %x) {977; CHECK-LABEL: define i1 @isnan_idiom_invalid_bitcast(978; CHECK-SAME: <2 x float> [[X:%.*]]) {979; CHECK-NEXT: [[BITS:%.*]] = bitcast <2 x float> [[X]] to i64980; CHECK-NEXT: [[MASK1:%.*]] = and i64 [[BITS]], 9218868437227405312981; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[MASK1]], 9218868437227405312982; CHECK-NEXT: [[MASK2:%.*]] = and i64 [[BITS]], 4503599627370495983; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[MASK2]], 0984; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]985; CHECK-NEXT: ret i1 [[RET]]986;987 %bits = bitcast <2 x float> %x to i64988 %mask1 = and i64 %bits, 9218868437227405312989 %cond1 = icmp eq i64 %mask1, 9218868437227405312990 %mask2 = and i64 %bits, 4503599627370495991 %cond2 = icmp ne i64 %mask2, 0992 %ret = and i1 %cond1, %cond2993 ret i1 %ret994}995 996define i1 @isnan_idiom_ppc_fp128(ppc_fp128 %x) {997; CHECK-LABEL: define i1 @isnan_idiom_ppc_fp128(998; CHECK-SAME: ppc_fp128 [[X:%.*]]) {999; CHECK-NEXT: [[BITS:%.*]] = bitcast ppc_fp128 [[X]] to i1281000; CHECK-NEXT: [[MASK1:%.*]] = and i128 [[BITS]], 1700581067107326744896308157746165841921001; CHECK-NEXT: [[COND1:%.*]] = icmp eq i128 [[MASK1]], 1700581067107326744896308157746165841921002; CHECK-NEXT: [[MASK2:%.*]] = and i128 [[BITS]], 830767497365572420564879412675215351003; CHECK-NEXT: [[COND2:%.*]] = icmp ne i128 [[MASK2]], 01004; CHECK-NEXT: [[RET:%.*]] = and i1 [[COND1]], [[COND2]]1005; CHECK-NEXT: ret i1 [[RET]]1006;1007 %bits = bitcast ppc_fp128 %x to i1281008 %mask1 = and i128 %bits, 1700581067107326744896308157746165841921009 %cond1 = icmp eq i128 %mask1, 1700581067107326744896308157746165841921010 %mask2 = and i128 %bits, 830767497365572420564879412675215351011 %cond2 = icmp ne i128 %mask2, 01012 %ret = and i1 %cond1, %cond21013 ret i1 %ret1014}1015 1016define 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 i321023 %masked = and i32 %cast, 21390950401024 %test1 = icmp ne i32 %masked, 21390950401025 %test2 = icmp ne i32 %masked, 01026 %res = and i1 %test1, %test21027 ret i1 %res1028}1029 1030define 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 i161037 %masked = and i16 %cast, 317441038 %test1 = icmp ne i16 %masked, 317441039 %test2 = icmp ne i16 %masked, 01040 %res = and i1 %test1, %test21041 ret i1 %res1042}1043 1044define <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, zeroinitializer1054 %res = and <2 x i1> %test1, %test21055 ret <2 x i1> %res1056}1057 1058define 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 i321065 %masked = and i32 %cast, 21390950401066 %test1 = icmp eq i32 %masked, 21390950401067 %test2 = icmp eq i32 %masked, 01068 %res = or i1 %test1, %test21069 ret i1 %res1070}1071 1072define <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, zeroinitializer1082 %res = or <2 x i1> %test1, %test21083 ret <2 x i1> %res1084}1085 1086define 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 i321093 %masked = and i32 %cast, 21390950401094 %test1 = icmp ne i32 %masked, 21390950401095 %test2 = icmp ne i32 %masked, 01096 %res = and i1 %test2, %test11097 ret i1 %res1098}1099 1100; Negative tests1101 1102define 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 i1281106; CHECK-NEXT: [[MASKED:%.*]] = and i128 [[BITS]], 1700581067107326744896308157746165841921107; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i128 [[MASKED]], 1700581067107326744896308157746165841921108; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i128 [[MASKED]], 01109; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST2]], [[TEST1]]1110; CHECK-NEXT: ret i1 [[RES]]1111;1112 %bits = bitcast ppc_fp128 %x to i1281113 %masked = and i128 %bits, 1700581067107326744896308157746165841921114 %test1 = icmp ne i128 %masked, 1700581067107326744896308157746165841921115 %test2 = icmp ne i128 %masked, 01116 %res = and i1 %test2, %test11117 ret i1 %res1118}1119 1120define 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 i321127 %masked = and i32 %cast, 21390950401128 %test1 = icmp ne i32 %masked, 21390950401129 %test2 = icmp eq i32 %masked, 01130 %res = and i1 %test1, %test21131 ret i1 %res1132}1133 1134define 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 i321138; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[CAST]], 21390950401139; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i32 [[MASKED]], 21390950401140; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i32 [[MASKED]], 01141; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST1]], [[TEST2]]1142; CHECK-NEXT: ret i1 [[RES]]1143;1144 %cast = bitcast float %num to i321145 %masked = and i32 %cast, 21390950401146 %test1 = icmp ne i32 %masked, 21390950401147 %test2 = icmp ne i32 %masked, 01148 %res = and i1 %test1, %test21149 ret i1 %res1150}1151 1152define 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 i321156; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[CAST]], 21390950391157; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i32 [[MASKED]], 21390950391158; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i32 [[MASKED]], 01159; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST1]], [[TEST2]]1160; CHECK-NEXT: ret i1 [[RES]]1161;1162 %cast = bitcast float %num to i321163 %masked = and i32 %cast, 21390950391164 %test1 = icmp ne i32 %masked, 21390950391165 %test2 = icmp ne i32 %masked, 01166 %res = and i1 %test1, %test21167 ret i1 %res1168}1169 1170define 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 i321174; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[CAST]], 21390950401175; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i32 [[MASKED]], 21307064321176; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i32 [[MASKED]], 01177; CHECK-NEXT: [[RES:%.*]] = and i1 [[TEST1]], [[TEST2]]1178; CHECK-NEXT: ret i1 [[RES]]1179;1180 %cast = bitcast float %num to i321181 %masked = and i32 %cast, 21390950401182 %test1 = icmp ne i32 %masked, 21307064321183 %test2 = icmp ne i32 %masked, 01184 %res = and i1 %test1, %test21185 ret i1 %res1186}1187 1188define 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 i321192; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CAST]], 21307064321193; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[TMP1]], 21307064321194; CHECK-NEXT: ret i1 [[RES]]1195;1196 %cast = bitcast float %num to i321197 %masked = and i32 %cast, 21390950401198 %test1 = icmp ne i32 %masked, 21390950401199 %test2 = icmp ne i32 %masked, 21307064321200 %res = and i1 %test1, %test21201 ret i1 %res1202}1203 1204define 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 i321208; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[CAST]], 21390950401209; CHECK-NEXT: [[TEST1:%.*]] = icmp ne i32 [[MASKED]], 21390950401210; CHECK-NEXT: [[TEST2:%.*]] = icmp ne i32 [[MASKED]], 01211; 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 i321216 %masked = and i32 %cast, 21390950401217 %test1 = icmp ne i32 %masked, 21390950401218 %test2 = icmp ne i32 %masked, 01219 call void @usei1(i1 %test1)1220 %res = and i1 %test1, %test21221 ret i1 %res1222}1223 1224declare void @usei32(i32)1225declare void @usei1(i1)1226 1227attributes #0 = { noimplicitfloat }1228