Index: llvm/trunk/include/llvm/Analysis/ConstantFolding.h =================================================================== --- llvm/trunk/include/llvm/Analysis/ConstantFolding.h +++ llvm/trunk/include/llvm/Analysis/ConstantFolding.h @@ -102,6 +102,13 @@ Constant *ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef Idxs); +/// \brief Attempt to constant fold an insertelement instruction with the +/// specified operands and indices. The constant result is returned if +/// successful; if not, null is returned. +Constant *ConstantFoldInsertElementInstruction(Constant *Val, + Constant *Elt, + Constant *Idx); + /// \brief Attempt to constant fold an extractelement instruction with the /// specified operands and indices. The constant result is returned if /// successful; if not, null is returned. Index: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h =================================================================== --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h @@ -161,6 +161,10 @@ Value *SimplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef Idxs, const SimplifyQuery &Q); +/// Given operands for an InsertElement, fold the result or return null. +Value *SimplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, + const SimplifyQuery &Q); + /// Given operands for an ExtractValueInst, fold the result or return null. Value *SimplifyExtractValueInst(Value *Agg, ArrayRef Idxs, const SimplifyQuery &Q); Index: llvm/trunk/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp @@ -3827,6 +3827,28 @@ return ::SimplifyInsertValueInst(Agg, Val, Idxs, Q, RecursionLimit); } +Value *llvm::SimplifyInsertElementInst(Value *Vec, Value *Val, Value *Idx, + const SimplifyQuery &Q) { + // Try to constant fold. + auto *VecC = dyn_cast(Vec); + auto *ValC = dyn_cast(Val); + auto *IdxC = dyn_cast(Idx); + if (VecC && ValC && IdxC) + return ConstantFoldInsertElementInstruction(VecC, ValC, IdxC); + + // Fold into undef if index is out of bounds. + if (auto *CI = dyn_cast(Idx)) { + uint64_t NumElements = cast(Vec->getType())->getNumElements(); + + if (CI->uge(NumElements)) + return UndefValue::get(Vec->getType()); + } + + // TODO: We should also fold if index is iteslf an undef. + + return nullptr; +} + /// Given operands for an ExtractValueInst, see if we can fold the result. /// If not, this returns null. static Value *SimplifyExtractValueInst(Value *Agg, ArrayRef Idxs, @@ -4695,6 +4717,12 @@ IV->getIndices(), Q); break; } + case Instruction::InsertElement: { + auto *IE = cast(I); + Result = SimplifyInsertElementInst(IE->getOperand(0), IE->getOperand(1), + IE->getOperand(2), Q); + break; + } case Instruction::ExtractValue: { auto *EVI = cast(I); Result = SimplifyExtractValueInst(EVI->getAggregateOperand(), Index: llvm/trunk/test/Transforms/InstSimplify/pr28725.ll =================================================================== --- llvm/trunk/test/Transforms/InstSimplify/pr28725.ll +++ llvm/trunk/test/Transforms/InstSimplify/pr28725.ll @@ -1,6 +1,4 @@ ; RUN: opt -S -instsimplify < %s | FileCheck %s -target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-pc-windows-msvc" %S = type { i16, i32 } define <2 x i16> @test1() { @@ -9,5 +7,6 @@ ret <2 x i16> %b } +; InstCombine will be able to fold this into zeroinitializer ; CHECK-LABEL: @test1( -; CHECK: ret <2 x i16> zeroinitializer +; 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>