diff options
author | ssijaric-nv <ssijaric@nvidia.com> | 2024-10-25 10:47:39 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-25 10:47:39 -0700 |
commit | 14db06946839729befd6bd3ced8142547f5fd139 (patch) | |
tree | b37ed8c8110f67049492b5b622d9ff2a9d99bdda /llvm/lib/IR/ConstantFold.cpp | |
parent | ac4bd74190fedfbe025ef757ff308dd184a507f5 (diff) | |
download | llvm-14db06946839729befd6bd3ced8142547f5fd139.zip llvm-14db06946839729befd6bd3ced8142547f5fd139.tar.gz llvm-14db06946839729befd6bd3ced8142547f5fd139.tar.bz2 |
[InstCombine] Fix a cycle when folding fneg(select) with scalable vector types (#112465)
The two folding operations are causing a cycle for the following case
with
scalable vector types:
define <vscale x 2 x double> @test_fneg_select_abs(<vscale x 2 x i1>
%cond, <vscale x 2 x double> %b) {
%1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double>
zeroinitializer, <vscale x 2 x double> %b
%2 = fneg fast <vscale x 2 x double> %1
ret <vscale x 2 x double> %2
}
1) fold fneg: -(Cond ? C : Y) -> Cond ? -C : -Y
2) fold select: (Cond ? -X : -Y) -> -(Cond ? X : Y)
1) results in the following since '<vscale x 2 x double>
zeroinitializer' passes
the check for the immediate constant:
%.neg = fneg fast <vscale x 2 x double> zeroinitializer
%b.neg = fneg fast <vscale x 2 x double> %b
%1 = select fast <vscale x 2 x i1> %cond, <vscale x 2 x double> %.neg,
<vscale x 2 x double> %b.neg
and so we end up going back and forth between 1) and 2).
Attempt to fold scalable vector constants, so that we end up with a
splat instead:
define <vscale x 2 x double> @test_fneg_select_abs(<vscale x 2 x i1>
%cond, <vscale x 2 x double> %b) {
%b.neg = fneg fast <vscale x 2 x double> %b
%1 = select fast <vscale x 2 x i1> %cond, <vscale x 2 x double>
shufflevector (<vscale x 2 x double> insertelement (<vscale x 2 x
double> poison, double -0.000000e+00, i64 0), <vscale x 2 x double>
poison, <vscale x 2 x i32> zeroinitializer), <vscale x 2 x double>
%b.neg
ret <vscale x 2 x double> %1
}
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 57d9a03..07dfbc4 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -581,26 +581,27 @@ Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) { case Instruction::FNeg: return ConstantFP::get(C->getContext(), neg(CV)); } - } else if (auto *VTy = dyn_cast<FixedVectorType>(C->getType())) { - - Type *Ty = IntegerType::get(VTy->getContext(), 32); + } else if (auto *VTy = dyn_cast<VectorType>(C->getType())) { // Fast path for splatted constants. if (Constant *Splat = C->getSplatValue()) if (Constant *Elt = ConstantFoldUnaryInstruction(Opcode, Splat)) return ConstantVector::getSplat(VTy->getElementCount(), Elt); - // Fold each element and create a vector constant from those constants. - SmallVector<Constant *, 16> Result; - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - Constant *ExtractIdx = ConstantInt::get(Ty, i); - Constant *Elt = ConstantExpr::getExtractElement(C, ExtractIdx); - Constant *Res = ConstantFoldUnaryInstruction(Opcode, Elt); - if (!Res) - return nullptr; - Result.push_back(Res); - } + if (auto *FVTy = dyn_cast<FixedVectorType>(VTy)) { + // Fold each element and create a vector constant from those constants. + Type *Ty = IntegerType::get(FVTy->getContext(), 32); + SmallVector<Constant *, 16> Result; + for (unsigned i = 0, e = FVTy->getNumElements(); i != e; ++i) { + Constant *ExtractIdx = ConstantInt::get(Ty, i); + Constant *Elt = ConstantExpr::getExtractElement(C, ExtractIdx); + Constant *Res = ConstantFoldUnaryInstruction(Opcode, Elt); + if (!Res) + return nullptr; + Result.push_back(Res); + } - return ConstantVector::get(Result); + return ConstantVector::get(Result); + } } // We don't know how to fold this. |