================ @@ -6481,6 +6737,71 @@ SDValue SystemZTargetLowering::combineLOAD( SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; EVT LdVT = N->getValueType(0); + SDLoc DL(N); + + // Replace an i128 load that is used solely to move its value into GPRs + // by separate loads of both halves. + if (LdVT == MVT::i128) { + LoadSDNode *LD = cast<LoadSDNode>(N); + if (!LD->isSimple() || !ISD::isNormalLoad(LD)) + return SDValue(); + + // Scan through all users. + SmallVector<std::pair<SDNode *, int>, 2> Users; + int UsedElements = 0; + for (SDNode::use_iterator UI = LD->use_begin(), UIEnd = LD->use_end(); + UI != UIEnd; ++UI) { + // Skip the uses of the chain. + if (UI.getUse().getResNo() != 0) + continue; + + // Verify every user is a TRUNCATE to i64 of the low or high half ... + SDNode *User = *UI; + int Index = 1; + if (User->getOpcode() == ISD::SRL && + User->getOperand(1).getOpcode() == ISD::Constant && + cast<ConstantSDNode>(User->getOperand(1))->getZExtValue() == 64 && + User->hasOneUse()) { + User = *User->use_begin(); + Index = 0; + } + if (User->getOpcode() != ISD::TRUNCATE || + User->getValueType(0) != MVT::i64) + return SDValue(); + + // ... and no half is extracted twice. + if (UsedElements & (1 << Index)) + return SDValue(); + + UsedElements |= 1 << Index; + Users.push_back(std::make_pair(User, Index)); + } + + // Rewrite each extraction as an independent load. + SmallVector<SDValue, 2> ArgChains; + for (auto UserAndIndex : Users) { + SDNode *User = UserAndIndex.first; + unsigned Offset = User->getValueType(0).getStoreSize() * UserAndIndex.second; + SDValue Ptr = ---------------- JonPsson1 wrote:
Offset = 8 * ... ? https://github.com/llvm/llvm-project/pull/74625 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits