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 @@ -65,6 +65,10 @@ return SimplifyGEPInst(Ty, Ptr, IdxList, IsInBounds, SQ); } + Value *FoldSelect(Value *C, Value *True, Value *False) const override { + return SimplifySelectInst(C, True, False, SQ); + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -220,11 +224,6 @@ // Other Instructions //===--------------------------------------------------------------------===// - Value *CreateSelect(Constant *C, Constant *True, - Constant *False) const override { - return ConstFolder.CreateSelect(C, True, False); - } - Value *CreateExtractElement(Constant *Vec, Constant *Idx) const override { return ConstFolder.CreateExtractElement(Vec, Idx); } 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 @@ -87,6 +87,16 @@ return nullptr; } + Value *FoldSelect(Value *C, Value *True, Value *False) const override { + auto *CC = dyn_cast(C); + auto *TC = dyn_cast(True); + auto *FC = dyn_cast(False); + if (CC && TC && FC) + return Fold(ConstantExpr::getSelect(CC, TC, FC)); + + return nullptr; + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -242,11 +252,6 @@ // Other Instructions //===--------------------------------------------------------------------===// - Constant *CreateSelect(Constant *C, Constant *True, - Constant *False) const override { - return Fold(ConstantExpr::getSelect(C, True, False)); - } - Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override { return Fold(ConstantExpr::getExtractElement(Vec, Idx)); } 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 @@ -78,6 +78,15 @@ return nullptr; } + Value *FoldSelect(Value *C, Value *True, Value *False) const override { + auto *CC = dyn_cast(C); + auto *TC = dyn_cast(True); + auto *FC = dyn_cast(False); + if (CC && TC && FC) + return ConstantExpr::getSelect(CC, TC, FC); + return nullptr; + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -247,11 +256,6 @@ // Other Instructions //===--------------------------------------------------------------------===// - Constant *CreateSelect(Constant *C, Constant *True, - Constant *False) const override { - return ConstantExpr::getSelect(C, True, False); - } - Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override { return ConstantExpr::getExtractElement(Vec, Idx); } 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 @@ -41,6 +41,8 @@ virtual Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, bool IsInBounds = false) const = 0; + virtual Value *FoldSelect(Value *C, Value *True, Value *False) const = 0; + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -111,8 +113,6 @@ // Other Instructions //===--------------------------------------------------------------------===// - virtual Value *CreateSelect(Constant *C, Constant *True, - Constant *False) const = 0; virtual Value *CreateExtractElement(Constant *Vec, Constant *Idx) const = 0; virtual Value *CreateInsertElement(Constant *Vec, Constant *NewElt, Constant *Idx) const = 0; 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 @@ -59,6 +59,10 @@ return nullptr; } + Value *FoldSelect(Value *C, Value *True, Value *False) const override { + return nullptr; + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -248,11 +252,6 @@ // Other Instructions //===--------------------------------------------------------------------===// - Instruction *CreateSelect(Constant *C, - Constant *True, Constant *False) const override { - return SelectInst::Create(C, True, False); - } - Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const override { return ExtractElementInst::Create(Vec, Idx); diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -984,10 +984,8 @@ Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False, const Twine &Name, Instruction *MDFrom) { - if (auto *CC = dyn_cast(C)) - if (auto *TC = dyn_cast(True)) - if (auto *FC = dyn_cast(False)) - return Insert(Folder.CreateSelect(CC, TC, FC), Name); + if (auto *V = Folder.FoldSelect(C, True, False)) + return V; SelectInst *Sel = SelectInst::Create(C, True, False); if (MDFrom) { diff --git a/llvm/test/Transforms/LoopVectorize/pr34681.ll b/llvm/test/Transforms/LoopVectorize/pr34681.ll --- a/llvm/test/Transforms/LoopVectorize/pr34681.ll +++ b/llvm/test/Transforms/LoopVectorize/pr34681.ll @@ -83,7 +83,6 @@ ; CHECK: vector.scevcheck: ; CHECK-NEXT: add nsw i32 %conv, -1 ; CHECK-NEXT: [[NEG:%.+]] = sub i32 0, %conv -; CHECK-NEXT: = select i1 false, i32 [[NEG]], i32 %conv ; CHECK-NOT: %ident.check = icmp ne i16 %N, 1 ; CHECK-NOT: %{{[0-9]+}} = or i1 false, %ident.check ; CHECK-NOT: br i1 %{{[0-9]+}}, label %scalar.ph, label %vector.ph