-/// processLoopStoreOfSplatValue - We see a strided store of a memsetable value.
-/// If we can transform this into a memset in the loop preheader, do so.
-bool LoopIdiomRecognize::
-processLoopStoreOfSplatValue(Value *DestPtr, unsigned StoreSize,
- unsigned StoreAlignment, Value *SplatValue,
- Instruction *TheStore,
- const SCEVAddRecExpr *Ev, const SCEV *BECount) {
- // If we're not allowed to form memset, we fail.
- if (!TLI->has(LibFunc::memset))
- return false;
+/// getMemSetPatternValue - If a strided store of the specified value is safe to
+/// turn into a memset_pattern16, return a ConstantArray of 16 bytes that should
+/// be passed in. Otherwise, return null.
+///
+/// Note that we don't ever attempt to use memset_pattern8 or 4, because these
+/// just replicate their input array and then pass on to memset_pattern16.
+static Constant *getMemSetPatternValue(Value *V, const TargetData &TD) {
+ // If the value isn't a constant, we can't promote it to being in a constant
+ // array. We could theoretically do a store to an alloca or something, but
+ // that doesn't seem worthwhile.
+ Constant *C = dyn_cast<Constant>(V);
+ if (C == 0) return 0;
+
+ // Only handle simple values that are a power of two bytes in size.
+ uint64_t Size = TD.getTypeSizeInBits(V->getType());
+ if (Size == 0 || (Size & 7) || (Size & (Size-1)))
+ return 0;
+
+ // Convert the constant to an integer type of the appropriate size so we can
+ // start hacking on it.
+ if (isa<PointerType>(V->getType()))
+ C = ConstantExpr::getPtrToInt(C, IntegerType::get(C->getContext(), Size));
+ else if (isa<VectorType>(V->getType()) || V->getType()->isFloatingPointTy())
+ C = ConstantExpr::getBitCast(C, IntegerType::get(C->getContext(), Size));
+ else if (!isa<IntegerType>(V->getType()))
+ return 0; // Unhandled type.
+
+ // Convert to size in bytes.
+ Size /= 8;
+
+ // If we couldn't fold this to an integer, we fail. We don't bother to handle
+ // relocatable expressions like the address of a global yet.
+ // FIXME!
+ ConstantInt *CI = dyn_cast<ConstantInt>(C);
+ if (CI == 0) return 0;
+
+ APInt CVal = CI->getValue();
+
+ // TODO: If CI is larger than 16-bytes, we can try slicing it in half to see
+ // if the top and bottom are the same.
+ if (Size > 16) return 0;