[clang] [llvm] [SystemZ] Support i128 as legal type in VRs (PR #74625)
Jonas Paulsson via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 13 13:50:32 PST 2023
================
@@ -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
More information about the llvm-commits
mailing list