From 7edddee2aa6a6183e40784c9141afec3e2eabb95 Mon Sep 17 00:00:00 2001 From: Bevin Hansson <59652494+bevin-hansson@users.noreply.github.com> Date: Wed, 3 Apr 2024 08:45:59 +0200 Subject: [ExpandLargeFpConvert] Scalarize vector types. (#86954) expand-large-fp-convert cannot handle vector types. If overly large vector element types survive into isel, they will likely be scalarized there, but since isel cannot handle scalar integer types of that size, it will assert. Handle vector types in expand-large-fp-convert by scalarizing them and then expanding the scalar type operation. For large vectors, this results in a *massive* code expansion, but it's better than asserting. --- llvm/lib/CodeGen/ExpandLargeFpConvert.cpp | 49 ++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'llvm/lib/CodeGen/ExpandLargeFpConvert.cpp') diff --git a/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp b/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp index 4ec966e..6213530 100644 --- a/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp +++ b/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp @@ -568,8 +568,29 @@ static void expandIToFP(Instruction *IToFP) { IToFP->eraseFromParent(); } +static void scalarize(Instruction *I, SmallVectorImpl &Replace) { + VectorType *VTy = cast(I->getType()); + + IRBuilder<> Builder(I); + + unsigned NumElements = VTy->getElementCount().getFixedValue(); + Value *Result = PoisonValue::get(VTy); + for (unsigned Idx = 0; Idx < NumElements; ++Idx) { + Value *Ext = Builder.CreateExtractElement(I->getOperand(0), Idx); + Value *Cast = Builder.CreateCast(cast(I)->getOpcode(), Ext, + I->getType()->getScalarType()); + Result = Builder.CreateInsertElement(Result, Cast, Idx); + if (isa(Cast)) + Replace.push_back(cast(Cast)); + } + I->replaceAllUsesWith(Result); + I->dropAllReferences(); + I->eraseFromParent(); +} + static bool runImpl(Function &F, const TargetLowering &TLI) { SmallVector Replace; + SmallVector ReplaceVector; bool Modified = false; unsigned MaxLegalFpConvertBitWidth = @@ -584,29 +605,36 @@ static bool runImpl(Function &F, const TargetLowering &TLI) { switch (I.getOpcode()) { case Instruction::FPToUI: case Instruction::FPToSI: { - // TODO: This pass doesn't handle vectors. - if (I.getOperand(0)->getType()->isVectorTy()) + // TODO: This pass doesn't handle scalable vectors. + if (I.getOperand(0)->getType()->isScalableTy()) continue; - auto *IntTy = dyn_cast(I.getType()); + auto *IntTy = dyn_cast(I.getType()->getScalarType()); if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth) continue; - Replace.push_back(&I); + if (I.getOperand(0)->getType()->isVectorTy()) + ReplaceVector.push_back(&I); + else + Replace.push_back(&I); Modified = true; break; } case Instruction::UIToFP: case Instruction::SIToFP: { - // TODO: This pass doesn't handle vectors. - if (I.getOperand(0)->getType()->isVectorTy()) + // TODO: This pass doesn't handle scalable vectors. + if (I.getOperand(0)->getType()->isScalableTy()) continue; - auto *IntTy = dyn_cast(I.getOperand(0)->getType()); + auto *IntTy = + dyn_cast(I.getOperand(0)->getType()->getScalarType()); if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth) continue; - Replace.push_back(&I); + if (I.getOperand(0)->getType()->isVectorTy()) + ReplaceVector.push_back(&I); + else + Replace.push_back(&I); Modified = true; break; } @@ -615,6 +643,11 @@ static bool runImpl(Function &F, const TargetLowering &TLI) { } } + while (!ReplaceVector.empty()) { + Instruction *I = ReplaceVector.pop_back_val(); + scalarize(I, Replace); + } + if (Replace.empty()) return false; -- cgit v1.1