From 1a78c64654cde1960be70fe532e999aff2aaa5bc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolai=20H=C3=A4hnle?= Date: Fri, 2 Dec 2022 16:07:30 +0100 Subject: [PATCH] Scalarizer: explicitly exclude scalable vectors They are unsupported and would previously crash, now we just skip them. Hypothetically, one could consider "scalarizing" a into n copies of . But (1) it's unclear how to do that because insertelement etc. don't work with scalable vectors in the required way, and (2) there is no user of such functionality. Differential Revision: https://reviews.llvm.org/D139358 --- llvm/lib/Transforms/Scalar/Scalarizer.cpp | 54 +++++++++++----------- .../Scalarizer/ignore-scalable-vectors.ll | 11 +++++ 2 files changed, 38 insertions(+), 27 deletions(-) create mode 100644 llvm/test/Transforms/Scalarizer/ignore-scalable-vectors.ll diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp index 3cab256..bbce942 100644 --- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp +++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp @@ -174,7 +174,7 @@ struct VectorLayout { } // The type of the vector. - VectorType *VecTy = nullptr; + FixedVectorType *VecTy = nullptr; // The type of each element. Type *ElemTy = nullptr; @@ -488,7 +488,7 @@ ScalarizerVisitor::getVectorLayout(Type *Ty, Align Alignment, const DataLayout &DL) { VectorLayout Layout; // Make sure we're dealing with a vector. - Layout.VecTy = dyn_cast(Ty); + Layout.VecTy = dyn_cast(Ty); if (!Layout.VecTy) return std::nullopt; // Check that we're dealing with full-byte elements. @@ -504,11 +504,11 @@ ScalarizerVisitor::getVectorLayout(Type *Ty, Align Alignment, // to create an instruction like I with operand X and name Name. template bool ScalarizerVisitor::splitUnary(Instruction &I, const Splitter &Split) { - VectorType *VT = dyn_cast(I.getType()); + auto *VT = dyn_cast(I.getType()); if (!VT) return false; - unsigned NumElems = cast(VT)->getNumElements(); + unsigned NumElems = VT->getNumElements(); IRBuilder<> Builder(&I); Scatterer Op = scatter(&I, I.getOperand(0)); assert(Op.size() == NumElems && "Mismatched unary operation"); @@ -524,11 +524,11 @@ bool ScalarizerVisitor::splitUnary(Instruction &I, const Splitter &Split) { // to create an instruction like I with operands X and Y and name Name. template bool ScalarizerVisitor::splitBinary(Instruction &I, const Splitter &Split) { - VectorType *VT = dyn_cast(I.getType()); + auto *VT = dyn_cast(I.getType()); if (!VT) return false; - unsigned NumElems = cast(VT)->getNumElements(); + unsigned NumElems = VT->getNumElements(); IRBuilder<> Builder(&I); Scatterer VOp0 = scatter(&I, I.getOperand(0)); Scatterer VOp1 = scatter(&I, I.getOperand(1)); @@ -559,7 +559,7 @@ static Function *getScalarIntrinsicDeclaration(Module *M, /// If a call to a vector typed intrinsic function, split into a scalar call per /// element if possible for the intrinsic. bool ScalarizerVisitor::splitCall(CallInst &CI) { - VectorType *VT = dyn_cast(CI.getType()); + auto *VT = dyn_cast(CI.getType()); if (!VT) return false; @@ -571,7 +571,7 @@ bool ScalarizerVisitor::splitCall(CallInst &CI) { if (ID == Intrinsic::not_intrinsic || !isTriviallyScalariable(ID)) return false; - unsigned NumElems = cast(VT)->getNumElements(); + unsigned NumElems = VT->getNumElements(); unsigned NumArgs = CI.arg_size(); ValueVector ScalarOperands(NumArgs); @@ -624,11 +624,11 @@ bool ScalarizerVisitor::splitCall(CallInst &CI) { } bool ScalarizerVisitor::visitSelectInst(SelectInst &SI) { - VectorType *VT = dyn_cast(SI.getType()); + auto *VT = dyn_cast(SI.getType()); if (!VT) return false; - unsigned NumElems = cast(VT)->getNumElements(); + unsigned NumElems = VT->getNumElements(); IRBuilder<> Builder(&SI); Scatterer VOp1 = scatter(&SI, SI.getOperand(1)); Scatterer VOp2 = scatter(&SI, SI.getOperand(2)); @@ -677,12 +677,12 @@ bool ScalarizerVisitor::visitBinaryOperator(BinaryOperator &BO) { } bool ScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) { - VectorType *VT = dyn_cast(GEPI.getType()); + auto *VT = dyn_cast(GEPI.getType()); if (!VT) return false; IRBuilder<> Builder(&GEPI); - unsigned NumElems = cast(VT)->getNumElements(); + unsigned NumElems = VT->getNumElements(); unsigned NumIndices = GEPI.getNumIndices(); // The base pointer might be scalar even if it's a vector GEP. In those cases, @@ -723,11 +723,11 @@ bool ScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) { } bool ScalarizerVisitor::visitCastInst(CastInst &CI) { - VectorType *VT = dyn_cast(CI.getDestTy()); + auto *VT = dyn_cast(CI.getDestTy()); if (!VT) return false; - unsigned NumElems = cast(VT)->getNumElements(); + unsigned NumElems = VT->getNumElements(); IRBuilder<> Builder(&CI); Scatterer Op0 = scatter(&CI, CI.getOperand(0)); assert(Op0.size() == NumElems && "Mismatched cast"); @@ -741,13 +741,13 @@ bool ScalarizerVisitor::visitCastInst(CastInst &CI) { } bool ScalarizerVisitor::visitBitCastInst(BitCastInst &BCI) { - VectorType *DstVT = dyn_cast(BCI.getDestTy()); - VectorType *SrcVT = dyn_cast(BCI.getSrcTy()); + auto *DstVT = dyn_cast(BCI.getDestTy()); + auto *SrcVT = dyn_cast(BCI.getSrcTy()); if (!DstVT || !SrcVT) return false; - unsigned DstNumElems = cast(DstVT)->getNumElements(); - unsigned SrcNumElems = cast(SrcVT)->getNumElements(); + unsigned DstNumElems = DstVT->getNumElements(); + unsigned SrcNumElems = SrcVT->getNumElements(); IRBuilder<> Builder(&BCI); Scatterer Op0 = scatter(&BCI, BCI.getOperand(0)); ValueVector Res; @@ -796,11 +796,11 @@ bool ScalarizerVisitor::visitBitCastInst(BitCastInst &BCI) { } bool ScalarizerVisitor::visitInsertElementInst(InsertElementInst &IEI) { - VectorType *VT = dyn_cast(IEI.getType()); + auto *VT = dyn_cast(IEI.getType()); if (!VT) return false; - unsigned NumElems = cast(VT)->getNumElements(); + unsigned NumElems = VT->getNumElements(); IRBuilder<> Builder(&IEI); Scatterer Op0 = scatter(&IEI, IEI.getOperand(0)); Value *NewElt = IEI.getOperand(1); @@ -831,11 +831,11 @@ bool ScalarizerVisitor::visitInsertElementInst(InsertElementInst &IEI) { } bool ScalarizerVisitor::visitExtractElementInst(ExtractElementInst &EEI) { - VectorType *VT = dyn_cast(EEI.getOperand(0)->getType()); + auto *VT = dyn_cast(EEI.getOperand(0)->getType()); if (!VT) return false; - unsigned NumSrcElems = cast(VT)->getNumElements(); + unsigned NumSrcElems = VT->getNumElements(); IRBuilder<> Builder(&EEI); Scatterer Op0 = scatter(&EEI, EEI.getOperand(0)); Value *ExtIdx = EEI.getOperand(1); @@ -863,11 +863,11 @@ bool ScalarizerVisitor::visitExtractElementInst(ExtractElementInst &EEI) { } bool ScalarizerVisitor::visitShuffleVectorInst(ShuffleVectorInst &SVI) { - VectorType *VT = dyn_cast(SVI.getType()); + auto *VT = dyn_cast(SVI.getType()); if (!VT) return false; - unsigned NumElems = cast(VT)->getNumElements(); + unsigned NumElems = VT->getNumElements(); Scatterer Op0 = scatter(&SVI, SVI.getOperand(0)); Scatterer Op1 = scatter(&SVI, SVI.getOperand(1)); ValueVector Res; @@ -887,7 +887,7 @@ bool ScalarizerVisitor::visitShuffleVectorInst(ShuffleVectorInst &SVI) { } bool ScalarizerVisitor::visitPHINode(PHINode &PHI) { - VectorType *VT = dyn_cast(PHI.getType()); + auto *VT = dyn_cast(PHI.getType()); if (!VT) return false; @@ -982,9 +982,9 @@ bool ScalarizerVisitor::finish() { // The value is still needed, so recreate it using a series of // InsertElements. Value *Res = PoisonValue::get(Op->getType()); - if (auto *Ty = dyn_cast(Op->getType())) { + if (auto *Ty = dyn_cast(Op->getType())) { BasicBlock *BB = Op->getParent(); - unsigned Count = cast(Ty)->getNumElements(); + unsigned Count = Ty->getNumElements(); IRBuilder<> Builder(Op); if (isa(Op)) Builder.SetInsertPoint(BB, BB->getFirstInsertionPt()); diff --git a/llvm/test/Transforms/Scalarizer/ignore-scalable-vectors.ll b/llvm/test/Transforms/Scalarizer/ignore-scalable-vectors.ll new file mode 100644 index 0000000..cb29457 --- /dev/null +++ b/llvm/test/Transforms/Scalarizer/ignore-scalable-vectors.ll @@ -0,0 +1,11 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt %s -passes=scalarizer -S -o - | FileCheck %s + +define @test1( %a, %b) { +; CHECK-LABEL: @test1( +; CHECK-NEXT: [[R:%.*]] = add [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: ret [[R]] +; + %r = add %a, %b + ret %r +} -- 2.7.4