Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -4222,7 +4222,8 @@ Known.copysign(KnownSign); break; } - case Intrinsic::sqrt: { + case Intrinsic::sqrt: + case Intrinsic::experimental_constrained_sqrt: { KnownFPClass KnownSrc; computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses, KnownSrc, Depth + 1, Q, TLI); Index: llvm/test/Transforms/Attributor/nofpclass.ll =================================================================== --- llvm/test/Transforms/Attributor/nofpclass.ll +++ llvm/test/Transforms/Attributor/nofpclass.ll @@ -14,6 +14,7 @@ declare i1 @llvm.is.fpclass.f32(float, i32 immarg) declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata) declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata) +declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata) define float @returned_0() { ; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @returned_0() { @@ -1185,3 +1186,58 @@ %val = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") ret float %val } + +define float @constrained_sqrt(float %arg) strictfp { +; CHECK: Function Attrs: nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) +; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @constrained_sqrt +; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR5]] { +; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.experimental.constrained.sqrt.f32(float [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR7]] +; CHECK-NEXT: ret float [[VAL]] +; + %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") + ret float %val +} + +define float @constrained_sqrt_nonan(float nofpclass(nan) %arg) strictfp { +; CHECK: Function Attrs: nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) +; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @constrained_sqrt_nonan +; CHECK-SAME: (float nofpclass(nan) [[ARG:%.*]]) #[[ATTR5]] { +; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(nan) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR7]] +; CHECK-NEXT: ret float [[VAL]] +; + %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") + ret float %val +} + +define float @constrained_sqrt_nopinf(float nofpclass(pinf) %arg) strictfp { +; CHECK: Function Attrs: nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) +; CHECK-LABEL: define nofpclass(inf nsub nnorm) float @constrained_sqrt_nopinf +; CHECK-SAME: (float nofpclass(pinf) [[ARG:%.*]]) #[[ATTR5]] { +; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(inf nsub nnorm) float @llvm.experimental.constrained.sqrt.f32(float nofpclass(pinf) [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR7]] +; CHECK-NEXT: ret float [[VAL]] +; + %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") + ret float %val +} + +define float @constrained_sqrt_nonegzero(float nofpclass(nzero) %arg) strictfp { +; CHECK: Function Attrs: nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) +; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @constrained_sqrt_nonegzero +; CHECK-SAME: (float nofpclass(nzero) [[ARG:%.*]]) #[[ATTR5]] { +; 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") #[[ATTR7]] +; CHECK-NEXT: ret float [[VAL]] +; + %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") + ret float %val +} + +define float @constrained_sqrt_nozero(float nofpclass(zero) %arg) strictfp { +; CHECK: Function Attrs: nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) +; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @constrained_sqrt_nozero +; CHECK-SAME: (float nofpclass(zero) [[ARG:%.*]]) #[[ATTR5]] { +; 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") #[[ATTR7]] +; CHECK-NEXT: ret float [[VAL]] +; + %val = call float @llvm.experimental.constrained.sqrt.f32(float %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") + ret float %val +}