https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/174846
>From 75415744a7a1a20af2771e9d47ed4e031460b795 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Wed, 7 Jan 2026 19:45:18 +0100 Subject: [PATCH] ValueTracking: sqrt never returns subnormal --- llvm/lib/Support/KnownFPClass.cpp | 1 + .../Transforms/Attributor/nofpclass-sqrt.ll | 104 +++++++++--------- .../simplify-demanded-fpclass-sqrt.ll | 7 +- llvm/unittests/Analysis/ValueTrackingTest.cpp | 28 ++--- 4 files changed, 69 insertions(+), 71 deletions(-) diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp index b8f6d97d1ee99..26cfb32f986f2 100644 --- a/llvm/lib/Support/KnownFPClass.cpp +++ b/llvm/lib/Support/KnownFPClass.cpp @@ -333,6 +333,7 @@ KnownFPClass KnownFPClass::log(const KnownFPClass &KnownSrc, KnownFPClass KnownFPClass::sqrt(const KnownFPClass &KnownSrc, DenormalMode Mode) { KnownFPClass Known; + Known.knownNot(fcPosSubnormal); if (KnownSrc.isKnownNeverPosInfinity()) Known.knownNot(fcPosInf); diff --git a/llvm/test/Transforms/Attributor/nofpclass-sqrt.ll b/llvm/test/Transforms/Attributor/nofpclass-sqrt.ll index 0a818c3f9e0bf..91831cd4621c9 100644 --- a/llvm/test/Transforms/Attributor/nofpclass-sqrt.ll +++ b/llvm/test/Transforms/Attributor/nofpclass-sqrt.ll @@ -6,9 +6,9 @@ declare <2 x float> @llvm.sqrt.v2f32(<2 x float>) declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata) define float @ret_sqrt(float %arg0) #0 { -; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_sqrt +; CHECK-LABEL: define nofpclass(ninf sub nnorm) float @ret_sqrt ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.sqrt.f32(float [[ARG0]]) #[[ATTR10:[0-9]+]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf sub nnorm) float @llvm.sqrt.f32(float [[ARG0]]) #[[ATTR10:[0-9]+]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -16,9 +16,9 @@ define float @ret_sqrt(float %arg0) #0 { } define float @ret_sqrt_noinf(float nofpclass(inf) %arg0) #0 { -; CHECK-LABEL: define nofpclass(inf nsub nnorm) float @ret_sqrt_noinf +; CHECK-LABEL: define nofpclass(inf sub nnorm) float @ret_sqrt_noinf ; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -26,9 +26,9 @@ define float @ret_sqrt_noinf(float nofpclass(inf) %arg0) #0 { } define float @ret_sqrt_nopinf(float nofpclass(pinf) %arg0) #0 { -; CHECK-LABEL: define nofpclass(inf nsub nnorm) float @ret_sqrt_nopinf +; CHECK-LABEL: define nofpclass(inf sub nnorm) float @ret_sqrt_nopinf ; CHECK-SAME: (float nofpclass(pinf) [[ARG0:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(pinf) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf sub nnorm) float @llvm.sqrt.f32(float nofpclass(pinf) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -36,9 +36,9 @@ define float @ret_sqrt_nopinf(float nofpclass(pinf) %arg0) #0 { } define float @ret_sqrt_noninf(float nofpclass(ninf) %arg0) #0 { -; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_sqrt_noninf +; CHECK-LABEL: define nofpclass(ninf sub nnorm) float @ret_sqrt_noninf ; CHECK-SAME: (float nofpclass(ninf) [[ARG0:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(ninf) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf sub nnorm) float @llvm.sqrt.f32(float nofpclass(ninf) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -46,9 +46,9 @@ define float @ret_sqrt_noninf(float nofpclass(ninf) %arg0) #0 { } define float @ret_sqrt_nonan(float nofpclass(nan) %arg0) #0 { -; CHECK-LABEL: define nofpclass(snan ninf nsub nnorm) float @ret_sqrt_nonan +; CHECK-LABEL: define nofpclass(snan ninf sub nnorm) float @ret_sqrt_nonan ; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan ninf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(nan) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan ninf sub nnorm) float @llvm.sqrt.f32(float nofpclass(nan) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -56,9 +56,9 @@ define float @ret_sqrt_nonan(float nofpclass(nan) %arg0) #0 { } define float @ret_sqrt_nonan_noinf(float nofpclass(nan inf) %arg0) #0 { -; CHECK-LABEL: define nofpclass(snan inf nsub nnorm) float @ret_sqrt_nonan_noinf +; CHECK-LABEL: define nofpclass(snan inf sub nnorm) float @ret_sqrt_nonan_noinf ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(nan inf) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub nnorm) float @llvm.sqrt.f32(float nofpclass(nan inf) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -66,9 +66,9 @@ define float @ret_sqrt_nonan_noinf(float nofpclass(nan inf) %arg0) #0 { } define float @ret_sqrt_nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0) #0 { -; CHECK-LABEL: define nofpclass(snan inf nzero nsub nnorm) float @ret_sqrt_nonan_noinf_nozero +; CHECK-LABEL: define nofpclass(snan inf nzero sub nnorm) float @ret_sqrt_nonan_noinf_nozero ; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf nzero nsub nnorm) float @llvm.sqrt.f32(float nofpclass(nan inf zero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf nzero sub nnorm) float @llvm.sqrt.f32(float nofpclass(nan inf zero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -76,9 +76,9 @@ define float @ret_sqrt_nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0) # } define float @ret_sqrt_noinf_nozero(float nofpclass(inf zero) %arg0) #0 { -; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_sqrt_noinf_nozero +; CHECK-LABEL: define nofpclass(inf nzero sub nnorm) float @ret_sqrt_noinf_nozero ; CHECK-SAME: (float nofpclass(inf zero) [[ARG0:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -86,9 +86,9 @@ define float @ret_sqrt_noinf_nozero(float nofpclass(inf zero) %arg0) #0 { } define float @ret_sqrt_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #0 { -; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_sqrt_noinf_nonegzero +; CHECK-LABEL: define nofpclass(inf nzero sub nnorm) float @ret_sqrt_noinf_nonegzero ; CHECK-SAME: (float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -96,10 +96,10 @@ define float @ret_sqrt_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #0 { } define float @ret_sqrt_positive_source(i32 %arg) #0 { -; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @ret_sqrt_positive_source +; CHECK-LABEL: define nofpclass(nan inf nzero sub nnorm) float @ret_sqrt_positive_source ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[UITOFP:%.*]] = uitofp i32 [[ARG]] to float -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.sqrt.f32(float [[UITOFP]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan inf nzero sub nnorm) float @llvm.sqrt.f32(float [[UITOFP]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %uitofp = uitofp i32 %arg to float @@ -109,10 +109,10 @@ define float @ret_sqrt_positive_source(i32 %arg) #0 { ; Could produce a nan because we don't know if the multiply is negative. define float @ret_sqrt_unknown_sign(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) #0 { -; CHECK-LABEL: define nofpclass(snan ninf nsub nnorm) float @ret_sqrt_unknown_sign +; CHECK-LABEL: define nofpclass(snan ninf sub nnorm) float @ret_sqrt_unknown_sign ; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[UNKNOWN_SIGN_NOT_NAN:%.*]] = fmul nnan float [[ARG0]], [[ARG1]] -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan ninf nsub nnorm) float @llvm.sqrt.f32(float [[UNKNOWN_SIGN_NOT_NAN]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan ninf sub nnorm) float @llvm.sqrt.f32(float [[UNKNOWN_SIGN_NOT_NAN]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %unknown.sign.not.nan = fmul nnan float %arg0, %arg1 @@ -121,9 +121,9 @@ define float @ret_sqrt_unknown_sign(float nofpclass(nan) %arg0, float nofpclass( } define float @ret_sqrt_daz_noinf_nozero(float nofpclass(inf zero) %arg0) #1 { -; CHECK-LABEL: define nofpclass(inf nsub nnorm) float @ret_sqrt_daz_noinf_nozero +; CHECK-LABEL: define nofpclass(inf sub nnorm) float @ret_sqrt_daz_noinf_nozero ; CHECK-SAME: (float nofpclass(inf zero) [[ARG0:%.*]]) #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -131,9 +131,9 @@ define float @ret_sqrt_daz_noinf_nozero(float nofpclass(inf zero) %arg0) #1 { } define <2 x float> @ret_sqrt_daz_noinf_nozero_v2f32(<2 x float> nofpclass(inf zero) %arg0) #1 { -; CHECK-LABEL: define nofpclass(inf nsub nnorm) <2 x float> @ret_sqrt_daz_noinf_nozero_v2f32 +; CHECK-LABEL: define nofpclass(inf sub nnorm) <2 x float> @ret_sqrt_daz_noinf_nozero_v2f32 ; CHECK-SAME: (<2 x float> nofpclass(inf zero) [[ARG0:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nsub nnorm) <2 x float> @llvm.sqrt.v2f32(<2 x float> nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf sub nnorm) <2 x float> @llvm.sqrt.v2f32(<2 x float> nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret <2 x float> [[CALL]] ; %call = call <2 x float> @llvm.sqrt.v2f32(<2 x float> %arg0) @@ -141,9 +141,9 @@ define <2 x float> @ret_sqrt_daz_noinf_nozero_v2f32(<2 x float> nofpclass(inf ze } define float @ret_sqrt_daz_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #1 { -; CHECK-LABEL: define nofpclass(inf nsub nnorm) float @ret_sqrt_daz_noinf_nonegzero +; CHECK-LABEL: define nofpclass(inf sub nnorm) float @ret_sqrt_daz_noinf_nonegzero ; CHECK-SAME: (float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -151,9 +151,9 @@ define float @ret_sqrt_daz_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #1 } define float @ret_sqrt_dapz_noinf_nozero(float nofpclass(inf zero) %arg0) #2 { -; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_sqrt_dapz_noinf_nozero +; CHECK-LABEL: define nofpclass(inf nzero sub nnorm) float @ret_sqrt_dapz_noinf_nozero ; CHECK-SAME: (float nofpclass(inf zero) [[ARG0:%.*]]) #[[ATTR4:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -161,9 +161,9 @@ define float @ret_sqrt_dapz_noinf_nozero(float nofpclass(inf zero) %arg0) #2 { } define float @ret_sqrt_dapz_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #2 { -; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_sqrt_dapz_noinf_nonegzero +; CHECK-LABEL: define nofpclass(inf nzero sub nnorm) float @ret_sqrt_dapz_noinf_nonegzero ; CHECK-SAME: (float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR4]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -171,9 +171,9 @@ define float @ret_sqrt_dapz_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #2 } define float @ret_sqrt_dynamic_noinf_nozero(float nofpclass(inf zero) %arg0) #3 { -; CHECK-LABEL: define nofpclass(inf nsub nnorm) float @ret_sqrt_dynamic_noinf_nozero +; CHECK-LABEL: define nofpclass(inf sub nnorm) float @ret_sqrt_dynamic_noinf_nozero ; CHECK-SAME: (float nofpclass(inf zero) [[ARG0:%.*]]) #[[ATTR5:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -181,9 +181,9 @@ define float @ret_sqrt_dynamic_noinf_nozero(float nofpclass(inf zero) %arg0) #3 } define float @ret_sqrt_dynamic_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #3 { -; CHECK-LABEL: define nofpclass(inf nsub nnorm) float @ret_sqrt_dynamic_noinf_nonegzero +; CHECK-LABEL: define nofpclass(inf sub nnorm) float @ret_sqrt_dynamic_noinf_nonegzero ; CHECK-SAME: (float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR5]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -191,9 +191,9 @@ define float @ret_sqrt_dynamic_noinf_nonegzero(float nofpclass(inf nzero) %arg0) } define float @ret_sqrt_ftz_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #4 { -; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_sqrt_ftz_noinf_nonegzero +; CHECK-LABEL: define nofpclass(inf nzero sub nnorm) float @ret_sqrt_ftz_noinf_nonegzero ; CHECK-SAME: (float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR6:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -201,9 +201,9 @@ define float @ret_sqrt_ftz_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #4 } define float @ret_sqrt_ftpz_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #5 { -; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_sqrt_ftpz_noinf_nonegzero +; CHECK-LABEL: define nofpclass(inf nzero sub nnorm) float @ret_sqrt_ftpz_noinf_nonegzero ; CHECK-SAME: (float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR7:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -211,9 +211,9 @@ define float @ret_sqrt_ftpz_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #5 } define float @ret_sqrt_ftz_dynamic_noinf_nonegzero(float nofpclass(inf nzero) %arg0) #6 { -; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_sqrt_ftz_dynamic_noinf_nonegzero +; CHECK-LABEL: define nofpclass(inf nzero sub nnorm) float @ret_sqrt_ftz_dynamic_noinf_nonegzero ; CHECK-SAME: (float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR8:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf nzero sub nnorm) float @llvm.sqrt.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR10]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.sqrt.f32(float %arg0) @@ -221,9 +221,9 @@ define float @ret_sqrt_ftz_dynamic_noinf_nonegzero(float nofpclass(inf nzero) %a } define float @constrained_sqrt(float %arg) strictfp { -; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @constrained_sqrt +; CHECK-LABEL: define nofpclass(ninf sub nnorm) float @constrained_sqrt ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR9:[0-9]+]] { -; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.experimental.constrained.sqrt.f32(float [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11:[0-9]+]] +; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(ninf sub nnorm) float @llvm.experimental.constrained.sqrt.f32(float [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11:[0-9]+]] ; CHECK-NEXT: ret float [[VAL]] ; %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") @@ -231,9 +231,9 @@ define float @constrained_sqrt(float %arg) strictfp { } define float @constrained_sqrt_nonan(float nofpclass(nan) %arg) strictfp { -; CHECK-LABEL: define nofpclass(snan ninf nsub nnorm) float @constrained_sqrt_nonan +; CHECK-LABEL: define nofpclass(snan ninf sub nnorm) float @constrained_sqrt_nonan ; CHECK-SAME: (float nofpclass(nan) [[ARG:%.*]]) #[[ATTR9]] { -; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(snan ninf nsub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(nan) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11]] +; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(snan ninf sub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(nan) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11]] ; CHECK-NEXT: ret float [[VAL]] ; %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") @@ -241,9 +241,9 @@ define float @constrained_sqrt_nonan(float nofpclass(nan) %arg) strictfp { } define float @constrained_sqrt_nopinf(float nofpclass(pinf) %arg) strictfp { -; CHECK-LABEL: define nofpclass(inf nsub nnorm) float @constrained_sqrt_nopinf +; CHECK-LABEL: define nofpclass(inf sub nnorm) float @constrained_sqrt_nopinf ; CHECK-SAME: (float nofpclass(pinf) [[ARG:%.*]]) #[[ATTR9]] { -; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(inf nsub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(pinf) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11]] +; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(inf sub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(pinf) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11]] ; CHECK-NEXT: ret float [[VAL]] ; %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") @@ -251,9 +251,9 @@ define float @constrained_sqrt_nopinf(float nofpclass(pinf) %arg) strictfp { } define float @constrained_sqrt_nonegzero(float nofpclass(nzero) %arg) strictfp { -; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @constrained_sqrt_nonegzero +; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @constrained_sqrt_nonegzero ; CHECK-SAME: (float nofpclass(nzero) [[ARG:%.*]]) #[[ATTR9]] { -; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(nzero) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11]] +; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(ninf nzero sub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(nzero) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11]] ; CHECK-NEXT: ret float [[VAL]] ; %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") @@ -261,9 +261,9 @@ define float @constrained_sqrt_nonegzero(float nofpclass(nzero) %arg) strictfp { } define float @constrained_sqrt_nozero(float nofpclass(zero) %arg) strictfp { -; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @constrained_sqrt_nozero +; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @constrained_sqrt_nozero ; CHECK-SAME: (float nofpclass(zero) [[ARG:%.*]]) #[[ATTR9]] { -; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(zero) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11]] +; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(ninf nzero sub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(zero) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR11]] ; CHECK-NEXT: ret float [[VAL]] ; %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll index 234d97c05f3aa..b09faf0f4c3af 100644 --- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll @@ -150,9 +150,7 @@ define nofpclass(inf norm zero) float @ret_only_nan_or_sub__sqrt__select_unknown ; CHECK-LABEL: define nofpclass(inf zero norm) float @ret_only_nan_or_sub__sqrt__select_unknown_or_known_neg_nonzero( ; CHECK-SAME: i1 [[COND:%.*]], float [[X:%.*]]) { ; CHECK-NEXT: [[KNOWN_NEGATIVE_NONZERO:%.*]] = call float @returns_negative_nonzero() -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float [[KNOWN_NEGATIVE_NONZERO]] -; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]]) -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %known.negative.nonzero = call float @returns_negative_nonzero() %select = select i1 %cond, float %x, float %known.negative.nonzero @@ -249,8 +247,7 @@ define nofpclass(nan inf zero nsub norm) float @psub_result_implies_not_pnorm_so ; CHECK-LABEL: define nofpclass(nan inf zero nsub norm) float @psub_result_implies_not_pnorm_source( ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) { ; CHECK-NEXT: [[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) float @func() -; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[NOT_NAN]]) -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float poison ; %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func() %select = select i1 %cond, float %not.nan, float %only.pnorm diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index 4171e383e1bf1..f542231dbf0fd 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1584,14 +1584,13 @@ TEST_F(ComputeKnownFPClassTest, CopySignNInfSrc0_NegSign) { } TEST_F(ComputeKnownFPClassTest, CopySignNInfSrc0_PosSign) { - parseAssembly( - "declare float @llvm.sqrt.f32(float)\n" - "declare float @llvm.copysign.f32(float, float)\n" - "define float @test(float %arg0, float %arg1) {\n" - " %ninf = call ninf float @llvm.sqrt.f32(float %arg0)" - " %A = call float @llvm.copysign.f32(float %ninf, float 1.0)" - " ret float %A\n" - "}\n"); + parseAssembly("declare float @llvm.sqrt.f32(float)\n" + "declare float @llvm.copysign.f32(float, float)\n" + "define float @test(float %arg0, float %arg1) {\n" + " %ninf = call ninf float @llvm.log.f32(float %arg0)" + " %A = call float @llvm.copysign.f32(float %ninf, float 1.0)" + " ret float %A\n" + "}\n"); expectKnownFPClass(fcPosFinite | fcNan, false); } @@ -2083,8 +2082,8 @@ TEST_F(ComputeKnownFPClassTest, SqrtNszSignBit) { " ret float %A\n" "}\n"); - const FPClassTest SqrtMask = fcPositive | fcNegZero | fcNan; - const FPClassTest NszSqrtMask = fcPositive | fcNan; + const FPClassTest SqrtMask = fcPosInf | fcPosNormal | fcZero | fcNan; + const FPClassTest NszSqrtMask = fcPosInf | fcPosNormal | fcPosZero | fcNan; { KnownFPClass UseInstrInfo = @@ -2118,14 +2117,14 @@ TEST_F(ComputeKnownFPClassTest, SqrtNszSignBit) { KnownFPClass UseInstrInfoNoNan = computeKnownFPClass(A3, M->getDataLayout(), fcAllFlags, nullptr, nullptr, nullptr, nullptr, /*UseInstrInfo=*/true); - EXPECT_EQ(fcPositive | fcNegZero | fcQNan, + EXPECT_EQ(fcPosInf | fcPosNormal | fcZero | fcQNan, UseInstrInfoNoNan.KnownFPClasses); EXPECT_EQ(std::nullopt, UseInstrInfoNoNan.SignBit); KnownFPClass NoUseInstrInfoNoNan = computeKnownFPClass(A3, M->getDataLayout(), fcAllFlags, nullptr, nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); - EXPECT_EQ(fcPositive | fcNegZero | fcQNan, + EXPECT_EQ(fcPosNormal | fcPosInf | fcZero | fcQNan, NoUseInstrInfoNoNan.KnownFPClasses); EXPECT_EQ(std::nullopt, NoUseInstrInfoNoNan.SignBit); } @@ -2134,13 +2133,14 @@ TEST_F(ComputeKnownFPClassTest, SqrtNszSignBit) { KnownFPClass UseInstrInfoNSZNoNan = computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, nullptr, nullptr, nullptr, nullptr, /*UseInstrInfo=*/true); - EXPECT_EQ(fcPositive | fcQNan, UseInstrInfoNSZNoNan.KnownFPClasses); + EXPECT_EQ(fcPosInf | fcPosNormal | fcPosZero | fcQNan, + UseInstrInfoNSZNoNan.KnownFPClasses); EXPECT_EQ(std::nullopt, UseInstrInfoNSZNoNan.SignBit); KnownFPClass NoUseInstrInfoNSZNoNan = computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, nullptr, nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); - EXPECT_EQ(fcPositive | fcNegZero | fcQNan, + EXPECT_EQ(fcPosInf | fcPosNormal | fcZero | fcQNan, NoUseInstrInfoNSZNoNan.KnownFPClasses); EXPECT_EQ(std::nullopt, NoUseInstrInfoNSZNoNan.SignBit); } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
