From 5548e807b5777fdda167b6795e0e05432a6163f1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 17 May 2022 15:45:52 +0200 Subject: [PATCH] [IR] Remove support for extractvalue constant expression This removes the extractvalue constant expression, as part of https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179. extractvalue is already not supported in bitcode, so we do not need to worry about bitcode auto-upgrade. Uses of ConstantExpr::getExtractValue() should be replaced with IRBuilder::CreateExtractValue() (if the fact that the result is constant is not important) or ConstantFoldExtractValueInstruction() (if it is). Though for this particular case, it is also possible and usually preferable to use getAggregateElement() instead. The C API function LLVMConstExtractValue() is removed, as the underlying constant expression no longer exists. Instead, LLVMBuildExtractValue() should be used (which will constant fold or create an instruction). Depending on the use-case, LLVMGetAggregateElement() may also be used instead. Differential Revision: https://reviews.llvm.org/D125795 --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 2 +- llvm/bindings/go/llvm/ir.go | 14 ------- llvm/bindings/ocaml/llvm/llvm.ml | 2 - llvm/bindings/ocaml/llvm/llvm.mli | 5 --- llvm/bindings/ocaml/llvm/llvm_ocaml.c | 16 -------- llvm/docs/ReleaseNotes.rst | 9 +++++ llvm/include/llvm-c/Core.h | 2 - llvm/include/llvm/Analysis/TargetFolder.h | 2 +- llvm/include/llvm/IR/ConstantFolder.h | 3 +- llvm/include/llvm/IR/Constants.h | 2 - llvm/lib/Analysis/ConstantFolding.cpp | 4 +- llvm/lib/Analysis/InlineCost.cpp | 2 +- llvm/lib/AsmParser/LLParser.cpp | 20 +--------- llvm/lib/IR/Constants.cpp | 37 +------------------ llvm/lib/IR/ConstantsContext.h | 37 ------------------- llvm/lib/IR/Core.cpp | 6 --- llvm/lib/Transforms/Coroutines/CoroElide.cpp | 5 +-- .../InstCombine/InstCombineCompares.cpp | 7 +++- llvm/lib/Transforms/Utils/Evaluator.cpp | 4 +- llvm/test/Assembler/insertextractvalue.ll | 21 +++++------ llvm/test/Assembler/unsupported-constexprs.ll | 6 +++ llvm/test/CodeGen/Generic/pr33094.ll | 5 ++- llvm/test/CodeGen/X86/nonconst-static-ev.ll | 8 ---- llvm/test/Transforms/InstCombine/cast.ll | 3 +- llvm/test/Transforms/InstCombine/pr28725.ll | 3 +- llvm/test/Transforms/InstSimplify/pr28725.ll | 15 +++++--- 26 files changed, 61 insertions(+), 179 deletions(-) create mode 100644 llvm/test/Assembler/unsupported-constexprs.ll delete mode 100644 llvm/test/CodeGen/X86/nonconst-static-ev.ll diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index f51e9b303236b0..c41b4192051a36 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -955,7 +955,7 @@ ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E, adj = llvm::ConstantInt::get(adj->getType(), offset); } - llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1); + llvm::Constant *srcAdj = src->getAggregateElement(1); llvm::Constant *dstAdj; if (isDerivedToBase) dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj); diff --git a/llvm/bindings/go/llvm/ir.go b/llvm/bindings/go/llvm/ir.go index 7bf92e60a27538..14cad0cb7ed30f 100644 --- a/llvm/bindings/go/llvm/ir.go +++ b/llvm/bindings/go/llvm/ir.go @@ -993,20 +993,6 @@ func ConstShuffleVector(veca, vecb, mask Value) (rv Value) { return } -//TODO -//LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, -// unsigned NumIdx); - -func ConstExtractValue(agg Value, indices []uint32) (rv Value) { - n := len(indices) - if n == 0 { - panic("one or more indices are required") - } - ptr := (*C.unsigned)(&indices[0]) - rv.C = C.LLVMConstExtractValue(agg.C, ptr, C.unsigned(n)) - return -} - func ConstInsertValue(agg, val Value, indices []uint32) (rv Value) { n := len(indices) if n == 0 { diff --git a/llvm/bindings/ocaml/llvm/llvm.ml b/llvm/bindings/ocaml/llvm/llvm.ml index b20c113ef32e45..bf8b96959f8194 100644 --- a/llvm/bindings/ocaml/llvm/llvm.ml +++ b/llvm/bindings/ocaml/llvm/llvm.ml @@ -704,8 +704,6 @@ external const_insertelement : llvalue -> llvalue -> llvalue -> llvalue = "LLVMConstInsertElement" external const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue = "LLVMConstShuffleVector" -external const_extractvalue : llvalue -> int array -> llvalue - = "llvm_const_extractvalue" external const_insertvalue : llvalue -> llvalue -> int array -> llvalue = "llvm_const_insertvalue" external const_inline_asm : lltype -> string -> string -> bool -> bool -> diff --git a/llvm/bindings/ocaml/llvm/llvm.mli b/llvm/bindings/ocaml/llvm/llvm.mli index af303774e0b962..385c3cc272d15e 100644 --- a/llvm/bindings/ocaml/llvm/llvm.mli +++ b/llvm/bindings/ocaml/llvm/llvm.mli @@ -1347,11 +1347,6 @@ val const_insertelement : llvalue -> llvalue -> llvalue -> llvalue See the method [llvm::ConstantExpr::getShuffleVector]. *) val const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue -(** [const_extractvalue agg idxs] returns the constant [idxs]th value of - constant aggregate [agg]. Each [idxs] must be less than the size of the - aggregate. See the method [llvm::ConstantExpr::getExtractValue]. *) -val const_extractvalue : llvalue -> int array -> llvalue - (** [const_insertvalue agg val idxs] inserts the value [val] in the specified indexs [idxs] in the aggregate [agg]. Each [idxs] must be less than the size of the aggregate. See the method [llvm::ConstantExpr::getInsertValue]. *) diff --git a/llvm/bindings/ocaml/llvm/llvm_ocaml.c b/llvm/bindings/ocaml/llvm/llvm_ocaml.c index 8a1b63aa8bf99f..b10b1a3ed84a0b 100644 --- a/llvm/bindings/ocaml/llvm/llvm_ocaml.c +++ b/llvm/bindings/ocaml/llvm/llvm_ocaml.c @@ -1013,22 +1013,6 @@ LLVMValueRef llvm_const_intcast(LLVMValueRef CV, LLVMTypeRef T, return LLVMConstIntCast(CV, T, Bool_val(IsSigned)); } -/* llvalue -> int array -> llvalue */ -LLVMValueRef llvm_const_extractvalue(LLVMValueRef Aggregate, value Indices) { - int size = Wosize_val(Indices); - int i; - LLVMValueRef result; - - unsigned *idxs = (unsigned *)malloc(size * sizeof(unsigned)); - for (i = 0; i < size; i++) { - idxs[i] = Int_val(Field(Indices, i)); - } - - result = LLVMConstExtractValue(Aggregate, idxs, size); - free(idxs); - return result; -} - /* llvalue -> llvalue -> int array -> llvalue */ LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate, LLVMValueRef Val, value Indices) { diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 4391d55b4e90d6..d1c5d967be5ab9 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -68,6 +68,9 @@ Changes to the LLVM IR * Renamed ``llvm.experimental.vector.extract`` intrinsic to ``llvm.vector.extract``. * Renamed ``llvm.experimental.vector.insert`` intrinsic to ``llvm.vector.insert``. +* The constant expression variants of the following instructions have been + removed: + * ``extractvalue`` Changes to building LLVM ------------------------ @@ -171,6 +174,12 @@ Changes to the C API favor of the new function, which works on all constant aggregates, rather than only instances of ``ConstantDataSequential``. +* The following functions for creating constant expressions have been removed, + because the underlying constant expressions are no longer supported. Instead, + an instruction should be created using the ``LLVMBuildXYZ`` APIs, which will + constant fold the operands if possible and create an instruction otherwise: + * ``LLVMConstExtractValue`` + Changes to the Go bindings -------------------------- diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index fd9bc0a38f2810..2abc29851cd9bb 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -2238,8 +2238,6 @@ LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, LLVMValueRef VectorBConstant, LLVMValueRef MaskConstant); -LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, - unsigned NumIdx); LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, LLVMValueRef ElementValueConstant, unsigned *IdxList, unsigned NumIdx); diff --git a/llvm/include/llvm/Analysis/TargetFolder.h b/llvm/include/llvm/Analysis/TargetFolder.h index c8d53d37b77033..ed8c08a1c650a5 100644 --- a/llvm/include/llvm/Analysis/TargetFolder.h +++ b/llvm/include/llvm/Analysis/TargetFolder.h @@ -109,7 +109,7 @@ class TargetFolder final : public IRBuilderFolder { Value *FoldExtractValue(Value *Agg, ArrayRef IdxList) const override { if (auto *CAgg = dyn_cast(Agg)) - return Fold(ConstantExpr::getExtractValue(CAgg, IdxList)); + return ConstantFoldExtractValueInstruction(CAgg, IdxList); return nullptr; }; diff --git a/llvm/include/llvm/IR/ConstantFolder.h b/llvm/include/llvm/IR/ConstantFolder.h index b1afd3e583ae9a..39199bd8dc79c5 100644 --- a/llvm/include/llvm/IR/ConstantFolder.h +++ b/llvm/include/llvm/IR/ConstantFolder.h @@ -19,6 +19,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/ConstantFold.h" #include "llvm/IR/IRBuilderFolder.h" #include "llvm/IR/Instruction.h" @@ -97,7 +98,7 @@ class ConstantFolder final : public IRBuilderFolder { Value *FoldExtractValue(Value *Agg, ArrayRef IdxList) const override { if (auto *CAgg = dyn_cast(Agg)) - return ConstantExpr::getExtractValue(CAgg, IdxList); + return ConstantFoldExtractValueInstruction(CAgg, IdxList); return nullptr; }; diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index 0caee4cb8a50c3..b5445ff71b7437 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -1294,8 +1294,6 @@ class ConstantExpr : public Constant { static Constant *getShuffleVector(Constant *V1, Constant *V2, ArrayRef Mask, Type *OnlyIfReducedTy = nullptr); - static Constant *getExtractValue(Constant *Agg, ArrayRef Idxs, - Type *OnlyIfReducedTy = nullptr); static Constant *getInsertValue(Constant *Agg, Constant *Val, ArrayRef Idxs, Type *OnlyIfReducedTy = nullptr); diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 0096aa99ff6be9..7a972c906b8c96 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1082,7 +1082,7 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode, case Instruction::ExtractElement: return ConstantExpr::getExtractElement(Ops[0], Ops[1]); case Instruction::ExtractValue: - return ConstantExpr::getExtractValue( + return ConstantFoldExtractValueInstruction( Ops[0], cast(InstOrCE)->getIndices()); case Instruction::InsertElement: return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]); @@ -1198,7 +1198,7 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL, return ConstantExpr::getInsertValue(Ops[0], Ops[1], IVI->getIndices()); if (auto *EVI = dyn_cast(I)) - return ConstantExpr::getExtractValue(Ops[0], EVI->getIndices()); + return ConstantFoldExtractValueInstruction(Ops[0], EVI->getIndices()); return ConstantFoldInstOperands(I, Ops, DL, TLI); } diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index 753071c2b88e37..0b0a2c835eeca2 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -2078,7 +2078,7 @@ bool CallAnalyzer::visitStore(StoreInst &I) { bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) { // Constant folding for extract value is trivial. if (simplifyInstruction(I, [&](SmallVectorImpl &COps) { - return ConstantExpr::getExtractValue(COps[0], I.getIndices()); + return ConstantFoldExtractValueInstruction(COps[0], I.getIndices()); })) return true; diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 90e5bffa9e0864..a1cdeac2b47f0b 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3472,24 +3472,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { ID.Kind = ValID::t_Constant; return false; } - case lltok::kw_extractvalue: { - Lex.Lex(); - Constant *Val; - SmallVector Indices; - if (parseToken(lltok::lparen, - "expected '(' in extractvalue constantexpr") || - parseGlobalTypeAndValue(Val) || parseIndexList(Indices) || - parseToken(lltok::rparen, "expected ')' in extractvalue constantexpr")) - return true; - - if (!Val->getType()->isAggregateType()) - return error(ID.Loc, "extractvalue operand must be aggregate type"); - if (!ExtractValueInst::getIndexedType(Val->getType(), Indices)) - return error(ID.Loc, "invalid indices for extractvalue"); - ID.ConstantVal = ConstantExpr::getExtractValue(Val, Indices); - ID.Kind = ValID::t_Constant; - return false; - } + case lltok::kw_extractvalue: + return error(ID.Loc, "extractvalue constexprs are no longer supported"); case lltok::kw_insertvalue: { Lex.Lex(); Constant *Val0, *Val1; diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 2eb43416c77bcf..0bf5e09d664727 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -547,8 +547,6 @@ void llvm::deleteConstant(Constant *C) { delete static_cast(C); else if (isa(C)) delete static_cast(C); - else if (isa(C)) - delete static_cast(C); else if (isa(C)) delete static_cast(C); else if (isa(C)) @@ -1491,15 +1489,10 @@ bool ConstantExpr::isCompare() const { } bool ConstantExpr::hasIndices() const { - return getOpcode() == Instruction::ExtractValue || - getOpcode() == Instruction::InsertValue; + return getOpcode() == Instruction::InsertValue; } ArrayRef ConstantExpr::getIndices() const { - if (const ExtractValueConstantExpr *EVCE = - dyn_cast(this)) - return EVCE->Indices; - return cast(this)->Indices; } @@ -1549,8 +1542,6 @@ Constant *ConstantExpr::getWithOperands(ArrayRef Ops, Type *Ty, case Instruction::InsertValue: return ConstantExpr::getInsertValue(Ops[0], Ops[1], getIndices(), OnlyIfReducedTy); - case Instruction::ExtractValue: - return ConstantExpr::getExtractValue(Ops[0], getIndices(), OnlyIfReducedTy); case Instruction::FNeg: return ConstantExpr::getFNeg(Ops[0]); case Instruction::ShuffleVector: @@ -2677,30 +2668,6 @@ Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val, return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -Constant *ConstantExpr::getExtractValue(Constant *Agg, ArrayRef Idxs, - Type *OnlyIfReducedTy) { - assert(Agg->getType()->isFirstClassType() && - "Tried to create extractelement operation on non-first-class type!"); - - Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs); - (void)ReqTy; - assert(ReqTy && "extractvalue indices invalid!"); - - assert(Agg->getType()->isFirstClassType() && - "Non-first-class type for constant extractvalue expression"); - if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs)) - return FC; - - if (OnlyIfReducedTy == ReqTy) - return nullptr; - - Constant *ArgVec[] = { Agg }; - const ConstantExprKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs); - - LLVMContextImpl *pImpl = Agg->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { assert(C->getType()->isIntOrIntVectorTy() && "Cannot NEG a nonintegral value!"); @@ -3553,8 +3520,6 @@ Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const { case Instruction::InsertValue: return InsertValueInst::Create(Ops[0], Ops[1], getIndices(), "", InsertBefore); - case Instruction::ExtractValue: - return ExtractValueInst::Create(Ops[0], getIndices(), "", InsertBefore); case Instruction::ShuffleVector: return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), "", InsertBefore); diff --git a/llvm/lib/IR/ConstantsContext.h b/llvm/lib/IR/ConstantsContext.h index 4056c57480816d..21ef1c0d9f6418 100644 --- a/llvm/lib/IR/ConstantsContext.h +++ b/llvm/lib/IR/ConstantsContext.h @@ -209,36 +209,6 @@ class ShuffleVectorConstantExpr final : public ConstantExpr { } }; -/// ExtractValueConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// extractvalue constant exprs. -class ExtractValueConstantExpr final : public ConstantExpr { -public: - ExtractValueConstantExpr(Constant *Agg, ArrayRef IdxList, - Type *DestTy) - : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), - Indices(IdxList.begin(), IdxList.end()) { - Op<0>() = Agg; - } - - // allocate space for exactly one operand - void *operator new(size_t S) { return User::operator new(S, 1); } - void operator delete(void *Ptr) { User::operator delete(Ptr); } - - /// Indices - These identify which value to extract. - const SmallVector Indices; - - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - - static bool classof(const ConstantExpr *CE) { - return CE->getOpcode() == Instruction::ExtractValue; - } - static bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } -}; - /// InsertValueConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// insertvalue constant exprs. @@ -362,11 +332,6 @@ struct OperandTraits : public FixedNumOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) -template <> -struct OperandTraits - : public FixedNumOperandTraits {}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) - template <> struct OperandTraits : public FixedNumOperandTraits {}; @@ -620,8 +585,6 @@ struct ConstantExprKeyType { return new ShuffleVectorConstantExpr(Ops[0], Ops[1], ShuffleMask); case Instruction::InsertValue: return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty); - case Instruction::ExtractValue: - return new ExtractValueConstantExpr(Ops[0], Indexes, Ty); case Instruction::GetElementPtr: return GetElementPtrConstantExpr::Create(ExplicitTy, Ops[0], Ops.slice(1), Ty, SubclassOptionalData); diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 5f6b2efdbf1a73..4b9189ca5baa91 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -1875,12 +1875,6 @@ LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, IntMask)); } -LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, - unsigned NumIdx) { - return wrap(ConstantExpr::getExtractValue(unwrap(AggConstant), - makeArrayRef(IdxList, NumIdx))); -} - LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, LLVMValueRef ElementValueConstant, unsigned *IdxList, unsigned NumIdx) { diff --git a/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/llvm/lib/Transforms/Coroutines/CoroElide.cpp index 392849f46ed69a..6f78fc8db311af 100644 --- a/llvm/lib/Transforms/Coroutines/CoroElide.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp @@ -336,14 +336,13 @@ bool Lowerer::processCoroId(CoroIdInst *CoroId, AAResults &AA, assert(Resumers && "PostSplit coro.id Info argument must refer to an array" "of coroutine subfunctions"); auto *ResumeAddrConstant = - ConstantExpr::getExtractValue(Resumers, CoroSubFnInst::ResumeIndex); + Resumers->getAggregateElement(CoroSubFnInst::ResumeIndex); replaceWithConstant(ResumeAddrConstant, ResumeAddr); bool ShouldElide = shouldElide(CoroId->getFunction(), DT); - auto *DestroyAddrConstant = ConstantExpr::getExtractValue( - Resumers, + auto *DestroyAddrConstant = Resumers->getAggregateElement( ShouldElide ? CoroSubFnInst::CleanupIndex : CoroSubFnInst::DestroyIndex); for (auto &It : DestroyAddr) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 2800d8692fc71d..d26cc1fe9a2b58 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -190,8 +190,11 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal( if (!Elt) return nullptr; // If this is indexing an array of structures, get the structure element. - if (!LaterIndices.empty()) - Elt = ConstantExpr::getExtractValue(Elt, LaterIndices); + if (!LaterIndices.empty()) { + Elt = ConstantFoldExtractValueInstruction(Elt, LaterIndices); + if (!Elt) + return nullptr; + } // If the element is masked, handle it. if (AndCst) Elt = ConstantExpr::getAnd(Elt, AndCst); diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp index 18abe3851d56f9..0f08360968b2a0 100644 --- a/llvm/lib/Transforms/Utils/Evaluator.cpp +++ b/llvm/lib/Transforms/Utils/Evaluator.cpp @@ -361,8 +361,10 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB, LLVM_DEBUG(dbgs() << "Found a Select! Simplifying: " << *InstResult << "\n"); } else if (auto *EVI = dyn_cast(CurInst)) { - InstResult = ConstantExpr::getExtractValue( + InstResult = ConstantFoldExtractValueInstruction( getVal(EVI->getAggregateOperand()), EVI->getIndices()); + if (!InstResult) + return false; LLVM_DEBUG(dbgs() << "Found an ExtractValueInst! Simplifying: " << *InstResult << "\n"); } else if (auto *IVI = dyn_cast(CurInst)) { diff --git a/llvm/test/Assembler/insertextractvalue.ll b/llvm/test/Assembler/insertextractvalue.ll index 71dbba371d4e08..6621330cbcf8ef 100644 --- a/llvm/test/Assembler/insertextractvalue.ll +++ b/llvm/test/Assembler/insertextractvalue.ll @@ -15,28 +15,25 @@ define float @foo({{i32},{float, double}}* %p) nounwind { ret float %s } -; CHECK: @bar +; CHECK-LABEL: @bar ; CHECK-NEXT: store { { i32 }, { float, double } } { { i32 } { i32 4 }, { float, double } { float 4.000000e+00, double 2.000000e+01 } }, { { i32 }, { float, double } }* %p -; CHECK-NEXT: ret float 7.000000e+00 -define float @bar({{i32},{float, double}}* %p) nounwind { +define void @bar({{i32},{float, double}}* %p) nounwind { store {{i32},{float, double}} insertvalue ({{i32},{float, double}}{{i32}{i32 4},{float, double}{float 4.0, double 5.0}}, double 20.0, 1, 1), {{i32},{float, double}}* %p - ret float extractvalue ({{i32},{float, double}}{{i32}{i32 3},{float, double}{float 7.0, double 9.0}}, 1, 0) + ret void } -; CHECK: @car +; CHECK-LABEL: @car ; CHECK-NEXT: store { { i32 }, { float, double } } { { i32 } undef, { float, double } { float undef, double 2.000000e+01 } }, { { i32 }, { float, double } }* %p -; CHECK-NEXT: ret float undef -define float @car({{i32},{float, double}}* %p) nounwind { +define void @car({{i32},{float, double}}* %p) nounwind { store {{i32},{float, double}} insertvalue ({{i32},{float, double}} undef, double 20.0, 1, 1), {{i32},{float, double}}* %p - ret float extractvalue ({{i32},{float, double}} undef, 1, 0) + ret void } -; CHECK: @dar +; CHECK-LABEL: @dar ; CHECK-NEXT: store { { i32 }, { float, double } } { { i32 } zeroinitializer, { float, double } { float 0.000000e+00, double 2.000000e+01 } }, { { i32 }, { float, double } }* %p -; CHECK-NEXT: ret float 0.000000e+00 -define float @dar({{i32},{float, double}}* %p) nounwind { +define void @dar({{i32},{float, double}}* %p) nounwind { store {{i32},{float, double}} insertvalue ({{i32},{float, double}} zeroinitializer, double 20.0, 1, 1), {{i32},{float, double}}* %p - ret float extractvalue ({{i32},{float, double}} zeroinitializer, 1, 0) + ret void } ; PR4963 diff --git a/llvm/test/Assembler/unsupported-constexprs.ll b/llvm/test/Assembler/unsupported-constexprs.ll new file mode 100644 index 00000000000000..77c0af7bab8307 --- /dev/null +++ b/llvm/test/Assembler/unsupported-constexprs.ll @@ -0,0 +1,6 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +define float @extractvalue() { +; CHECK: [[@LINE+1]]:13: error: extractvalue constexprs are no longer supported + ret float extractvalue ({i32} {i32 3}, 0) +} diff --git a/llvm/test/CodeGen/Generic/pr33094.ll b/llvm/test/CodeGen/Generic/pr33094.ll index afa464f63f6633..08403f1c6d1bff 100644 --- a/llvm/test/CodeGen/Generic/pr33094.ll +++ b/llvm/test/CodeGen/Generic/pr33094.ll @@ -12,7 +12,8 @@ @B_Inst = global %B zeroinitializer define i64 @foo() { - ret i64 extractvalue (%Tuple select (i1 icmp eq + %e = extractvalue %Tuple select (i1 icmp eq (%B* bitcast (%A* @A_Inst to %B*), %B* @B_Inst), - %Tuple { i64 33 }, %Tuple { i64 42 }), 0) + %Tuple { i64 33 }, %Tuple { i64 42 }), 0 + ret i64 %e } diff --git a/llvm/test/CodeGen/X86/nonconst-static-ev.ll b/llvm/test/CodeGen/X86/nonconst-static-ev.ll deleted file mode 100644 index 60eff9c750b785..00000000000000 --- a/llvm/test/CodeGen/X86/nonconst-static-ev.ll +++ /dev/null @@ -1,8 +0,0 @@ -; RUN: not --crash llc -mtriple=i686-linux-gnu < %s 2> %t -; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s - -@0 = global i8 extractvalue ([1 x i8] select (i1 ptrtoint (ptr @1 to i1), [1 x i8] [ i8 1 ], [1 x i8] [ i8 2 ]), 0) -@1 = external global i32 - -; CHECK-ERRORS: Unsupported expression in static initializer: extractvalue - diff --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll index 735f0f91810740..3fafbd69e03209 100644 --- a/llvm/test/Transforms/InstCombine/cast.ll +++ b/llvm/test/Transforms/InstCombine/cast.ll @@ -1470,7 +1470,8 @@ define i64 @PR28745() { ; LE-LABEL: @PR28745( ; LE-NEXT: ret i64 0 ; - %b = zext i32 extractvalue ({ i32 } select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), { i32 } { i32 1 }, { i32 } zeroinitializer), 0) to i64 + %e = extractvalue { i32 } select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), { i32 } { i32 1 }, { i32 } zeroinitializer), 0 + %b = zext i32 %e to i64 ret i64 %b } diff --git a/llvm/test/Transforms/InstCombine/pr28725.ll b/llvm/test/Transforms/InstCombine/pr28725.ll index b86f22e0df0ea6..26772eb7fe3afe 100644 --- a/llvm/test/Transforms/InstCombine/pr28725.ll +++ b/llvm/test/Transforms/InstCombine/pr28725.ll @@ -3,7 +3,8 @@ define <2 x i16> @test1() { entry: - %b = insertelement <2 x i16> , i16 extractvalue (%S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0), i32 0 + %e = extractvalue %S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0 + %b = insertelement <2 x i16> , i16 %e, i32 0 ret <2 x i16> %b } diff --git a/llvm/test/Transforms/InstSimplify/pr28725.ll b/llvm/test/Transforms/InstSimplify/pr28725.ll index 1ccb8176386391..67e6170c4f1bc3 100644 --- a/llvm/test/Transforms/InstSimplify/pr28725.ll +++ b/llvm/test/Transforms/InstSimplify/pr28725.ll @@ -1,12 +1,17 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s %S = type { i16, i32 } +; InstCombine will be able to fold this into zeroinitializer define <2 x i16> @test1() { +; CHECK-LABEL: @test1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[E:%.*]] = extractvalue [[S:%.*]] select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), [[S]] zeroinitializer, [[S]] { i16 0, i32 1 }), 0 +; CHECK-NEXT: [[B:%.*]] = insertelement <2 x i16> , i16 [[E]], i32 0 +; CHECK-NEXT: ret <2 x i16> [[B]] +; entry: - %b = insertelement <2 x i16> , i16 extractvalue (%S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0), i32 0 + %e = extractvalue %S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0 + %b = insertelement <2 x i16> , i16 %e, i32 0 ret <2 x i16> %b } - -; InstCombine will be able to fold this into zeroinitializer -; CHECK-LABEL: @test1( -; CHECK: ret <2 x i16> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0), i16 0>