From 83ed93c0c387ca92d436e7bb3229712d3d4f665f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 9 Dec 2022 14:36:22 -0500 Subject: [PATCH] [InstCombine] add tests for fabs folds with more FMF; NFC The existing variants have "nsz", but that's not enough to get fabs/fneg semantics right with a NAN input, so I duplicated those with "nnan" tacked on. See discussion in issue #59279. --- llvm/test/Transforms/InstCombine/fabs.ll | 47 +++++++++-- llvm/test/Transforms/InstCombine/fneg-fabs.ll | 111 ++++++++++++++++++++++++-- llvm/test/Transforms/InstCombine/fneg.ll | 17 +++- 3 files changed, 159 insertions(+), 16 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/fabs.ll b/llvm/test/Transforms/InstCombine/fabs.ll index 1b9f4a3..a000693 100644 --- a/llvm/test/Transforms/InstCombine/fabs.ll +++ b/llvm/test/Transforms/InstCombine/fabs.ll @@ -349,8 +349,8 @@ define fp128 @select_fcmp_ogt_zero(fp128 %x) { ret fp128 %fabs } -define float @select_fcmp_ogt_fneg(float %a) { -; CHECK-LABEL: @select_fcmp_ogt_fneg( +define float @select_nsz_fcmp_ogt_fneg(float %a) { +; CHECK-LABEL: @select_nsz_fcmp_ogt_fneg( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz float @llvm.fabs.f32(float [[A:%.*]]) ; CHECK-NEXT: ret float [[TMP1]] ; @@ -360,6 +360,17 @@ define float @select_fcmp_ogt_fneg(float %a) { ret float %r } +define float @select_nsz_nnan_fcmp_ogt_fneg(float %a) { +; CHECK-LABEL: @select_nsz_nnan_fcmp_ogt_fneg( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[A:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] +; + %fneg = fneg float %a + %cmp = fcmp ogt float %a, %fneg + %r = select nsz nnan i1 %cmp, float %a, float %fneg + ret float %r +} + define fp128 @select_fcmp_nnan_ogt_zero(fp128 %x) { ; CHECK-LABEL: @select_fcmp_nnan_ogt_zero( ; CHECK-NEXT: [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X:%.*]]) @@ -436,8 +447,8 @@ define half @select_fcmp_nnan_oge_negzero(half %x) { ; X < 0.0 ? -X : X --> fabs(X) -define double @select_fcmp_olt_zero_unary_fneg(double %x) { -; CHECK-LABEL: @select_fcmp_olt_zero_unary_fneg( +define double @select_nsz_fcmp_olt_zero_unary_fneg(double %x) { +; CHECK-LABEL: @select_nsz_fcmp_olt_zero_unary_fneg( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]]) ; CHECK-NEXT: ret double [[TMP1]] ; @@ -447,6 +458,17 @@ define double @select_fcmp_olt_zero_unary_fneg(double %x) { ret double %fabs } +define double @select_nsz_nnan_fcmp_olt_zero_unary_fneg(double %x) { +; CHECK-LABEL: @select_nsz_nnan_fcmp_olt_zero_unary_fneg( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: ret double [[TMP1]] +; + %ltzero = fcmp olt double %x, 0.0 + %negx = fneg double %x + %fabs = select nsz nnan i1 %ltzero, double %negx, double %x + ret double %fabs +} + define double @select_fcmp_nnan_nsz_olt_zero(double %x) { ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero( ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00 @@ -721,10 +743,10 @@ define float @select_fcmp_nnan_nsz_ule_negzero_unary_fneg(float %x) { ret float %fabs } -; X > 0.0 ? X : (0.0 - X) --> fabs(X) +; X > 0.0 ? X : (-X) --> fabs(X) -define <2 x float> @select_fcmp_ogt_zero_unary_fneg(<2 x float> %x) { -; CHECK-LABEL: @select_fcmp_ogt_zero_unary_fneg( +define <2 x float> @select_nsz_fcmp_ogt_zero_unary_fneg(<2 x float> %x) { +; CHECK-LABEL: @select_nsz_fcmp_ogt_zero_unary_fneg( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]]) ; CHECK-NEXT: ret <2 x float> [[TMP1]] ; @@ -734,6 +756,17 @@ define <2 x float> @select_fcmp_ogt_zero_unary_fneg(<2 x float> %x) { ret <2 x float> %fabs } +define <2 x float> @select_nsz_nnan_fcmp_ogt_zero_unary_fneg(<2 x float> %x) { +; CHECK-LABEL: @select_nsz_nnan_fcmp_ogt_zero_unary_fneg( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]]) +; CHECK-NEXT: ret <2 x float> [[TMP1]] +; + %gtzero = fcmp ogt <2 x float> %x, zeroinitializer + %negx = fneg <2 x float> %x + %fabs = select nsz nnan <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx + ret <2 x float> %fabs +} + define <2 x float> @select_fcmp_nnan_nsz_ogt_zero(<2 x float> %x) { ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_zero( ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer diff --git a/llvm/test/Transforms/InstCombine/fneg-fabs.ll b/llvm/test/Transforms/InstCombine/fneg-fabs.ll index 665c011..f47d727 100644 --- a/llvm/test/Transforms/InstCombine/fneg-fabs.ll +++ b/llvm/test/Transforms/InstCombine/fneg-fabs.ll @@ -30,19 +30,20 @@ define double @select_nsz_nfabs_lt_fmfProp(double %x) { ret double %sel } -; Tests with various predicate types. -define double @select_nsz_nfabs_olt(double %x) { -; CHECK-LABEL: @select_nsz_nfabs_olt( -; CHECK-NEXT: [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]]) -; CHECK-NEXT: [[SEL:%.*]] = fneg nsz double [[TMP1]] +define double @select_nsz_nnan_nfabs_lt_fmfProp(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_lt_fmfProp( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] ; CHECK-NEXT: ret double [[SEL]] ; %cmp = fcmp olt double %x, 0.000000e+00 - %negX = fneg double %x - %sel = select nsz i1 %cmp, double %x, double %negX + %negX = fneg fast double %x + %sel = select nsz nnan i1 %cmp, double %x, double %negX ret double %sel } +; Tests with various predicate types. + define double @select_nsz_nfabs_ult(double %x) { ; CHECK-LABEL: @select_nsz_nfabs_ult( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]]) @@ -55,6 +56,18 @@ define double @select_nsz_nfabs_ult(double %x) { ret double %sel } +define double @select_nsz_nnan_nfabs_ult(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_ult( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] +; CHECK-NEXT: ret double [[SEL]] +; + %cmp = fcmp ult double %x, 0.000000e+00 + %negX = fneg double %x + %sel = select nsz nnan i1 %cmp, double %x, double %negX + ret double %sel +} + define double @select_nsz_nfabs_ole(double %x) { ; CHECK-LABEL: @select_nsz_nfabs_ole( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]]) @@ -67,6 +80,18 @@ define double @select_nsz_nfabs_ole(double %x) { ret double %sel } +define double @select_nsz_nnan_nfabs_ole(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_ole( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] +; CHECK-NEXT: ret double [[SEL]] +; + %cmp = fcmp ole double %x, 0.000000e+00 + %negX = fneg double %x + %sel = select nsz nnan i1 %cmp, double %x, double %negX + ret double %sel +} + define double @select_nsz_nfabs_ule(double %x) { ; CHECK-LABEL: @select_nsz_nfabs_ule( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]]) @@ -79,6 +104,18 @@ define double @select_nsz_nfabs_ule(double %x) { ret double %sel } +define double @select_nsz_nnan_nfabs_ule(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_ule( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] +; CHECK-NEXT: ret double [[SEL]] +; + %cmp = fcmp ule double %x, 0.000000e+00 + %negX = fneg double %x + %sel = select nsz nnan i1 %cmp, double %x, double %negX + ret double %sel +} + ; (X > +/-0.0) ? -X : X --> -fabs(X) ; (X >= +/-0.0) ? -X : X --> -fabs(X) ; One negative test with no fmf @@ -108,6 +145,18 @@ define double @select_nsz_nfabs_gt_fmfProp(double %x) { ret double %sel } +define double @select_nsz_nnan_nfabs_gt_fmfProp(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_gt_fmfProp( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] +; CHECK-NEXT: ret double [[SEL]] +; + %cmp = fcmp ogt double %x, 0.000000e+00 + %negX = fneg fast double %x + %sel = select nsz nnan i1 %cmp, double %negX, double %x + ret double %sel +} + ; Tests with various predicate types. define double @select_nsz_nfabs_ogt(double %x) { ; CHECK-LABEL: @select_nsz_nfabs_ogt( @@ -121,6 +170,18 @@ define double @select_nsz_nfabs_ogt(double %x) { ret double %sel } +define double @select_nsz_nnan_nfabs_ogt(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_ogt( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] +; CHECK-NEXT: ret double [[SEL]] +; + %cmp = fcmp ogt double %x, 0.000000e+00 + %negX = fneg double %x + %sel = select nsz nnan i1 %cmp, double %negX, double %x + ret double %sel +} + define double @select_nsz_nfabs_ugt(double %x) { ; CHECK-LABEL: @select_nsz_nfabs_ugt( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]]) @@ -133,6 +194,18 @@ define double @select_nsz_nfabs_ugt(double %x) { ret double %sel } +define double @select_nsz_nnan_nfabs_ugt(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_ugt( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] +; CHECK-NEXT: ret double [[SEL]] +; + %cmp = fcmp ugt double %x, 0.000000e+00 + %negX = fneg double %x + %sel = select nsz nnan i1 %cmp, double %negX, double %x + ret double %sel +} + define double @select_nsz_nfabs_oge(double %x) { ; CHECK-LABEL: @select_nsz_nfabs_oge( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]]) @@ -145,6 +218,18 @@ define double @select_nsz_nfabs_oge(double %x) { ret double %sel } +define double @select_nsz_nnan_nfabs_oge(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_oge( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] +; CHECK-NEXT: ret double [[SEL]] +; + %cmp = fcmp oge double %x, 0.000000e+00 + %negX = fneg double %x + %sel = select nsz nnan i1 %cmp, double %negX, double %x + ret double %sel +} + define double @select_nsz_nfabs_uge(double %x) { ; CHECK-LABEL: @select_nsz_nfabs_uge( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]]) @@ -157,6 +242,18 @@ define double @select_nsz_nfabs_uge(double %x) { ret double %sel } +define double @select_nsz_nnan_nfabs_uge(double %x) { +; CHECK-LABEL: @select_nsz_nnan_nfabs_uge( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]] +; CHECK-NEXT: ret double [[SEL]] +; + %cmp = fcmp uge double %x, 0.000000e+00 + %negX = fneg double %x + %sel = select nsz nnan i1 %cmp, double %negX, double %x + ret double %sel +} + ; (X < +/-0.0) ? X : (0.0 - X) --> (0.0 - fabs(X)) ; One negative test with <=. define double @select_noFMF_fsubfabs_le(double %x) { diff --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll index 2c47b33..00d8539 100644 --- a/llvm/test/Transforms/InstCombine/fneg.ll +++ b/llvm/test/Transforms/InstCombine/fneg.ll @@ -742,8 +742,8 @@ define float @fnabs_1(float %a) { ret float %fneg1 } -define float @fnabs_2(float %a) { -; CHECK-LABEL: @fnabs_2( +define float @fnabs_2_nsz(float %a) { +; CHECK-LABEL: @fnabs_2_nsz( ; CHECK-NEXT: [[TMP1:%.*]] = call nsz float @llvm.fabs.f32(float [[A:%.*]]) ; CHECK-NEXT: [[FNEG1:%.*]] = fneg float [[TMP1]] ; CHECK-NEXT: ret float [[FNEG1]] @@ -755,6 +755,19 @@ define float @fnabs_2(float %a) { ret float %fneg1 } +define float @fnabs_2_nsz_nnan(float %a) { +; CHECK-LABEL: @fnabs_2_nsz_nnan( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[A:%.*]]) +; CHECK-NEXT: [[FNEG1:%.*]] = fneg float [[TMP1]] +; CHECK-NEXT: ret float [[FNEG1]] +; + %fneg = fneg float %a + %cmp = fcmp olt float %a, %fneg + %sel = select nsz nnan i1 %cmp, float %fneg, float %a + %fneg1 = fneg float %sel + ret float %fneg1 +} + define float @select_fneg_both(float %x, float %y, i1 %b) { ; CHECK-LABEL: @select_fneg_both( ; CHECK-NEXT: [[S_V:%.*]] = select i1 [[B:%.*]], float [[X:%.*]], float [[Y:%.*]] -- 2.7.4