diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -2184,6 +2184,11 @@ /// cannot be inferred. MaybeAlign InferPtrAlign(SDValue Ptr) const; + /// Split the scalar node with EXTRACT_ELEMENT using the provided VTs and + /// return the low/high part. + std::pair SplitScalar(const SDValue &N, const SDLoc &DL, + const EVT &LoVT, const EVT &HiVT); + /// Compute the VTs needed for the low/hi parts of a type /// which is split (or expanded) into two not necessarily identical pieces. std::pair GetSplitDestVTs(const EVT &VT) const; diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -988,10 +988,7 @@ SDValue &Lo, SDValue &Hi) { SDLoc dl(Pair); EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Pair.getValueType()); - Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Pair, - DAG.getIntPtrConstant(0, dl)); - Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Pair, - DAG.getIntPtrConstant(1, dl)); + std::tie(Lo, Hi) = DAG.SplitScalar(Pair, dl, NVT, NVT); } /// Build an integer with low bits Lo and high bits Hi. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -11643,6 +11643,21 @@ return std::nullopt; } +/// Split the scalar node with EXTRACT_ELEMENT using the provided +/// VTs and return the low/high part. +std::pair SelectionDAG::SplitScalar(const SDValue &N, + const SDLoc &DL, + const EVT &LoVT, + const EVT &HiVT) { + assert(!LoVT.isVector() && !HiVT.isVector() && !N.getValueType().isVector() && + "Split node must be a scalar type"); + SDValue Lo = + getNode(ISD::EXTRACT_ELEMENT, DL, LoVT, N, getIntPtrConstant(0, DL)); + SDValue Hi = + getNode(ISD::EXTRACT_ELEMENT, DL, HiVT, N, getIntPtrConstant(1, DL)); + return std::make_pair(Lo, Hi); +} + /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type /// which is split (or expanded) into two not necessarily identical pieces. std::pair SelectionDAG::GetSplitDestVTs(const EVT &VT) const { diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -7353,12 +7353,8 @@ // more pieces using a smaller bit width. if (HalfMaxPlus1.urem(Divisor).isOne()) { assert(!LL == !LH && "Expected both input halves or no input halves!"); - if (!LL) { - LL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HiLoVT, N->getOperand(0), - DAG.getIntPtrConstant(0, dl)); - LH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HiLoVT, N->getOperand(0), - DAG.getIntPtrConstant(1, dl)); - } + if (!LL) + std::tie(LL, LH) = DAG.SplitScalar(N->getOperand(0), dl, HiLoVT, HiLoVT); // Shift the input by the number of TrailingZeros in the divisor. The // shifted out bits will be added to the remainder later. @@ -7432,10 +7428,8 @@ DAG.getConstant(MulFactor, dl, VT)); // Split the quotient into low and high parts. - SDValue QuotL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HiLoVT, Quotient, - DAG.getIntPtrConstant(0, dl)); - SDValue QuotH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HiLoVT, Quotient, - DAG.getIntPtrConstant(1, dl)); + SDValue QuotL, QuotH; + std::tie(QuotL, QuotH) = DAG.SplitScalar(Quotient, dl, HiLoVT, HiLoVT); Result.push_back(QuotL); Result.push_back(QuotH); } diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -5591,15 +5591,6 @@ return SDValue(); } -static std::pair splitInt128(SDValue N, SelectionDAG &DAG) { - SDLoc DL(N); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i64, N, - DAG.getConstant(0, DL, MVT::i64)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i64, N, - DAG.getConstant(1, DL, MVT::i64)); - return std::make_pair(Lo, Hi); -} - /// Lower atomic or volatile 128-bit stores to a single STP instruction. SDValue AArch64TargetLowering::LowerStore128(SDValue Op, SelectionDAG &DAG) const { @@ -5619,7 +5610,7 @@ ? StoreNode->getOperand(1) : StoreNode->getOperand(2); SDLoc DL(Op); - auto StoreValue = splitInt128(Value, DAG); + auto StoreValue = DAG.SplitScalar(Value, DL, MVT::i64, MVT::i64); unsigned Opcode = IsStoreRelease ? AArch64ISD::STILP : AArch64ISD::STP; SDValue Result = DAG.getMemIntrinsicNode( Opcode, DL, DAG.getVTList(MVT::Other), @@ -6015,7 +6006,8 @@ SDValue Chain = Op.getOperand(0); SDValue SysRegName = Op.getOperand(1); - std::pair Pair = splitInt128(Op.getOperand(2), DAG); + std::pair Pair = + DAG.SplitScalar(Op.getOperand(2), DL, MVT::i64, MVT::i64); // chain = MSRR(chain, sysregname, lo, hi) SDValue Result = DAG.getNode(AArch64ISD::MSRR, DL, MVT::Other, Chain, @@ -22328,8 +22320,9 @@ llvm_unreachable("Unexpected ordering!"); } - auto Desired = splitInt128(N->getOperand(2), DAG); - auto New = splitInt128(N->getOperand(3), DAG); + SDLoc DL(N); + auto Desired = DAG.SplitScalar(N->getOperand(2), DL, MVT::i64, MVT::i64); + auto New = DAG.SplitScalar(N->getOperand(3), DL, MVT::i64, MVT::i64); SDValue Ops[] = {N->getOperand(1), Desired.first, Desired.second, New.first, New.second, N->getOperand(0)}; SDNode *CmpSwap = DAG.getMachineNode( @@ -22337,7 +22330,7 @@ Ops); DAG.setNodeMemRefs(cast(CmpSwap), {MemOp}); - Results.push_back(DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), MVT::i128, + Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i128, SDValue(CmpSwap, 0), SDValue(CmpSwap, 1))); Results.push_back(SDValue(CmpSwap, 3)); } @@ -22439,7 +22432,8 @@ const SDValue &Chain = N->getOperand(0); const SDValue &Ptr = N->getOperand(1); const SDValue &Val128 = N->getOperand(2); - std::pair Val2x64 = splitInt128(Val128, DAG); + std::pair Val2x64 = + DAG.SplitScalar(Val128, SDLoc(Val128), MVT::i64, MVT::i64); const unsigned ISDOpcode = N->getOpcode(); const unsigned MachineOpcode = diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -1878,13 +1878,13 @@ SDValue Zero = DAG.getConstant(0, DL, HalfVT); //HiLo split + SDValue LHS_Lo, LHS_Hi; SDValue LHS = Op.getOperand(0); - SDValue LHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, Zero); - SDValue LHS_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, One); + std::tie(LHS_Lo, LHS_Hi) = DAG.SplitScalar(LHS, DL, HalfVT, HalfVT); + SDValue RHS_Lo, RHS_Hi; SDValue RHS = Op.getOperand(1); - SDValue RHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, Zero); - SDValue RHS_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, One); + std::tie(RHS_Lo, RHS_Hi) = DAG.SplitScalar(RHS, DL, HalfVT, HalfVT); if (DAG.MaskedValueIsZero(RHS, APInt::getHighBitsSet(64, 32)) && DAG.MaskedValueIsZero(LHS, APInt::getHighBitsSet(64, 32))) { @@ -1942,10 +1942,9 @@ SDValue Neg_RHS = DAG.getNode(ISD::SUB, DL, VT, Zero64, RHS); SDValue Mullo1 = DAG.getNode(ISD::MUL, DL, VT, Neg_RHS, Rcp64); SDValue Mulhi1 = DAG.getNode(ISD::MULHU, DL, VT, Rcp64, Mullo1); - SDValue Mulhi1_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, Mulhi1, - Zero); - SDValue Mulhi1_Hi = - DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, Mulhi1, One); + SDValue Mulhi1_Lo, Mulhi1_Hi; + std::tie(Mulhi1_Lo, Mulhi1_Hi) = + DAG.SplitScalar(Mulhi1, DL, HalfVT, HalfVT); SDValue Add1_Lo = DAG.getNode(ISD::ADDCARRY, DL, HalfCarryVT, Rcp_Lo, Mulhi1_Lo, Zero1); SDValue Add1_Hi = DAG.getNode(ISD::ADDCARRY, DL, HalfCarryVT, Rcp_Hi, @@ -1956,10 +1955,9 @@ // Second round of UNR. SDValue Mullo2 = DAG.getNode(ISD::MUL, DL, VT, Neg_RHS, Add1); SDValue Mulhi2 = DAG.getNode(ISD::MULHU, DL, VT, Add1, Mullo2); - SDValue Mulhi2_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, Mulhi2, - Zero); - SDValue Mulhi2_Hi = - DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, Mulhi2, One); + SDValue Mulhi2_Lo, Mulhi2_Hi; + std::tie(Mulhi2_Lo, Mulhi2_Hi) = + DAG.SplitScalar(Mulhi2, DL, HalfVT, HalfVT); SDValue Add2_Lo = DAG.getNode(ISD::ADDCARRY, DL, HalfCarryVT, Add1_Lo, Mulhi2_Lo, Zero1); SDValue Add2_Hi = DAG.getNode(ISD::ADDCARRY, DL, HalfCarryVT, Add1_Hi, @@ -1971,8 +1969,8 @@ SDValue Mul3 = DAG.getNode(ISD::MUL, DL, VT, RHS, Mulhi3); - SDValue Mul3_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, Mul3, Zero); - SDValue Mul3_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, Mul3, One); + SDValue Mul3_Lo, Mul3_Hi; + std::tie(Mul3_Lo, Mul3_Hi) = DAG.SplitScalar(Mul3, DL, HalfVT, HalfVT); SDValue Sub1_Lo = DAG.getNode(ISD::SUBCARRY, DL, HalfCarryVT, LHS_Lo, Mul3_Lo, Zero1); SDValue Sub1_Hi = DAG.getNode(ISD::SUBCARRY, DL, HalfCarryVT, LHS_Hi, diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -11201,7 +11201,6 @@ // The actual DAG is noisier than the pseudo code, but only due to // instructions that disassemble values into low and high parts, and // assemble the final result. - SDValue Zero = DAG.getConstant(0, SL, MVT::i32); SDValue One = DAG.getConstant(1, SL, MVT::i32); auto MulLHSLo = DAG.getNode(ISD::TRUNCATE, SL, MVT::i32, MulLHS); @@ -11210,8 +11209,8 @@ getMad64_32(DAG, SL, MVT::i64, MulLHSLo, MulRHSLo, AddRHS, MulSignedLo); if (!MulSignedLo && (!MulLHSUnsigned32 || !MulRHSUnsigned32)) { - auto AccumLo = DAG.getNode(ISD::EXTRACT_ELEMENT, SL, MVT::i32, Accum, Zero); - auto AccumHi = DAG.getNode(ISD::EXTRACT_ELEMENT, SL, MVT::i32, Accum, One); + SDValue AccumLo, AccumHi; + std::tie(AccumLo, AccumHi) = DAG.SplitScalar(Accum, SL, MVT::i32, MVT::i32); if (!MulLHSUnsigned32) { auto MulLHSHi = diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -3432,10 +3432,8 @@ assert(WriteValue.getValueType() == MVT::i64 && "LowerWRITE_REGISTER called for non-i64 type argument."); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, WriteValue, - DAG.getConstant(0, DL, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, WriteValue, - DAG.getConstant(1, DL, MVT::i32)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(WriteValue, DL, MVT::i32, MVT::i32); SDValue Ops[] = { Op->getOperand(0), Op->getOperand(1), Lo, Hi }; return DAG.getNode(ISD::WRITE_REGISTER, DL, MVT::Other, Ops); } @@ -4120,11 +4118,8 @@ // else 31 + clz(if hi(x) == 0 then lo(x) else not(lo(x))) const SDValue &Operand = Op.getOperand(1); const EVT VTy = Op.getValueType(); - - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VTy, Operand, - DAG.getConstant(1, dl, VTy)); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VTy, Operand, - DAG.getConstant(0, dl, VTy)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(Operand, dl, VTy, VTy); SDValue Constant0 = DAG.getConstant(0, dl, VTy); SDValue Constant1 = DAG.getConstant(1, dl, VTy); SDValue Constant31 = DAG.getConstant(31, dl, VTy); @@ -6251,11 +6246,8 @@ // if we can combine the bitcast with its source. if (SDValue Val = CombineVMOVDRRCandidateWithVecOp(N, DAG)) return Val; - - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op, - DAG.getConstant(0, dl, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op, - DAG.getConstant(1, dl, MVT::i32)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(Op, dl, MVT::i32, MVT::i32); return DAG.getNode(ISD::BITCAST, dl, DstVT, DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi)); } @@ -6667,13 +6659,10 @@ } else if (ShOpc == ISD::SRA) ShPartsOpc = ARMISD::ASRL; - // Lower 32 bits of the destination/source - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), - DAG.getConstant(0, dl, MVT::i32)); - // Upper 32 bits of the destination/source - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), - DAG.getConstant(1, dl, MVT::i32)); - + // Split Lower/Upper 32 bits of the destination/source + SDValue Lo, Hi; + std::tie(Lo, Hi) = + DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32); // Generate the shift operation as computed above Lo = DAG.getNode(ShPartsOpc, dl, DAG.getVTList(MVT::i32, MVT::i32), Lo, Hi, ShAmt); @@ -6691,10 +6680,8 @@ return SDValue(); // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), - DAG.getConstant(0, dl, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), - DAG.getConstant(1, dl, MVT::i32)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32); // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and // captures the result into a carry flag. @@ -10016,10 +10003,8 @@ SDValue Op = N->getOperand(1); if (N->getValueType(0) == MVT::i32) return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, Op); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op, - DAG.getConstant(0, DL, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op, - DAG.getConstant(1, DL, MVT::i32)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(Op, DL, MVT::i32, MVT::i32); return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi)); } @@ -10626,12 +10611,8 @@ return; SDLoc dl(N); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, - N->getOperand(3), - DAG.getConstant(0, dl, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, - N->getOperand(3), - DAG.getConstant(1, dl, MVT::i32)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(3), dl, MVT::i32, MVT::i32); SDValue LongMul = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, MVT::i32), @@ -13678,11 +13659,9 @@ NA = DAG.getNode(ISD::ADD, dl, MVT::i64, Inp, NA); } - SmallVector Ops; - Ops.push_back(DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, NA, - DAG.getConstant(0, dl, MVT::i32))); - Ops.push_back(DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, NA, - DAG.getConstant(1, dl, MVT::i32))); + SmallVector Ops(2); + std::tie(Ops[0], Ops[1]) = DAG.SplitScalar(NA, dl, MVT::i32, MVT::i32); + unsigned S = VecRed->getOpcode() == OpcodeA ? 2 : 0; for (unsigned I = S, E = VecRed.getNumOperands(); I < E; I++) Ops.push_back(VecRed->getOperand(I)); diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -1015,16 +1015,11 @@ // Initialize accumulator. SDLoc DL(ROOTNode); - SDValue TopHalf; - SDValue BottomHalf; - BottomHalf = CurDAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, AddOperand, - CurDAG.getIntPtrConstant(0, DL)); - - TopHalf = CurDAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, AddOperand, - CurDAG.getIntPtrConstant(1, DL)); - SDValue ACCIn = CurDAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, - BottomHalf, - TopHalf); + SDValue BottomHalf, TopHalf; + std::tie(BottomHalf, TopHalf) = + CurDAG.SplitScalar(AddOperand, DL, MVT::i32, MVT::i32); + SDValue ACCIn = + CurDAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, BottomHalf, TopHalf); // Create MipsMAdd(u) / MipsMSub(u) node. bool IsAdd = ROOTNode->getOpcode() == ISD::ADD; diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp --- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp @@ -1230,10 +1230,9 @@ // Bitcast i64 to double. if (Src == MVT::i64 && Dest == MVT::f64) { - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, - Op.getOperand(0), DAG.getIntPtrConstant(0, DL)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, - Op.getOperand(0), DAG.getIntPtrConstant(1, DL)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = + DAG.SplitScalar(Op.getOperand(0), DL, MVT::i32, MVT::i32); return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi); } @@ -1277,10 +1276,8 @@ } static SDValue initAccumulator(SDValue In, const SDLoc &DL, SelectionDAG &DAG) { - SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, - DAG.getConstant(0, DL, MVT::i32)); - SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, - DAG.getConstant(1, DL, MVT::i32)); + SDValue InLo, InHi; + std::tie(InLo, InHi) = DAG.SplitScalar(In, DL, MVT::i32, MVT::i32); return DAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, InLo, InHi); } diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -8225,10 +8225,8 @@ Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept()); if (IsSigned) { - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Src, - DAG.getIntPtrConstant(0, dl)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Src, - DAG.getIntPtrConstant(1, dl)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(Src, dl, MVT::f64, MVT::f64); // Add the two halves of the long double in round-to-zero mode, and use // a smaller FP_TO_SINT. diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -2895,10 +2895,8 @@ SDValue Scalar, SDValue VL, SelectionDAG &DAG) { assert(Scalar.getValueType() == MVT::i64 && "Unexpected VT!"); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Scalar, - DAG.getConstant(0, DL, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Scalar, - DAG.getConstant(1, DL, MVT::i32)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(Scalar, DL, MVT::i32, MVT::i32); return splatPartsI64WithVL(DL, VT, Passthru, Lo, Hi, VL, DAG); } @@ -4012,10 +4010,8 @@ } if (VT == MVT::f64 && Op0VT == MVT::i64 && XLenVT == MVT::i32 && Subtarget.hasStdExtZfa()) { - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op0, - DAG.getConstant(0, DL, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op0, - DAG.getConstant(1, DL, MVT::i32)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(Op0, DL, MVT::i32, MVT::i32); SDValue RetReg = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi); return RetReg; @@ -5539,7 +5535,6 @@ MVT XLenVT = Subtarget.getXLenVT(); - SDValue Zero = DAG.getConstant(0, DL, XLenVT); bool IsLegalInsert = Subtarget.is64Bit() || Val.getValueType() != MVT::i64; // Even i64-element vectors on RV32 can be lowered without scalar // legalization if the most-significant 32 bits of the value are not affected @@ -5572,9 +5567,8 @@ // value at element 0, by using two vslide1down instructions in sequence on // the i32 split lo/hi value. Use an equivalently-sized i32 vector for // this. - SDValue One = DAG.getConstant(1, DL, XLenVT); - SDValue ValLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Val, Zero); - SDValue ValHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Val, One); + SDValue ValLo, ValHi; + std::tie(ValLo, ValHi) = DAG.SplitScalar(Val, DL, MVT::i32, MVT::i32); MVT I32ContainerVT = MVT::getVectorVT(MVT::i32, ContainerVT.getVectorElementCount() * 2); SDValue I32Mask = @@ -5804,11 +5798,9 @@ // Convert the vector source to the equivalent nxvXi32 vector. MVT I32VT = MVT::getVectorVT(MVT::i32, VT.getVectorElementCount() * 2); SDValue Vec = DAG.getBitcast(I32VT, Operands[2]); - - SDValue ScalarLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, ScalarOp, - DAG.getConstant(0, DL, XLenVT)); - SDValue ScalarHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, ScalarOp, - DAG.getConstant(1, DL, XLenVT)); + SDValue ScalarLo, ScalarHi; + std::tie(ScalarLo, ScalarHi) = + DAG.SplitScalar(ScalarOp, DL, MVT::i32, MVT::i32); // Double the VL since we halved SEW. SDValue AVL = getVLOperand(Op); diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -3144,10 +3144,8 @@ SDValue MulResult = TLI.makeLibCall(DAG, RTLIB::MUL_I128, WideVT, Args, CallOptions, dl).first; - SDValue BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, - MulResult, DAG.getIntPtrConstant(0, dl)); - SDValue TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, - MulResult, DAG.getIntPtrConstant(1, dl)); + SDValue BottomHalf, TopHalf; + std::tie(BottomHalf, TopHalf) = DAG.SplitScalar(MulResult, dl, VT, VT); if (isSigned) { SDValue Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, ShiftAmt); TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, Tmp1, ISD::SETNE); diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1438,10 +1438,8 @@ static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In) { SDLoc DL(In); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i64, In, - DAG.getIntPtrConstant(0, DL)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i64, In, - DAG.getIntPtrConstant(1, DL)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(In, DL, MVT::i64, MVT::i64); SDNode *Pair = DAG.getMachineNode(SystemZ::PAIR128, DL, MVT::Untyped, Hi, Lo); return SDValue(Pair, 0); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3190,10 +3190,7 @@ // Splitting the value into two i32 types SDValue Lo, Hi; - Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::i32, Arg, - DAG.getConstant(0, Dl, MVT::i32)); - Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::i32, Arg, - DAG.getConstant(1, Dl, MVT::i32)); + std::tie(Lo, Hi) = DAG.SplitScalar(Arg, Dl, MVT::i32, MVT::i32); // Attach the two i32 types into corresponding registers RegsToPass.push_back(std::make_pair(VA.getLocReg(), Lo)); @@ -27268,14 +27265,9 @@ assert(Subtarget.hasBWI() && "Expected AVX512BW target!"); // In case 32bit mode, bitcast i64 is illegal, extend/split it. SDValue Lo, Hi; - Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Mask, - DAG.getConstant(0, dl, MVT::i32)); - Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Mask, - DAG.getConstant(1, dl, MVT::i32)); - + std::tie(Lo, Hi) = DAG.SplitScalar(Mask, dl, MVT::i32, MVT::i32); Lo = DAG.getBitcast(MVT::v32i1, Lo); Hi = DAG.getBitcast(MVT::v32i1, Hi); - return DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v64i1, Lo, Hi); } else { MVT BitcastVT = MVT::getVectorVT(MVT::i1, @@ -32659,11 +32651,9 @@ assert(!Subtarget.is64Bit() && "Expected 32-bit mode"); assert(Subtarget.hasBWI() && "Expected BWI target"); SDLoc dl(Op); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Src, - DAG.getIntPtrConstant(0, dl)); + SDValue Lo, Hi; + std::tie(Lo, Hi) = DAG.SplitScalar(Src, dl, MVT::i32, MVT::i32); Lo = DAG.getBitcast(MVT::v32i1, Lo); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Src, - DAG.getIntPtrConstant(1, dl)); Hi = DAG.getBitcast(MVT::v32i1, Hi); return DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v64i1, Lo, Hi); } @@ -34660,21 +34650,16 @@ "64-bit ATOMIC_CMP_SWAP_WITH_SUCCESS requires CMPXCHG16B"); MVT HalfT = Regs64bit ? MVT::i64 : MVT::i32; SDValue cpInL, cpInH; - cpInL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(2), - DAG.getConstant(0, dl, HalfT)); - cpInH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(2), - DAG.getConstant(1, dl, HalfT)); + std::tie(cpInL, cpInH) = + DAG.SplitScalar(N->getOperand(2), dl, HalfT, HalfT); cpInL = DAG.getCopyToReg(N->getOperand(0), dl, - Regs64bit ? X86::RAX : X86::EAX, - cpInL, SDValue()); - cpInH = DAG.getCopyToReg(cpInL.getValue(0), dl, - Regs64bit ? X86::RDX : X86::EDX, - cpInH, cpInL.getValue(1)); + Regs64bit ? X86::RAX : X86::EAX, cpInL, SDValue()); + cpInH = + DAG.getCopyToReg(cpInL.getValue(0), dl, Regs64bit ? X86::RDX : X86::EDX, + cpInH, cpInL.getValue(1)); SDValue swapInL, swapInH; - swapInL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(3), - DAG.getConstant(0, dl, HalfT)); - swapInH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(3), - DAG.getConstant(1, dl, HalfT)); + std::tie(swapInL, swapInH) = + DAG.SplitScalar(N->getOperand(3), dl, HalfT, HalfT); swapInH = DAG.getCopyToReg(cpInH.getValue(0), dl, Regs64bit ? X86::RCX : X86::ECX, swapInH, cpInH.getValue(1));