aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/ExpandLargeFpConvert.cpp')
-rw-r--r--llvm/lib/CodeGen/ExpandLargeFpConvert.cpp49
1 files changed, 41 insertions, 8 deletions
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<Instruction *> &Replace) {
+ VectorType *VTy = cast<FixedVectorType>(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<CastInst>(I)->getOpcode(), Ext,
+ I->getType()->getScalarType());
+ Result = Builder.CreateInsertElement(Result, Cast, Idx);
+ if (isa<Instruction>(Cast))
+ Replace.push_back(cast<Instruction>(Cast));
+ }
+ I->replaceAllUsesWith(Result);
+ I->dropAllReferences();
+ I->eraseFromParent();
+}
+
static bool runImpl(Function &F, const TargetLowering &TLI) {
SmallVector<Instruction *, 4> Replace;
+ SmallVector<Instruction *, 4> 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<IntegerType>(I.getType());
+ auto *IntTy = dyn_cast<IntegerType>(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<IntegerType>(I.getOperand(0)->getType());
+ auto *IntTy =
+ dyn_cast<IntegerType>(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;