diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -5467,6 +5467,15 @@ if (!In->isNaN()) return ConstantFP::getNaN(Ty); + // If we known this is a NaN, and it's scalable vector, we must have a splat + // on our hands. Grab that before splatting a QNaN constant. + if (isa(Ty)) { + auto *Splat = In->getSplatValue(); + assert(Splat && Splat->isNaN() && + "Found a scalable-vector NaN but not a splat"); + In = Splat; + } + // Propagate an existing QNaN constant. If it is an SNaN, make it quiet, but // preserve the sign/payload. return ConstantFP::get(Ty, cast(In)->getValue().makeQuiet()); diff --git a/llvm/test/Transforms/InstSimplify/fp-nan.ll b/llvm/test/Transforms/InstSimplify/fp-nan.ll --- a/llvm/test/Transforms/InstSimplify/fp-nan.ll +++ b/llvm/test/Transforms/InstSimplify/fp-nan.ll @@ -49,6 +49,14 @@ ret <2 x float> %r } +define @fsub_nan_op1_scalable_vec( %x) { +; CHECK-LABEL: @fsub_nan_op1_scalable_vec( +; CHECK-NEXT: ret shufflevector ( insertelement ( poison, float 0x7FF9000000000000, i64 0), poison, zeroinitializer) +; + %r = fsub %x, shufflevector ( insertelement ( poison, float 0x7FF1000000000000, i64 0), poison, zeroinitializer) + ret %r +} + ; Signaling and signed - make quiet and preserve the payload and signbit define double @fmul_nan_op0(double %x) {