From: Igor Laevsky Date: Wed, 13 Dec 2017 11:21:18 +0000 (+0000) Subject: Reintroduce r320049, r320014 and r319894. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fcf12e077b5376a700761fb8be219a1bd2af84ae;p=llvm Reintroduce r320049, r320014 and r319894. OpenGL issues should be fixed by now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320568 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h index cb314e3766c..6d4eef41252 100644 --- a/include/llvm/Analysis/ConstantFolding.h +++ b/include/llvm/Analysis/ConstantFolding.h @@ -102,6 +102,13 @@ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, 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. diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index be0f32ef444..3932a2ec249 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -161,6 +161,10 @@ Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, 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); diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 94de0c995d3..09f516a8cb9 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -3827,6 +3827,28 @@ Value *llvm::SimplifyInsertValueInst(Value *Agg, Value *Val, 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, @@ -4700,6 +4722,12 @@ Value *llvm::SimplifyInstruction(Instruction *I, const SimplifyQuery &SQ, 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(), diff --git a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 6c99007475c..65a96b96522 100644 --- a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -781,6 +781,10 @@ Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) { Value *ScalarOp = IE.getOperand(1); Value *IdxOp = IE.getOperand(2); + if (auto *V = SimplifyInsertElementInst( + VecOp, ScalarOp, IdxOp, SQ.getWithInstruction(&IE))) + return replaceInstUsesWith(IE, V); + // Inserting an undef or into an undefined place, remove this. if (isa(ScalarOp) || isa(IdxOp)) replaceInstUsesWith(IE, VecOp); diff --git a/test/Transforms/InstCombine/out-of-bounds-indexes.ll b/test/Transforms/InstCombine/out-of-bounds-indexes.ll index a1887d27550..02be57a4d15 100644 --- a/test/Transforms/InstCombine/out-of-bounds-indexes.ll +++ b/test/Transforms/InstCombine/out-of-bounds-indexes.ll @@ -31,3 +31,11 @@ define i128 @test_non64bit(i128 %a) { } declare void @llvm.assume(i1) + +define <4 x double> @inselt_bad_index(<4 x double> %a) { +; CHECK-LABEL: @inselt_bad_index( +; CHECK-NEXT: ret <4 x double> undef +; + %I = insertelement <4 x double> %a, double 0.0, i64 4294967296 + ret <4 x double> %I +} diff --git a/test/Transforms/InstCombine/pr28725.ll b/test/Transforms/InstCombine/pr28725.ll new file mode 100644 index 00000000000..ff9440d605a --- /dev/null +++ b/test/Transforms/InstCombine/pr28725.ll @@ -0,0 +1,11 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s +%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 diff --git a/test/Transforms/InstCombine/vector_insertelt_shuffle.ll b/test/Transforms/InstCombine/vector_insertelt_shuffle.ll index c358509d690..41c6370e48e 100644 --- a/test/Transforms/InstCombine/vector_insertelt_shuffle.ll +++ b/test/Transforms/InstCombine/vector_insertelt_shuffle.ll @@ -54,10 +54,10 @@ define <4 x float> @bazz(<4 x float> %x, i32 %a) { ret <4 x float> %ins6 } +; Out of bounds index folds to undef define <4 x float> @bazzz(<4 x float> %x) { ; CHECK-LABEL: @bazzz( -; CHECK-NEXT: [[INS2:%.*]] = insertelement <4 x float> %x, float 2.000000e+00, i32 2 -; CHECK-NEXT: ret <4 x float> [[INS2]] +; CHECK-NEXT: ret <4 x float> ; %ins1 = insertelement<4 x float> %x, float 1.0, i32 5 %ins2 = insertelement<4 x float> %ins1, float 2.0, i32 2 diff --git a/test/Transforms/InstSimplify/insertelement.ll b/test/Transforms/InstSimplify/insertelement.ll new file mode 100644 index 00000000000..3acd921cbad --- /dev/null +++ b/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 +} diff --git a/test/Transforms/InstSimplify/pr28725.ll b/test/Transforms/InstSimplify/pr28725.ll index b85fc10b6c8..7ff0b90c65d 100644 --- a/test/Transforms/InstSimplify/pr28725.ll +++ b/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 @@ entry: 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>