llvm.org GIT mirror llvm / 59764b9
Constfold insertelement to undef when index is out-of-bounds Summary: This patch adds constant folding of insertelement instruction to undef value when index operand is constant and is not less than vector size or is undef. InstCombine does not support this case, but I'm happy to add it there also if this change is accepted. Test Plan: Unittests and regression tests for ConstProp pass. Reviewers: majnemer Reviewed By: majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9287 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235854 91177308-0d34-0410-b5e6-96231b3b80d8 Pawel Bylica 4 years ago
3 changed file(s) with 48 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
799799 Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,
800800 Constant *Elt,
801801 Constant *Idx) {
802 if (isa(Idx))
803 return UndefValue::get(Val->getType());
804
802805 ConstantInt *CIdx = dyn_cast(Idx);
803806 if (!CIdx) return nullptr;
804 const APInt &IdxVal = CIdx->getValue();
805
807
808 unsigned NumElts = Val->getType()->getVectorNumElements();
809 if (CIdx->uge(NumElts))
810 return UndefValue::get(Val->getType());
811
806812 SmallVector Result;
807 Type *Ty = IntegerType::get(Val->getContext(), 32);
808 for (unsigned i = 0, e = Val->getType()->getVectorNumElements(); i != e; ++i){
813 Result.reserve(NumElts);
814 auto *Ty = Type::getInt32Ty(Val->getContext());
815 uint64_t IdxVal = CIdx->getZExtValue();
816 for (unsigned i = 0; i != NumElts; ++i) {
809817 if (i == IdxVal) {
810818 Result.push_back(Elt);
811819 continue;
812820 }
813821
814 Constant *C =
815 ConstantExpr::getExtractElement(Val, ConstantInt::get(Ty, i));
822 Constant *C = ConstantExpr::getExtractElement(Val, ConstantInt::get(Ty, i));
816823 Result.push_back(C);
817824 }
818
825
819826 return ConstantVector::get(Result);
820827 }
821828
0 ; RUN: opt < %s -constprop -S | FileCheck %s
11
2 ; CHECK-LABEL: @test1
23 define i32 @test1() {
34 %A = bitcast i32 2139171423 to float
45 %B = insertelement <1 x float> undef, float %A, i32 0
56 %C = extractelement <1 x float> %B, i32 0
67 %D = bitcast float %C to i32
78 ret i32 %D
8 ; CHECK: @test1
99 ; CHECK: ret i32 2139171423
1010 }
1111
12 ; CHECK-LABEL: @insertelement
13 define <4 x i64> @insertelement() {
14 %vec1 = insertelement <4 x i64> undef, i64 -1, i32 0
15 %vec2 = insertelement <4 x i64> %vec1, i64 -2, i32 1
16 %vec3 = insertelement <4 x i64> %vec2, i64 -3, i32 2
17 %vec4 = insertelement <4 x i64> %vec3, i64 -4, i32 3
18 ; CHECK: ret <4 x i64>
19 ret <4 x i64> %vec4
20 }
21
22 ; CHECK-LABEL: @insertelement_undef
23 define <4 x i64> @insertelement_undef() {
24 %vec1 = insertelement <4 x i64> undef, i64 -1, i32 0
25 %vec2 = insertelement <4 x i64> %vec1, i64 -2, i32 1
26 %vec3 = insertelement <4 x i64> %vec2, i64 -3, i32 2
27 %vec4 = insertelement <4 x i64> %vec3, i64 -4, i32 3
28 %vec5 = insertelement <4 x i64> %vec3, i64 -5, i32 4
29 ; CHECK: ret <4 x i64> undef
30 ret <4 x i64> %vec5
31 }
189189 Constant *Two = ConstantInt::get(Int64Ty, 2);
190190 Constant *Big = ConstantInt::get(getGlobalContext(),
191191 APInt{256, uint64_t(-1), true});
192 Constant *Undef = UndefValue::get(Int64Ty);
192 Constant *Elt = ConstantInt::get(Int16Ty, 2015);
193 Constant *Undef16 = UndefValue::get(Int16Ty);
194 Constant *Undef64 = UndefValue::get(Int64Ty);
195 Constant *UndefV16 = UndefValue::get(P6->getType());
193196
194197 #define P0STR "ptrtoint (i32** @dummy to i32)"
195198 #define P1STR "uitofp (i32 ptrtoint (i32** @dummy to i32) to float)"
259262 CHECK(ConstantExpr::getExtractElement(P6, One), "extractelement <2 x i16> "
260263 P6STR ", i32 1");
261264
262 EXPECT_TRUE(isa(ConstantExpr::getExtractElement(P6, Two)));
263 EXPECT_TRUE(isa(ConstantExpr::getExtractElement(P6, Big)));
264 EXPECT_TRUE(isa(ConstantExpr::getExtractElement(P6, Undef)));
265 EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Two));
266 EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Big));
267 EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Undef64));
268
269 EXPECT_EQ(Elt, ConstantExpr::getExtractElement(
270 ConstantExpr::getInsertElement(P6, Elt, One), One));
271 EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Two));
272 EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Big));
273 EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Undef64));
265274 }
266275
267276 #ifdef GTEST_HAS_DEATH_TEST