diff --git a/llvm/include/llvm/Analysis/InstSimplifyFolder.h b/llvm/include/llvm/Analysis/InstSimplifyFolder.h --- a/llvm/include/llvm/Analysis/InstSimplifyFolder.h +++ b/llvm/include/llvm/Analysis/InstSimplifyFolder.h @@ -60,6 +60,11 @@ return SimplifyICmpInst(P, LHS, RHS, SQ); } + Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, + bool IsInBounds = false) const override { + return SimplifyGEPInst(Ty, Ptr, IdxList, IsInBounds, SQ); + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -144,43 +149,6 @@ return ConstFolder.CreateUnOp(Opc, C); } - //===--------------------------------------------------------------------===// - // Memory Instructions - //===--------------------------------------------------------------------===// - - Value *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return ConstFolder.CreateGetElementPtr(Ty, C, IdxList); - } - Value *CreateGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const override { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - return ConstFolder.CreateGetElementPtr(Ty, C, Idx); - } - Value *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return ConstFolder.CreateGetElementPtr(Ty, C, IdxList); - } - - Value * - CreateInBoundsGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return ConstFolder.CreateInBoundsGetElementPtr(Ty, C, IdxList); - } - Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const override { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - return ConstFolder.CreateInBoundsGetElementPtr(Ty, C, Idx); - } - Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return ConstFolder.CreateInBoundsGetElementPtr(Ty, C, IdxList); - } - //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// diff --git a/llvm/include/llvm/Analysis/TargetFolder.h b/llvm/include/llvm/Analysis/TargetFolder.h --- a/llvm/include/llvm/Analysis/TargetFolder.h +++ b/llvm/include/llvm/Analysis/TargetFolder.h @@ -73,6 +73,20 @@ return nullptr; } + Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, + bool IsInBounds = false) const override { + if (auto *PC = dyn_cast(Ptr)) { + // Every index must be constant. + if (any_of(IdxList, [](Value *V) { return !isa(V); })) + return nullptr; + if (IsInBounds) + return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList)); + else + return Fold(ConstantExpr::getGetElementPtr(Ty, PC, IdxList)); + } + return nullptr; + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -157,42 +171,6 @@ return Fold(ConstantExpr::get(Opc, C)); } - //===--------------------------------------------------------------------===// - // Memory Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList)); - } - Constant *CreateGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const override { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx)); - } - Constant *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList)); - } - - Constant *CreateInBoundsGetElementPtr( - Type *Ty, Constant *C, ArrayRef IdxList) const override { - return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList)); - } - Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const override { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx)); - } - Constant *CreateInBoundsGetElementPtr( - Type *Ty, Constant *C, ArrayRef IdxList) const override { - return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList)); - } - //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// diff --git a/llvm/include/llvm/IR/ConstantFolder.h b/llvm/include/llvm/IR/ConstantFolder.h --- a/llvm/include/llvm/IR/ConstantFolder.h +++ b/llvm/include/llvm/IR/ConstantFolder.h @@ -17,10 +17,11 @@ #define LLVM_IR_CONSTANTFOLDER_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/IRBuilderFolder.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" -#include "llvm/IR/IRBuilderFolder.h" namespace llvm { @@ -62,6 +63,21 @@ return nullptr; } + Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, + bool IsInBounds = false) const override { + if (auto *PC = dyn_cast(Ptr)) { + // Every index must be constant. + if (any_of(IdxList, [](Value *V) { return !isa(V); })) + return nullptr; + + if (IsInBounds) + return ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList); + else + return ConstantExpr::getGetElementPtr(Ty, PC, IdxList); + } + return nullptr; + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -167,46 +183,6 @@ return ConstantExpr::get(Opc, C); } - //===--------------------------------------------------------------------===// - // Memory Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return ConstantExpr::getGetElementPtr(Ty, C, IdxList); - } - - Constant *CreateGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const override { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - return ConstantExpr::getGetElementPtr(Ty, C, Idx); - } - - Constant *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return ConstantExpr::getGetElementPtr(Ty, C, IdxList); - } - - Constant *CreateInBoundsGetElementPtr( - Type *Ty, Constant *C, ArrayRef IdxList) const override { - return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList); - } - - Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const override { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx); - } - - Constant *CreateInBoundsGetElementPtr( - Type *Ty, Constant *C, ArrayRef IdxList) const override { - return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList); - } - //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1739,45 +1739,28 @@ Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, const Twine &Name = "") { - if (auto *PC = dyn_cast(Ptr)) { - // Every index must be constant. - size_t i, e; - for (i = 0, e = IdxList.size(); i != e; ++i) - if (!isa(IdxList[i])) - break; - if (i == e) - return Insert(Folder.CreateGetElementPtr(Ty, PC, IdxList), Name); - } + if (auto *V = Folder.FoldGEP(Ty, Ptr, IdxList, /*IsInBounds=*/false)) + return V; return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList), Name); } Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, const Twine &Name = "") { - if (auto *PC = dyn_cast(Ptr)) { - // Every index must be constant. - size_t i, e; - for (i = 0, e = IdxList.size(); i != e; ++i) - if (!isa(IdxList[i])) - break; - if (i == e) - return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IdxList), - Name); - } + if (auto *V = Folder.FoldGEP(Ty, Ptr, IdxList, /*IsInBounds=*/true)) + return V; return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, IdxList), Name); } Value *CreateGEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name = "") { - if (auto *PC = dyn_cast(Ptr)) - if (auto *IC = dyn_cast(Idx)) - return Insert(Folder.CreateGetElementPtr(Ty, PC, IC), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, {Idx}, /*IsInBounds=*/false)) + return V; return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name); } Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name = "") { - if (auto *PC = dyn_cast(Ptr)) - if (auto *IC = dyn_cast(Idx)) - return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IC), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, {Idx}, /*IsInBounds=*/true)) + return V; return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name); } @@ -1785,8 +1768,8 @@ const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); - if (auto *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/false)) + return V; return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name); } @@ -1795,8 +1778,8 @@ const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); - if (auto *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/true)) + return V; return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name); } @@ -1808,8 +1791,8 @@ ConstantInt::get(Type::getInt32Ty(Context), Idx1) }; - if (auto *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/false)) + return V; return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name); } @@ -1821,8 +1804,8 @@ ConstantInt::get(Type::getInt32Ty(Context), Idx1) }; - if (auto *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/true)) + return V; return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name); } @@ -1831,8 +1814,8 @@ const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); - if (auto *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/false)) + return V; return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name); } @@ -1841,8 +1824,8 @@ const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); - if (auto *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/true)) + return V; return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name); } @@ -1854,8 +1837,8 @@ ConstantInt::get(Type::getInt64Ty(Context), Idx1) }; - if (auto *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/false)) + return V; return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name); } @@ -1867,8 +1850,8 @@ ConstantInt::get(Type::getInt64Ty(Context), Idx1) }; - if (auto *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name); + if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/true)) + return V; return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name); } diff --git a/llvm/include/llvm/IR/IRBuilderFolder.h b/llvm/include/llvm/IR/IRBuilderFolder.h --- a/llvm/include/llvm/IR/IRBuilderFolder.h +++ b/llvm/include/llvm/IR/IRBuilderFolder.h @@ -38,6 +38,9 @@ virtual Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const = 0; + virtual Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, + bool IsInBounds = false) const = 0; + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -78,29 +81,6 @@ virtual Value *CreateNot(Constant *C) const = 0; virtual Value *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const = 0; - //===--------------------------------------------------------------------===// - // Memory Instructions - //===--------------------------------------------------------------------===// - - virtual Value *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const = 0; - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - virtual Value *CreateGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const = 0; - virtual Value *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const = 0; - virtual Value *CreateInBoundsGetElementPtr( - Type *Ty, Constant *C, ArrayRef IdxList) const = 0; - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - virtual Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const = 0; - virtual Value *CreateInBoundsGetElementPtr( - Type *Ty, Constant *C, ArrayRef IdxList) const = 0; - //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// diff --git a/llvm/include/llvm/IR/NoFolder.h b/llvm/include/llvm/IR/NoFolder.h --- a/llvm/include/llvm/IR/NoFolder.h +++ b/llvm/include/llvm/IR/NoFolder.h @@ -54,6 +54,11 @@ return nullptr; } + Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, + bool IsInBounds = false) const override { + return nullptr; + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -179,46 +184,6 @@ return UnaryOperator::Create(Opc, C); } - //===--------------------------------------------------------------------===// - // Memory Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return ConstantExpr::getGetElementPtr(Ty, C, IdxList); - } - - Constant *CreateGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const override { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - return ConstantExpr::getGetElementPtr(Ty, C, Idx); - } - - Instruction *CreateGetElementPtr(Type *Ty, Constant *C, - ArrayRef IdxList) const override { - return GetElementPtrInst::Create(Ty, C, IdxList); - } - - Constant *CreateInBoundsGetElementPtr( - Type *Ty, Constant *C, ArrayRef IdxList) const override { - return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList); - } - - Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, - Constant *Idx) const override { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef or - // ArrayRef. - return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx); - } - - Instruction *CreateInBoundsGetElementPtr( - Type *Ty, Constant *C, ArrayRef IdxList) const override { - return GetElementPtrInst::CreateInBounds(Ty, C, IdxList); - } - //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// diff --git a/llvm/test/Transforms/LoopVersioning/lcssa.ll b/llvm/test/Transforms/LoopVersioning/lcssa.ll --- a/llvm/test/Transforms/LoopVersioning/lcssa.ll +++ b/llvm/test/Transforms/LoopVersioning/lcssa.ll @@ -57,8 +57,6 @@ ; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[LS2_21_PROMOTED]], [[SCEVGEP1]] ; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] ; CHECK-NEXT: [[SCEVGEP3:%.*]] = getelementptr i8, i8* [[LS1_20_PROMOTED]], i64 -1 -; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, i8* [[SCEVGEP3]], i64 0 -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, i8* [[LS1_20_PROMOTED]], i64 0 ; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label %bb1.ph.lver.orig, label %bb1.ph ; CHECK: bb1.ph.lver.orig: ;