Index: include/llvm/Analysis/ValueTracking.h =================================================================== --- include/llvm/Analysis/ValueTracking.h +++ include/llvm/Analysis/ValueTracking.h @@ -217,12 +217,18 @@ /// x < -0 --> false bool SignBitMustBeZero(const Value *V, const TargetLibraryInfo *TLI); - /// If the specified value can be set by repeating the same byte in memory, - /// return the i8 value that it is represented with. This is true for all i8 - /// values obviously, but is also true for i32 0, i32 -1, i16 0xF0F0, double - /// 0.0 etc. If the value can't be handled with a repeated byte store (e.g. - /// i16 0x1234), return null. - Value *isBytewiseValue(Value *V); + /// If the specified value can be set by repeating the same sequence of \p + /// SplatSizeInBits bits, return the i value that it is represented by. + /// + /// If the value can't be represented as a repeated sequence (e.g. + /// i16 0x1234 with SplatSizeInBits=8), return null. + Value *isSplatValue(Value *V, unsigned SplatSizeInBits); + + /// If the specified value is a bytewise splat value, return the value + /// truncated to one byte. Otherwise return null. + inline Value *isBytewiseValue(Value *V) { + return isSplatValue(V, 8); + } /// Given an aggregrate and an sequence of indices, see if the scalar value /// indexed is already around as a register, for example if it were inserted Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3042,22 +3042,18 @@ return true; } -/// If the specified value can be set by repeating the same byte in memory, -/// return the i8 value that it is represented with. This is -/// true for all i8 values obviously, but is also true for i32 0, i32 -1, -/// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated -/// byte store (e.g. i16 0x1234), return null. -Value *llvm::isBytewiseValue(Value *V) { - // All byte-wide stores are splatable, even of arbitrary variables. - if (V->getType()->isIntegerTy(8)) return V; +Value *llvm::isSplatValue(Value *V, unsigned SplatSizeInBits) { + // SplatSizeInBits sized integers are splatable + if (V->getType()->isIntegerTy(SplatSizeInBits)) return V; // Handle 'null' ConstantArrayZero etc. if (Constant *C = dyn_cast(V)) if (C->isNullValue()) - return Constant::getNullValue(Type::getInt8Ty(V->getContext())); + return Constant::getNullValue(Type::getIntNTy(V->getContext(), + SplatSizeInBits)); // Constant float and double values can be handled as integer values if the - // corresponding integer value is "byteable". An important case is 0.0. + // corresponding integer value is "splatable". An important case is 0.0. if (ConstantFP *CFP = dyn_cast(V)) { if (CFP->getType()->isFloatTy()) V = ConstantExpr::getBitCast(CFP, Type::getInt32Ty(V->getContext())); @@ -3066,14 +3062,16 @@ // Don't handle long double formats, which have strange constraints. } - // We can handle constant integers that are multiple of 8 bits. + // We can handle constant integers that are multiple of SplatSize bits wide. if (ConstantInt *CI = dyn_cast(V)) { - if (CI->getBitWidth() % 8 == 0) { - assert(CI->getBitWidth() > 8 && "8 bits should be handled above!"); + if (CI->getBitWidth() % SplatSizeInBits == 0) { + assert(CI->getBitWidth() > SplatSizeInBits && + "SplatSize bits should be handled above!"); - if (!CI->getValue().isSplat(8)) + if (!CI->getValue().isSplat(SplatSizeInBits)) return nullptr; - return ConstantInt::get(V->getContext(), CI->getValue().trunc(8)); + return ConstantInt::get(V->getContext(), + CI->getValue().trunc(SplatSizeInBits)); } } @@ -3081,7 +3079,7 @@ // also splatable. if (ConstantDataSequential *CA = dyn_cast(V)) { Value *Elt = CA->getElementAsConstant(0); - Value *Val = isBytewiseValue(Elt); + Value *Val = isSplatValue(Elt, SplatSizeInBits); if (!Val) return nullptr;