Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -962,27 +962,40 @@ } void SCCPSolver::visitInsertElementInst(InsertElementInst &I) { - // TODO : SCCP does not handle vectors properly. - return markOverdefined(&I); -#if 0 LatticeVal &ValState = getValueState(I.getOperand(0)); LatticeVal &EltState = getValueState(I.getOperand(1)); LatticeVal &IdxState = getValueState(I.getOperand(2)); if (ValState.isOverdefined() || EltState.isOverdefined() || IdxState.isOverdefined()) - markOverdefined(&I); - else if(ValState.isConstant() && EltState.isConstant() && - IdxState.isConstant()) - markConstant(&I, ConstantExpr::getInsertElement(ValState.getConstant(), - EltState.getConstant(), - IdxState.getConstant())); - else if (ValState.isUndefined() && EltState.isConstant() && - IdxState.isConstant()) - markConstant(&I,ConstantExpr::getInsertElement(UndefValue::get(I.getType()), - EltState.getConstant(), - IdxState.getConstant())); -#endif + return markOverdefined(&I); + + // Creating a new vector. + // Example: insertelement <1 x i64> undef, i64 27, i32 0 + // -> <1 x i64> + if (ValState.isUndefined()) + return markConstant( + &I, + ConstantExpr::getInsertElement( + UndefValue::get(I.getType()), + EltState.isUndefined() ? UndefValue::get(I.getOperand(1)->getType()) + : EltState.getConstant(), + IdxState.isUndefined() ? UndefValue::get(I.getOperand(2)->getType()) + : IdxState.getConstant())); + // Inserting into an existing vector. + // Example: %vec = <2 x i64> + // insertelement <2 x i64> %vec, i64 42, i32 1 -> + // <2 x i64> + if (ValState.isConstant()) + return markConstant( + &I, + ConstantExpr::getInsertElement( + ValState.getConstant(), + EltState.isUndefined() ? UndefValue::get(I.getOperand(1)->getType()) + : EltState.getConstant(), + IdxState.isUndefined() ? UndefValue::get(I.getOperand(2)->getType()) + : IdxState.getConstant())); + markOverdefined(&I); } void SCCPSolver::visitShuffleVectorInst(ShuffleVectorInst &I) { Index: test/Transforms/SCCP/insertelement.ll =================================================================== --- /dev/null +++ test/Transforms/SCCP/insertelement.ll @@ -0,0 +1,45 @@ +; RUN: opt < %s -sccp -S | FileCheck %s + +; CHECK-LABEL: @insertelement +define <4 x i64> @insertelement() { + %vec1 = insertelement <4 x i64> undef, i64 -1, i32 0 + %vec2 = insertelement <4 x i64> %vec1, i64 -2, i32 1 + %vec3 = insertelement <4 x i64> %vec2, i64 -3, i32 2 + %vec4 = insertelement <4 x i64> %vec3, i64 -4, i32 3 + ; CHECK: ret <4 x i64> + ret <4 x i64> %vec4 +} + +; CHECK-LABEL: @insertelement_undef +define <4 x i64> @insertelement_undef() { + %vec1 = insertelement <4 x i64> undef, i64 -1, i32 0 + %vec2 = insertelement <4 x i64> %vec1, i64 -2, i32 1 + %vec3 = insertelement <4 x i64> %vec2, i64 -3, i32 2 + %vec4 = insertelement <4 x i64> %vec3, i64 -4, i32 3 + %vec5 = insertelement <4 x i64> %vec3, i64 -5, i32 4 + ; CHECK: ret <4 x i64> undef + ret <4 x i64> %vec5 +} + +define <1 x i64> @insertelement_undef_idx1() { + ; Out-of-bounds index -> fold to undef + %vec1 = insertelement <1 x i64> undef, i64 42, i32 27 + ret <1 x i64> %vec1 + ; CHECK: ret <1 x i64> undef +} + +define <2 x i64> @insertelement_undef_idx2() { + ; Undef index -> fold to undef + %vec1 = insertelement <2 x i64> undef, i64 42, i32 undef + %vec2 = insertelement <2 x i64> %vec1, i64 666, i32 undef + ret <2 x i64> %vec2 + ; CHECK: ret <2 x i64> undef +} + +define <2 x i64> @insertelement_undef_elem() { + ; Undef elem -> fold to undef + %vec1 = insertelement <2 x i64> undef, i64 undef, i32 0 + %vec2 = insertelement <2 x i64> %vec1, i64 undef, i32 1 + ret <2 x i64> %vec2 + ; CHECK: ret <2 x i64> undef +}