llvm.org GIT mirror llvm / 51431e7
[InstSimplify] enhance fcmp fold with never-nan operand This is 1 step towards correcting our usage of fast-math-flags when applied on an fcmp. In this case, we are checking for 'nnan' on the fcmp itself rather than the operand of the fcmp. But I'm leaving that clause in until we're more confident that we can stop relying on fcmp's FMF. By using the more general "isKnownNeverNaN()", we gain a simplification shown on the tests with 'uitofp' regardless of the FMF on the fcmp (uitofp never produces a NaN). On the tests with 'fabs', we are now relying on the FMF for the call fabs instruction in addition to the FMF on the fcmp. I'll update the 'ult' case below here as a follow-up assuming no problems here. Differential Revision: https://reviews.llvm.org/D62979 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362879 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 3 months ago
2 changed file(s) with 7 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
34763476 if (match(RHS, m_AnyZeroFP())) {
34773477 switch (Pred) {
34783478 case FCmpInst::FCMP_OGE:
3479 if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI))
3479 if ((FMF.noNaNs() || isKnownNeverNaN(LHS, Q.TLI)) &&
3480 CannotBeOrderedLessThanZero(LHS, Q.TLI))
34803481 return getTrue(RetTy);
34813482 break;
34823483 case FCmpInst::FCMP_UGE:
34843485 return getTrue(RetTy);
34853486 break;
34863487 case FCmpInst::FCMP_ULT:
3488 // TODO: This should match 'oge'.
34873489 if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI))
34883490 return getFalse(RetTy);
34893491 break;
256256
257257 define i1 @UIToFP_is_positive_or_zero(i32 %x) {
258258 ; CHECK-LABEL: @UIToFP_is_positive_or_zero(
259 ; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X:%.*]] to float
260 ; CHECK-NEXT: [[R:%.*]] = fcmp oge float [[A]], 0.000000e+00
261 ; CHECK-NEXT: ret i1 [[R]]
259 ; CHECK-NEXT: ret i1 true
262260 ;
263261 %a = uitofp i32 %x to float
264262 %r = fcmp oge float %a, 0.000000e+00
267265
268266 define <2 x i1> @UIToFP_is_positive_or_zero_vec(<2 x i32> %x) {
269267 ; CHECK-LABEL: @UIToFP_is_positive_or_zero_vec(
270 ; CHECK-NEXT: [[A:%.*]] = uitofp <2 x i32> [[X:%.*]] to <2 x float>
271 ; CHECK-NEXT: [[R:%.*]] = fcmp oge <2 x float> [[A]], zeroinitializer
272 ; CHECK-NEXT: ret <2 x i1> [[R]]
268 ; CHECK-NEXT: ret <2 x i1>
273269 ;
274270 %a = uitofp <2 x i32> %x to <2 x float>
275271 %r = fcmp oge <2 x float> %a, zeroinitializer
350346
351347 define i1 @fabs_nnan_is_positive_or_zero(double %x) {
352348 ; CHECK-LABEL: @fabs_nnan_is_positive_or_zero(
353 ; CHECK-NEXT: [[FABS:%.*]] = tail call nnan double @llvm.fabs.f64(double [[X:%.*]])
354 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge double [[FABS]], 0.000000e+00
355 ; CHECK-NEXT: ret i1 [[CMP]]
349 ; CHECK-NEXT: ret i1 true
356350 ;
357351 %fabs = tail call nnan double @llvm.fabs.f64(double %x)
358352 %cmp = fcmp oge double %fabs, 0.0
361355
362356 define <2 x i1> @fabs_nnan_is_positive_or_zero_vec(<2 x double> %x) {
363357 ; CHECK-LABEL: @fabs_nnan_is_positive_or_zero_vec(
364 ; CHECK-NEXT: [[FABS:%.*]] = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> [[X:%.*]])
365 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge <2 x double> [[FABS]], zeroinitializer
366 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
358 ; CHECK-NEXT: ret <2 x i1>
367359 ;
368360 %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
369361 %cmp = fcmp oge <2 x double> %fabs, zeroinitializer