diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -964,11 +964,12 @@ /// FIXME We could be more clever, as we are for bzero above, and generate /// memset followed by stores. It's unclear that's worth the effort. static llvm::Value *shouldUseMemSetToInitialize(llvm::Constant *Init, - uint64_t GlobalSize) { + uint64_t GlobalSize, + const llvm::DataLayout &DL) { uint64_t SizeLimit = 32; if (GlobalSize <= SizeLimit) return nullptr; - return llvm::isBytewiseValue(Init); + return llvm::isBytewiseValue(Init, DL); } /// Decide whether we want to split a constant structure or array store into a @@ -1174,7 +1175,8 @@ } // If the initializer is a repeated byte pattern, use memset. - llvm::Value *Pattern = shouldUseMemSetToInitialize(constant, ConstantSize); + llvm::Value *Pattern = + shouldUseMemSetToInitialize(constant, ConstantSize, CGM.getDataLayout()); if (Pattern) { uint64_t Value = 0x00; if (!isa(Pattern)) { diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -224,7 +224,7 @@ /// 0.0 etc. If the value can't be handled with a repeated byte store (e.g. /// i16 0x1234), return null. If the value is entirely undef and padding, /// return undef. - Value *isBytewiseValue(Value *V); + Value *isBytewiseValue(Value *V, const DataLayout &DL); /// 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 diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3166,7 +3166,7 @@ return true; } -Value *llvm::isBytewiseValue(Value *V) { +Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { // All byte-wide stores are splatable, even of arbitrary variables. if (V->getType()->isIntegerTy(8)) @@ -3205,7 +3205,8 @@ else if (CFP->getType()->isDoubleTy()) Ty = Type::getInt64Ty(Ctx); // Don't handle long double formats, which have strange constraints. - return Ty ? isBytewiseValue(ConstantExpr::getBitCast(CFP, Ty)) : nullptr; + return Ty ? isBytewiseValue(ConstantExpr::getBitCast(CFP, Ty), DL) + : nullptr; } // We can handle constant integers that are multiple of 8 bits. @@ -3233,20 +3234,20 @@ if (ConstantDataSequential *CA = dyn_cast(C)) { Value *Val = UndefInt8; for (unsigned I = 0, E = CA->getNumElements(); I != E; ++I) - if (!(Val = Merge(Val, isBytewiseValue(CA->getElementAsConstant(I))))) + if (!(Val = Merge(Val, isBytewiseValue(CA->getElementAsConstant(I), DL)))) return nullptr; return Val; } if (isa(C)) { Constant *Splat = cast(C)->getSplatValue(); - return Splat ? isBytewiseValue(Splat) : nullptr; + return Splat ? isBytewiseValue(Splat, DL) : nullptr; } if (isa(C) || isa(C)) { Value *Val = UndefInt8; for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I) - if (!(Val = Merge(Val, isBytewiseValue(C->getOperand(I))))) + if (!(Val = Merge(Val, isBytewiseValue(C->getOperand(I), DL)))) return nullptr; return Val; } diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -450,7 +450,7 @@ // turned into a memset of i8 -1, assuming that all the consecutive bytes // are stored. A store of i32 0x01020304 can never be turned into a memset, // but it can be turned into memset_pattern if the target supports it. - Value *SplatValue = isBytewiseValue(StoredVal); + Value *SplatValue = isBytewiseValue(StoredVal, *DL); Constant *PatternValue = nullptr; // Note: memset and memset_pattern on unordered-atomic is yet not supported @@ -627,7 +627,7 @@ Constant *FirstPatternValue = nullptr; if (For == ForMemset::Yes) - FirstSplatValue = isBytewiseValue(FirstStoredVal); + FirstSplatValue = isBytewiseValue(FirstStoredVal, *DL); else FirstPatternValue = getMemSetPatternValue(FirstStoredVal, DL); @@ -660,7 +660,7 @@ Constant *SecondPatternValue = nullptr; if (For == ForMemset::Yes) - SecondSplatValue = isBytewiseValue(SecondStoredVal); + SecondSplatValue = isBytewiseValue(SecondStoredVal, *DL); else SecondPatternValue = getMemSetPatternValue(SecondStoredVal, DL); @@ -880,7 +880,7 @@ Value *StoredVal, Instruction *TheStore, SmallPtrSetImpl &Stores, const SCEVAddRecExpr *Ev, const SCEV *BECount, bool NegStride, bool IsLoopMemset) { - Value *SplatValue = isBytewiseValue(StoredVal); + Value *SplatValue = isBytewiseValue(StoredVal, *DL); Constant *PatternValue = nullptr; if (!SplatValue) diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -412,7 +412,7 @@ if (!NextStore->isSimple()) break; // Check to see if this stored value is of the same byte-splattable value. - Value *StoredByte = isBytewiseValue(NextStore->getOperand(0)); + Value *StoredByte = isBytewiseValue(NextStore->getOperand(0), DL); if (isa(ByteVal) && StoredByte) ByteVal = StoredByte; if (ByteVal != StoredByte) @@ -749,7 +749,7 @@ // byte at a time like "0" or "-1" or any width, as well as things like // 0xA0A0A0A0 and 0.0. auto *V = SI->getOperand(0); - if (Value *ByteVal = isBytewiseValue(V)) { + if (Value *ByteVal = isBytewiseValue(V, DL)) { if (Instruction *I = tryMergingIntoMemset(SI, SI->getPointerOperand(), ByteVal)) { BBI = I->getIterator(); // Don't invalidate iterator. @@ -1229,7 +1229,8 @@ // If copying from a constant, try to turn the memcpy into a memset. if (GlobalVariable *GV = dyn_cast(M->getSource())) if (GV->isConstant() && GV->hasDefinitiveInitializer()) - if (Value *ByteVal = isBytewiseValue(GV->getInitializer())) { + if (Value *ByteVal = isBytewiseValue(GV->getInitializer(), + M->getModule()->getDataLayout())) { IRBuilder<> Builder(M); Builder.CreateMemSet(M->getRawDest(), ByteVal, M->getLength(), M->getDestAlignment(), false);