aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorssijaric-nv <ssijaric@nvidia.com>2024-10-25 10:47:39 -0700
committerGitHub <noreply@github.com>2024-10-25 10:47:39 -0700
commit14db06946839729befd6bd3ced8142547f5fd139 (patch)
treeb37ed8c8110f67049492b5b622d9ff2a9d99bdda /llvm/lib/IR/ConstantFold.cpp
parentac4bd74190fedfbe025ef757ff308dd184a507f5 (diff)
downloadllvm-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.cpp29
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.