diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 56d1259e95519..5266808c5abab 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -902,7 +902,8 @@ Instruction *InstCombinerImpl::foldIntrinsicIsFPClass(IntrinsicInst &II) { const FPClassTest OrderedMask = Mask & ~fcNan; const FPClassTest OrderedInvertedMask = ~OrderedMask & ~fcNan; - const bool IsStrict = II.isStrictFP(); + const bool IsStrict = + II.getFunction()->getAttributes().hasFnAttr(Attribute::StrictFP); Value *FNegSrc; if (match(Src0, m_FNeg(m_Value(FNegSrc)))) { diff --git a/llvm/test/Transforms/InstCombine/fpclass-check-idioms.ll b/llvm/test/Transforms/InstCombine/fpclass-check-idioms.ll index d2b4536448ebd..42c6506e34cf4 100644 --- a/llvm/test/Transforms/InstCombine/fpclass-check-idioms.ll +++ b/llvm/test/Transforms/InstCombine/fpclass-check-idioms.ll @@ -14,6 +14,18 @@ define i1 @f32_fcnan_fcinf(float %a) { ret i1 %cmp } +define i1 @f32_fcnan_fcinf_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcnan_fcinf_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 519) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %and = and i32 %i32, 2139095040 + %cmp = icmp eq i32 %and, 2139095040 + ret i1 %cmp +} + define i1 @f32_not_fcnan_fcinf(float %a) { ; CHECK-LABEL: define i1 @f32_not_fcnan_fcinf( ; CHECK-SAME: float [[A:%.*]]) { @@ -27,6 +39,18 @@ define i1 @f32_not_fcnan_fcinf(float %a) { ret i1 %cmp } +define i1 @f32_not_fcnan_fcinf_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_not_fcnan_fcinf_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 504) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %and = and i32 %i32, 2139095040 + %cmp = icmp ne i32 %and, 2139095040 + ret i1 %cmp +} + define i1 @f64_fcnan_fcinf(double %a) { ; CHECK-LABEL: define i1 @f64_fcnan_fcinf( ; CHECK-SAME: double [[A:%.*]]) { @@ -40,6 +64,18 @@ define i1 @f64_fcnan_fcinf(double %a) { ret i1 %cmp } +define i1 @f64_fcnan_fcinf_strictfp(double %a) strictfp { +; CHECK-LABEL: define i1 @f64_fcnan_fcinf_strictfp( +; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f64(double [[A]], i32 519) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i64 = bitcast double %a to i64 + %and = and i64 %i64, 9218868437227405312 + %cmp = icmp eq i64 %and, 9218868437227405312 + ret i1 %cmp +} + define i1 @f32_fcinf(float %a) { ; CHECK-LABEL: define i1 @f32_fcinf( ; CHECK-SAME: float [[A:%.*]]) { @@ -53,6 +89,18 @@ define i1 @f32_fcinf(float %a) { ret i1 %cmp } +define i1 @f32_fcinf_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcinf_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 516) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %and = and i32 %i32, 2147483647 + %cmp = icmp eq i32 %and, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcposinf(float %a) { ; CHECK-LABEL: define i1 @f32_fcposinf( ; CHECK-SAME: float [[A:%.*]]) { @@ -64,6 +112,17 @@ define i1 @f32_fcposinf(float %a) { ret i1 %cmp } +define i1 @f32_fcposinf_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcposinf_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 512) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %cmp = icmp eq i32 %i32, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcneginf(float %a) { ; CHECK-LABEL: define i1 @f32_fcneginf( ; CHECK-SAME: float [[A:%.*]]) { @@ -75,6 +134,17 @@ define i1 @f32_fcneginf(float %a) { ret i1 %cmp } +define i1 @f32_fcneginf_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcneginf_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 4) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %cmp = icmp eq i32 %i32, 4286578688 + ret i1 %cmp +} + define i1 @f32_fcposzero(float %a) { ; CHECK-LABEL: define i1 @f32_fcposzero( ; CHECK-SAME: float [[A:%.*]]) { @@ -86,6 +156,17 @@ define i1 @f32_fcposzero(float %a) { ret i1 %cmp } +define i1 @f32_fcposzero_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcposzero_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 64) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %cmp = icmp eq i32 %i32, 0 + ret i1 %cmp +} + define i1 @f32_fcnegzero(float %a) { ; CHECK-LABEL: define i1 @f32_fcnegzero( ; CHECK-SAME: float [[A:%.*]]) { @@ -97,6 +178,17 @@ define i1 @f32_fcnegzero(float %a) { ret i1 %cmp } +define i1 @f32_fcnegzero_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcnegzero_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 32) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %cmp = icmp eq i32 %i32, 2147483648 + ret i1 %cmp +} + define i1 @f32_fczero(float %a) { ; CHECK-LABEL: define i1 @f32_fczero( ; CHECK-SAME: float [[A:%.*]]) { @@ -109,6 +201,18 @@ define i1 @f32_fczero(float %a) { ret i1 %cmp } +define i1 @f32_fczero_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fczero_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 96) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %and = and i32 %i32, 2147483647 + %cmp = icmp eq i32 %and, 0 + ret i1 %cmp +} + ; TODO: handle more fpclass check idioms define i1 @f32_fcnan(float %a) { ; CHECK-LABEL: define i1 @f32_fcnan( @@ -130,17 +234,24 @@ define i1 @f32_fcnan(float %a) { ret i1 %res } -define i1 @f32_fcnan_fcinf_strictfp(float %a) strictfp { -; CHECK-LABEL: define i1 @f32_fcnan_fcinf_strictfp( -; CHECK-SAME: float [[A:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[TMP1]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[CMP]] +define i1 @f32_fcnan_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcnan_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: [[AND1:%.*]] = and i32 [[I32]], 2139095040 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 2139095040 +; CHECK-NEXT: [[AND2:%.*]] = and i32 [[I32]], 8388607 +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[AND2]], 0 +; CHECK-NEXT: [[RES:%.*]] = and i1 [[CMP1]], [[CMP2]] +; CHECK-NEXT: ret i1 [[RES]] ; %i32 = bitcast float %a to i32 - %and = and i32 %i32, 2139095040 - %cmp = icmp eq i32 %and, 2139095040 - ret i1 %cmp + %and1 = and i32 %i32, 2139095040 + %cmp1 = icmp eq i32 %and1, 2139095040 + %and2 = and i32 %i32, 8388607 + %cmp2 = icmp ne i32 %and2, 0 + %res = and i1 %cmp1, %cmp2 + ret i1 %res } define <2 x i1> @f32_fcnan_fcinf_vec(<2 x float> %a) { @@ -156,6 +267,18 @@ define <2 x i1> @f32_fcnan_fcinf_vec(<2 x float> %a) { ret <2 x i1> %cmp } +define <2 x i1> @f32_fcnan_fcinf_vec_strictfp(<2 x float> %a) strictfp { +; CHECK-LABEL: define <2 x i1> @f32_fcnan_fcinf_vec_strictfp( +; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A]], i32 519) +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %i32 = bitcast <2 x float> %a to <2 x i32> + %and = and <2 x i32> %i32, + %cmp = icmp eq <2 x i32> %and, + ret <2 x i1> %cmp +} + define <2 x i1> @f32_fcinf_vec(<2 x float> %a) { ; CHECK-LABEL: define <2 x i1> @f32_fcinf_vec( ; CHECK-SAME: <2 x float> [[A:%.*]]) { @@ -169,6 +292,18 @@ define <2 x i1> @f32_fcinf_vec(<2 x float> %a) { ret <2 x i1> %cmp } +define <2 x i1> @f32_fcinf_vec_strictfp(<2 x float> %a) strictfp { +; CHECK-LABEL: define <2 x i1> @f32_fcinf_vec_strictfp( +; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A]], i32 516) +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %i32 = bitcast <2 x float> %a to <2 x i32> + %and = and <2 x i32> %i32, + %cmp = icmp eq <2 x i32> %and, + ret <2 x i1> %cmp +} + ; Negative tests define i1 @f32_fcnan_fcinf_wrong_mask1(float %a) { @@ -185,6 +320,20 @@ define i1 @f32_fcnan_fcinf_wrong_mask1(float %a) { ret i1 %cmp } +define i1 @f32_fcnan_fcinf_wrong_mask1_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask1_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095041 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %and = and i32 %i32, 2139095041 + %cmp = icmp eq i32 %and, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcnan_fcinf_wrong_mask2(float %a) { ; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask2( ; CHECK-SAME: float [[A:%.*]]) { @@ -199,6 +348,20 @@ define i1 @f32_fcnan_fcinf_wrong_mask2(float %a) { ret i1 %cmp } +define i1 @f32_fcnan_fcinf_wrong_mask2_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_mask2_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2130706432 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %and = and i32 %i32, 2139095040 + %cmp = icmp eq i32 %and, 2130706432 + ret i1 %cmp +} + define i1 @f64_fcnan_fcinf_wrong_mask3(double %a) { ; CHECK-LABEL: define i1 @f64_fcnan_fcinf_wrong_mask3( ; CHECK-SAME: double [[A:%.*]]) { @@ -213,6 +376,20 @@ define i1 @f64_fcnan_fcinf_wrong_mask3(double %a) { ret i1 %cmp } +define i1 @f64_fcnan_fcinf_wrong_mask3_strictfp(double %a) strictfp { +; CHECK-LABEL: define i1 @f64_fcnan_fcinf_wrong_mask3_strictfp( +; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I64:%.*]] = bitcast double [[A]] to i64 +; CHECK-NEXT: [[AND:%.*]] = and i64 [[I64]], 2139095040 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i64 = bitcast double %a to i64 + %and = and i64 %i64, 2139095040 + %cmp = icmp eq i64 %and, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcnan_fcinf_wrong_pred(float %a) { ; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_pred( ; CHECK-SAME: float [[A:%.*]]) { @@ -226,6 +403,18 @@ define i1 @f32_fcnan_fcinf_wrong_pred(float %a) { ret i1 %cmp } +define i1 @f32_fcnan_fcinf_wrong_pred_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_pred_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 504) +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %and = and i32 %i32, 2139095040 + %cmp = icmp slt i32 %and, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcposzero_wrong_pred(float %a) { ; CHECK-LABEL: define i1 @f32_fcposzero_wrong_pred( ; CHECK-SAME: float [[A:%.*]]) { @@ -238,6 +427,18 @@ define i1 @f32_fcposzero_wrong_pred(float %a) { ret i1 %cmp } +define i1 @f32_fcposzero_wrong_pred_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcposzero_wrong_pred_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I32]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %cmp = icmp slt i32 %i32, 0 + ret i1 %cmp +} + define i1 @f32_fcnan_fcinf_wrong_type1(<2 x float> %a) { ; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type1( ; CHECK-SAME: <2 x float> [[A:%.*]]) { @@ -252,6 +453,20 @@ define i1 @f32_fcnan_fcinf_wrong_type1(<2 x float> %a) { ret i1 %cmp } +define i1 @f32_fcnan_fcinf_wrong_type1_strictfp(<2 x float> %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type1_strictfp( +; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x float> [[A]] to i64 +; CHECK-NEXT: [[AND:%.*]] = and i64 [[I64]], 2139095040 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[AND]], 2139095040 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i64 = bitcast <2 x float> %a to i64 + %and = and i64 %i64, 2139095040 + %cmp = icmp eq i64 %and, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcposinf_wrong_type1(<2 x float> %a) { ; CHECK-LABEL: define i1 @f32_fcposinf_wrong_type1( ; CHECK-SAME: <2 x float> [[A:%.*]]) { @@ -264,6 +479,18 @@ define i1 @f32_fcposinf_wrong_type1(<2 x float> %a) { ret i1 %cmp } +define i1 @f32_fcposinf_wrong_type1_strictfp(<2 x float> %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcposinf_wrong_type1_strictfp( +; CHECK-SAME: <2 x float> [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x float> [[A]] to i64 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[I64]], 2139095040 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i64 = bitcast <2 x float> %a to i64 + %cmp = icmp eq i64 %i64, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcnan_fcinf_wrong_type2(x86_fp80 %a) { ; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type2( ; CHECK-SAME: x86_fp80 [[A:%.*]]) { @@ -278,6 +505,20 @@ define i1 @f32_fcnan_fcinf_wrong_type2(x86_fp80 %a) { ret i1 %cmp } +define i1 @f32_fcnan_fcinf_wrong_type2_strictfp(x86_fp80 %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type2_strictfp( +; CHECK-SAME: x86_fp80 [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80 +; CHECK-NEXT: [[AND:%.*]] = and i80 [[I80]], 2139095040 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i80 [[AND]], 2139095040 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i80 = bitcast x86_fp80 %a to i80 + %and = and i80 %i80, 2139095040 + %cmp = icmp eq i80 %and, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcposzero_wrong_type2(x86_fp80 %a) { ; CHECK-LABEL: define i1 @f32_fcposzero_wrong_type2( ; CHECK-SAME: x86_fp80 [[A:%.*]]) { @@ -290,6 +531,18 @@ define i1 @f32_fcposzero_wrong_type2(x86_fp80 %a) { ret i1 %cmp } +define i1 @f32_fcposzero_wrong_type2_strictfp(x86_fp80 %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcposzero_wrong_type2_strictfp( +; CHECK-SAME: x86_fp80 [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i80 [[I80]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i80 = bitcast x86_fp80 %a to i80 + %cmp = icmp eq i80 %i80, 0 + ret i1 %cmp +} + define i1 @f32_fcnan_fcinf_noimplicitfloat(float %a) #0 { ; CHECK-LABEL: define i1 @f32_fcnan_fcinf_noimplicitfloat( ; CHECK-SAME: float [[A:%.*]]) #[[ATTR1:[0-9]+]] { @@ -304,6 +557,20 @@ define i1 @f32_fcnan_fcinf_noimplicitfloat(float %a) #0 { ret i1 %cmp } +define i1 @f32_fcnan_fcinf_noimplicitfloat_strictfp(float %a) strictfp #0 { +; CHECK-LABEL: define i1 @f32_fcnan_fcinf_noimplicitfloat_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR2:[0-9]+]] { +; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %and = and i32 %i32, 2139095040 + %cmp = icmp eq i32 %and, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcposinf_noimplicitfloat(float %a) #0 { ; CHECK-LABEL: define i1 @f32_fcposinf_noimplicitfloat( ; CHECK-SAME: float [[A:%.*]]) #[[ATTR1]] { @@ -316,6 +583,18 @@ define i1 @f32_fcposinf_noimplicitfloat(float %a) #0 { ret i1 %cmp } +define i1 @f32_fcposinf_noimplicitfloat_strictfp(float %a) strictfp #0 { +; CHECK-LABEL: define i1 @f32_fcposinf_noimplicitfloat_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %cmp = icmp eq i32 %i32, 2139095040 + ret i1 %cmp +} + define i1 @f32_fcposnan(float %a) { ; CHECK-LABEL: define i1 @f32_fcposnan( ; CHECK-SAME: float [[A:%.*]]) { @@ -328,6 +607,18 @@ define i1 @f32_fcposnan(float %a) { ret i1 %cmp } +define i1 @f32_fcposnan_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcposnan_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095041 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + %cmp = icmp eq i32 %i32, 2139095041 + ret i1 %cmp +} + define i1 @f32_fcposinf_multiuse(float %a) { ; CHECK-LABEL: define i1 @f32_fcposinf_multiuse( ; CHECK-SAME: float [[A:%.*]]) { @@ -342,6 +633,20 @@ define i1 @f32_fcposinf_multiuse(float %a) { ret i1 %cmp } +define i1 @f32_fcposinf_multiuse_strictfp(float %a) strictfp { +; CHECK-LABEL: define i1 @f32_fcposinf_multiuse_strictfp( +; CHECK-SAME: float [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: call void @usei32(i32 [[I32]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i32 = bitcast float %a to i32 + call void @usei32(i32 %i32) + %cmp = icmp eq i32 %i32, 2139095040 + ret i1 %cmp +} + declare void @usei32(i32) attributes #0 = { noimplicitfloat }