@@ -15437,6 +15437,32 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
1543715437 CombineTo(ST1, ST1->getChain());
1543815438 return SDValue();
1543915439 }
15440+
15441+ // If ST stores to a subset of preceeding store's write set, we may be
15442+ // able to fold ST's value into the preceeding stored value. As we know
15443+ // the other uses of ST1's chain are unconcerned with ST, this folding
15444+ // will not affect those nodes.
15445+ int64_t Offset;
15446+ if (ChainBase.contains(ChainByteSize, STBase, STByteSize, DAG,
15447+ Offset)) {
15448+ SDValue ChainValue = ST1->getValue();
15449+ if (auto *C1 = dyn_cast<ConstantSDNode>(ChainValue)) {
15450+ if (auto *C = dyn_cast<ConstantSDNode>(Value)) {
15451+ APInt Val = C1->getAPIntValue();
15452+ APInt InsertVal = C->getAPIntValue().zextOrTrunc(STByteSize * 8);
15453+ if (DAG.getDataLayout().isBigEndian())
15454+ Offset = ChainByteSize - 1 - Offset;
15455+ Val.insertBits(InsertVal, Offset * 8);
15456+ SDValue NewSDVal =
15457+ DAG.getConstant(Val, SDLoc(C), ChainValue.getValueType(),
15458+ C1->isTargetOpcode(), C1->isOpaque());
15459+ SDNode *NewST1 = DAG.UpdateNodeOperands(
15460+ ST1, ST1->getChain(), NewSDVal, ST1->getOperand(2),
15461+ ST1->getOperand(3));
15462+ return CombineTo(ST, SDValue(NewST1, 0));
15463+ }
15464+ }
15465+ } // End ST subset of ST1 case.
1544015466 }
1544115467 }
1544215468 }
0 commit comments