diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index dbceb8e557849..eb8650fd0eb60 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5877,6 +5877,12 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, break; } case Instruction::ShuffleVector: { + // Handle vector splat idiom + if (Value *Splat = getSplatValue(V)) { + computeKnownFPClass(Splat, Known, InterestedClasses, Q, Depth + 1); + break; + } + // For undef elements, we don't know anything about the common state of // the shuffle result. APInt DemandedLHS, DemandedRHS; diff --git a/llvm/test/Transforms/Attributor/nofpclass.ll b/llvm/test/Transforms/Attributor/nofpclass.ll index a9ebdaa397015..d82dc412f5e36 100644 --- a/llvm/test/Transforms/Attributor/nofpclass.ll +++ b/llvm/test/Transforms/Attributor/nofpclass.ll @@ -2667,15 +2667,10 @@ define [4 x float] @constant_aggregate_zero() { } define @scalable_splat_pnorm() { -; CHECK-CV: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) -; CHECK-CV-LABEL: define noundef @scalable_splat_pnorm -; CHECK-CV-SAME: () #[[ATTR3]] { -; CHECK-CV-NEXT: ret splat (float 1.000000e+00) -; -; CHECK-CI: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) -; CHECK-CI-LABEL: define noundef nofpclass(nan inf zero sub nnorm) @scalable_splat_pnorm -; CHECK-CI-SAME: () #[[ATTR3]] { -; CHECK-CI-NEXT: ret splat (float 1.000000e+00) +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CHECK-LABEL: define noundef nofpclass(nan inf zero sub nnorm) @scalable_splat_pnorm +; CHECK-SAME: () #[[ATTR3]] { +; CHECK-NEXT: ret splat (float 1.000000e+00) ; ret splat (float 1.0) } @@ -2689,6 +2684,19 @@ define @scalable_splat_zero() { ret zeroinitializer } +define @scalable_splat_nnan(float nofpclass(nan) %x) { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CHECK-LABEL: define nofpclass(nan) @scalable_splat_nnan +; CHECK-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] { +; CHECK-NEXT: [[HEAD:%.*]] = insertelement poison, float [[X]], i32 0 +; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector [[HEAD]], poison, zeroinitializer +; CHECK-NEXT: ret [[SPLAT]] +; + %head = insertelement poison, float %x, i32 0 + %splat = shufflevector %head, poison, zeroinitializer + ret %splat +} + ; Verify we do not derive 'nofpclass(inf zero sub norm)' for the argument __x. ; See https://github.com/llvm/llvm-project/issues/78507 @@ -2989,5 +2997,7 @@ attributes #5 = { "denormal-fp-math"="ieee,positive-zero" } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: ; CGSCC-CI: {{.*}} ; CGSCC-CV: {{.*}} +; CHECK-CI: {{.*}} +; CHECK-CV: {{.*}} ; TUNIT-CI: {{.*}} ; TUNIT-CV: {{.*}}