-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[LLVM][InstCombine] Preserve vector types when shrinking FP constants. #163598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4e936bb
b6765f8
db09782
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1643,33 +1643,46 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) { | |
|
|
||
| /// Return a Constant* for the specified floating-point constant if it fits | ||
| /// in the specified FP type without changing its value. | ||
| static bool fitsInFPType(ConstantFP *CFP, const fltSemantics &Sem) { | ||
| static bool fitsInFPType(APFloat F, const fltSemantics &Sem) { | ||
| bool losesInfo; | ||
| APFloat F = CFP->getValueAPF(); | ||
| (void)F.convert(Sem, APFloat::rmNearestTiesToEven, &losesInfo); | ||
| return !losesInfo; | ||
| } | ||
|
|
||
| static Type *shrinkFPConstant(ConstantFP *CFP, bool PreferBFloat) { | ||
| if (CFP->getType() == Type::getPPC_FP128Ty(CFP->getContext())) | ||
| return nullptr; // No constant folding of this. | ||
| static Type *shrinkFPConstant(LLVMContext &Ctx, const APFloat &F, | ||
| bool PreferBFloat) { | ||
| // See if the value can be truncated to bfloat and then reextended. | ||
| if (PreferBFloat && fitsInFPType(CFP, APFloat::BFloat())) | ||
| return Type::getBFloatTy(CFP->getContext()); | ||
| if (PreferBFloat && fitsInFPType(F, APFloat::BFloat())) | ||
| return Type::getBFloatTy(Ctx); | ||
| // See if the value can be truncated to half and then reextended. | ||
| if (!PreferBFloat && fitsInFPType(CFP, APFloat::IEEEhalf())) | ||
| return Type::getHalfTy(CFP->getContext()); | ||
| if (!PreferBFloat && fitsInFPType(F, APFloat::IEEEhalf())) | ||
| return Type::getHalfTy(Ctx); | ||
| // See if the value can be truncated to float and then reextended. | ||
| if (fitsInFPType(CFP, APFloat::IEEEsingle())) | ||
| return Type::getFloatTy(CFP->getContext()); | ||
| if (CFP->getType()->isDoubleTy()) | ||
| return nullptr; // Won't shrink. | ||
| if (fitsInFPType(CFP, APFloat::IEEEdouble())) | ||
| return Type::getDoubleTy(CFP->getContext()); | ||
| if (fitsInFPType(F, APFloat::IEEEsingle())) | ||
| return Type::getFloatTy(Ctx); | ||
| if (&F.getSemantics() == &APFloat::IEEEdouble()) | ||
| return nullptr; // Won't shrink. | ||
| // See if the value can be truncated to double and then reextended. | ||
| if (fitsInFPType(F, APFloat::IEEEdouble())) | ||
| return Type::getDoubleTy(Ctx); | ||
| // Don't try to shrink to various long double types. | ||
| return nullptr; | ||
| } | ||
|
|
||
| static Type *shrinkFPConstant(ConstantFP *CFP, bool PreferBFloat) { | ||
| Type *Ty = CFP->getType(); | ||
| if (Ty->getScalarType()->isPPC_FP128Ty()) | ||
| return nullptr; // No constant folding of this. | ||
|
|
||
| Type *ShrinkTy = | ||
| shrinkFPConstant(CFP->getContext(), CFP->getValueAPF(), PreferBFloat); | ||
| if (ShrinkTy) | ||
| if (auto *VecTy = dyn_cast<VectorType>(Ty)) | ||
| ShrinkTy = VectorType::get(ShrinkTy, VecTy); | ||
|
|
||
| return ShrinkTy; | ||
| } | ||
|
|
||
| // Determine if this is a vector of ConstantFPs and if so, return the minimal | ||
| // type we can safely truncate all elements to. | ||
| static Type *shrinkFPConstantVector(Value *V, bool PreferBFloat) { | ||
|
|
@@ -1720,10 +1733,10 @@ static Type *getMinimumFPType(Value *V, bool PreferBFloat) { | |
|
|
||
| // Try to shrink scalable and fixed splat vectors. | ||
| if (auto *FPC = dyn_cast<Constant>(V)) | ||
| if (isa<VectorType>(V->getType())) | ||
| if (auto *VTy = dyn_cast<VectorType>(V->getType())) | ||
| if (auto *Splat = dyn_cast_or_null<ConstantFP>(FPC->getSplatValue())) | ||
| if (Type *T = shrinkFPConstant(Splat, PreferBFloat)) | ||
| return T; | ||
| return VectorType::get(T, VTy); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks right to me, but I don't really get how this worked previously. E.g. v4f32_fadd has a vector splat, why did that work? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only the Instruction::FRem handling uses getMinimumFPType()'s return type and even then the bug only occurs when LHS is the vector splat of which there were no tests. |
||
|
|
||
| // Try to shrink a vector of FP constants. This returns nullptr on scalable | ||
| // vectors | ||
|
|
@@ -1796,10 +1809,9 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) { | |
| Type *Ty = FPT.getType(); | ||
| auto *BO = dyn_cast<BinaryOperator>(FPT.getOperand(0)); | ||
| if (BO && BO->hasOneUse()) { | ||
| Type *LHSMinType = | ||
| getMinimumFPType(BO->getOperand(0), /*PreferBFloat=*/Ty->isBFloatTy()); | ||
| Type *RHSMinType = | ||
| getMinimumFPType(BO->getOperand(1), /*PreferBFloat=*/Ty->isBFloatTy()); | ||
| bool PreferBFloat = Ty->getScalarType()->isBFloatTy(); | ||
| Type *LHSMinType = getMinimumFPType(BO->getOperand(0), PreferBFloat); | ||
| Type *RHSMinType = getMinimumFPType(BO->getOperand(1), PreferBFloat); | ||
| unsigned OpWidth = BO->getType()->getFPMantissaWidth(); | ||
| unsigned LHSWidth = LHSMinType->getFPMantissaWidth(); | ||
| unsigned RHSWidth = RHSMinType->getFPMantissaWidth(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.