Index: lib/Transforms/Utils/Evaluator.cpp =================================================================== --- lib/Transforms/Utils/Evaluator.cpp +++ lib/Transforms/Utils/Evaluator.cpp @@ -247,13 +247,51 @@ IntegerType *IdxTy = IntegerType::get(NewTy->getContext(), 32); Constant *IdxZero = ConstantInt::get(IdxTy, 0, false); Constant * const IdxList[] = {IdxZero, IdxZero}; - Ptr = ConstantExpr::getGetElementPtr(nullptr, Ptr, IdxList); if (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI)) Ptr = FoldedPtr; - - // If we can't improve the situation by introspecting NewTy, - // we have to give up. + } else if (auto *ATy = dyn_cast(NewTy)) { + // See if we can remove undefs at the end of a vector to make + // the types compatible. + // For eg. + // @globalvariable1 = internal global [1 x <3 x float>] + // zeroinitializer + // store <4 x float> , + // <4 x float> * bitcast ([1 x <3 x float>] * @globalvariable1 to + // <4 x float> *) + auto *ElemTy = dyn_cast(ATy->getElementType()); + auto *Vec = dyn_cast(Val); + if (Vec && ElemTy) { + // See if the Constant vector has undefs at the end + // and can be truncated to ElemTy's size. + unsigned ValSize = Vec->getNumOperands(); + // Make sure we're truncating and not extending. + if (ValSize <= ElemTy->getNumElements()) + return false; + for (unsigned i = ElemTy->getNumElements(); i < ValSize; ++i) { + Value *V = Vec->getOperand(i); + if (!isa(V)) + // This is not an undef and we can't shrink the store. + return false; + } + // We know we can shrink it to ElemTy's size without losing + // data. + SmallVector NewVec; + for (unsigned i = 0; i < ElemTy->getNumElements(); ++i) + NewVec.push_back(Vec->getOperand(i)); + Val = ConstantVector::get(NewVec); + IntegerType *IdxTy = IntegerType::get(Val->getContext(), 32); + Constant *IdxZero = ConstantInt::get(IdxTy, 0, false); + Constant *const IdxList[] = {IdxZero, IdxZero}; + Ptr = ConstantExpr::getGetElementPtr(nullptr, Ptr, IdxList); + NewTy = ElemTy; + } else { + + DEBUG(dbgs() << "Failed to bitcast constant ptr, can not " + "evaluate.\n"); + return false; + } } else { DEBUG(dbgs() << "Failed to bitcast constant ptr, can not " "evaluate.\n"); Index: test/Transforms/GlobalOpt/ShrinkUndefStore.ll =================================================================== --- /dev/null +++ test/Transforms/GlobalOpt/ShrinkUndefStore.ll @@ -0,0 +1,32 @@ +; RUN: opt -globalopt -S < %s | FileCheck %s +@_ZL9aPosition = internal addrspace(2) global [1 x <3 x float>] zeroinitializer, align 16 +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__ctor1, i8* null }] +; CHECK-NOT: ctor1 +; CHECK: constant [1 x <3 x float>] [<3 x float> ] +; CHECK-LABEL: Z4aFooi + +; Function Attrs: nounwind optsize +define <3 x float> @_Z4aFooi(i32 %i) { +entry: + %idxprom = sext i32 %i to i64 + %arrayidx = getelementptr inbounds [1 x <3 x float>], [1 x <3 x float>] addrspace(2)* @_ZL9aPosition, i32 0, i64 %idxprom + %castToVec4 = bitcast <3 x float> addrspace(2)* %arrayidx to <4 x float> addrspace(2)* + %loadVec4 = load <4 x float>, <4 x float> addrspace(2)* %castToVec4 + %extractVec = shufflevector <4 x float> %loadVec4, <4 x float> undef, <3 x i32> + ret <3 x float> %extractVec +} + +; Function Attrs: nounwind optsize +define internal fastcc void @__cxx_global_var_init() { +entry: + %arrayidx = getelementptr inbounds [1 x <3 x float>], [1 x <3 x float>] addrspace(2)* @_ZL9aPosition, i32 0, i64 0 + store <4 x float> , <4 x float> addrspace(2)* bitcast ([1 x <3 x float>] addrspace(2)* @_ZL9aPosition to <4 x float> addrspace(2)*) + ret void +} + +; Function Attrs: nounwind optsize +define internal void @_GLOBAL__ctor1() { +entry: + call fastcc void @__cxx_global_var_init() + ret void +}