Index: include/llvm/Analysis/ConstantFolding.h =================================================================== --- include/llvm/Analysis/ConstantFolding.h +++ 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: include/llvm/Analysis/InstructionSimplify.h =================================================================== --- include/llvm/Analysis/InstructionSimplify.h +++ 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: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -3805,6 +3805,26 @@ 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()); + } + + 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, @@ -4673,6 +4693,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: test/Transforms/InstCombine/pr28725.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/pr28725.ll @@ -0,0 +1,13 @@ +; RUN: opt -S -instcombine < %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() { +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 + ret <2 x i16> %b +} + +; CHECK-LABEL: @test1( +; CHECK: ret <2 x i16> zeroinitializer Index: test/Transforms/InstSimplify/insertelement.ll =================================================================== --- /dev/null +++ test/Transforms/InstSimplify/insertelement.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -instsimplify < %s | FileCheck %s + +define <4 x i32> @test1(<4 x i32> %A) { + %I = insertelement <4 x i32> %A, i32 5, i64 4294967296 + ; CHECK: ret <4 x i32> undef + ret <4 x i32> %I +} + +define <4 x i32> @test2(<4 x i32> %A) { + %I = insertelement <4 x i32> %A, i32 5, i64 4 + ; CHECK: ret <4 x i32> undef + ret <4 x i32> %I +} + +define <4 x i32> @test3(<4 x i32> %A) { + %I = insertelement <4 x i32> %A, i32 5, i64 1 + ; CHECK: ret <4 x i32> %I + ret <4 x i32> %I +} + +define <4 x i32> @test4(<4 x i32> %A) { + %I = insertelement <4 x i32> %A, i32 5, i128 100 + ; CHECK: ret <4 x i32> undef + ret <4 x i32> %I +} Index: test/Transforms/InstSimplify/pr28725.ll =================================================================== --- test/Transforms/InstSimplify/pr28725.ll +++ test/Transforms/InstSimplify/pr28725.ll @@ -9,5 +9,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>