From 46505b3cbfc5f48f28431b9141085c5d71ddf1c4 Mon Sep 17 00:00:00 2001 From: RicoAfoat <51285519+RicoAfoat@users.noreply.github.com> Date: Tue, 16 Jul 2024 19:46:32 +0800 Subject: [PATCH] [SelectionDAG] use HandleSDNode instead of SDValue during SelectInlineAsmMemoryOperands (#85081) SelectInlineAsmMemoryOperands - change the vector of SDValue into a list of SDNodeHandle. Fixes issues where x86 might call replaceAllUses when matching address. Fixes https://github.com/llvm/llvm-project/issues/82431 - see https://github.com/llvm/llvm-project/issues/82431 for more information. --- .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 43 +++++++------ llvm/test/CodeGen/X86/inline-asm-memop.ll | 64 ++++++++++++++++--- 2 files changed, 80 insertions(+), 27 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index ecdbf3e963b835..df3d207d85d351 100644 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2220,24 +2220,27 @@ bool SelectionDAGISel::CheckOrMask(SDValue LHS, ConstantSDNode *RHS, /// by tblgen. Others should not call it. void SelectionDAGISel::SelectInlineAsmMemoryOperands(std::vector &Ops, const SDLoc &DL) { - std::vector InOps; - std::swap(InOps, Ops); + // Change the vector of SDValue into a list of SDNodeHandle for x86 might call + // replaceAllUses when matching address. - Ops.push_back(InOps[InlineAsm::Op_InputChain]); // 0 - Ops.push_back(InOps[InlineAsm::Op_AsmString]); // 1 - Ops.push_back(InOps[InlineAsm::Op_MDNode]); // 2, !srcloc - Ops.push_back(InOps[InlineAsm::Op_ExtraInfo]); // 3 (SideEffect, AlignStack) + std::list Handles; - unsigned i = InlineAsm::Op_FirstOperand, e = InOps.size(); - if (InOps[e-1].getValueType() == MVT::Glue) + Handles.emplace_back(Ops[InlineAsm::Op_InputChain]); // 0 + Handles.emplace_back(Ops[InlineAsm::Op_AsmString]); // 1 + Handles.emplace_back(Ops[InlineAsm::Op_MDNode]); // 2, !srcloc + Handles.emplace_back( + Ops[InlineAsm::Op_ExtraInfo]); // 3 (SideEffect, AlignStack) + + unsigned i = InlineAsm::Op_FirstOperand, e = Ops.size(); + if (Ops[e - 1].getValueType() == MVT::Glue) --e; // Don't process a glue operand if it is here. while (i != e) { - InlineAsm::Flag Flags(InOps[i]->getAsZExtVal()); + InlineAsm::Flag Flags(Ops[i]->getAsZExtVal()); if (!Flags.isMemKind() && !Flags.isFuncKind()) { // Just skip over this operand, copying the operands verbatim. - Ops.insert(Ops.end(), InOps.begin() + i, - InOps.begin() + i + Flags.getNumOperandRegisters() + 1); + Handles.insert(Handles.end(), Ops.begin() + i, + Ops.begin() + i + Flags.getNumOperandRegisters() + 1); i += Flags.getNumOperandRegisters() + 1; } else { assert(Flags.getNumOperandRegisters() == 1 && @@ -2247,10 +2250,10 @@ void SelectionDAGISel::SelectInlineAsmMemoryOperands(std::vector &Ops, if (Flags.isUseOperandTiedToDef(TiedToOperand)) { // We need the constraint ID from the operand this is tied to. unsigned CurOp = InlineAsm::Op_FirstOperand; - Flags = InlineAsm::Flag(InOps[CurOp]->getAsZExtVal()); + Flags = InlineAsm::Flag(Ops[CurOp]->getAsZExtVal()); for (; TiedToOperand; --TiedToOperand) { CurOp += Flags.getNumOperandRegisters() + 1; - Flags = InlineAsm::Flag(InOps[CurOp]->getAsZExtVal()); + Flags = InlineAsm::Flag(Ops[CurOp]->getAsZExtVal()); } } @@ -2258,7 +2261,7 @@ void SelectionDAGISel::SelectInlineAsmMemoryOperands(std::vector &Ops, std::vector SelOps; const InlineAsm::ConstraintCode ConstraintID = Flags.getMemoryConstraintID(); - if (SelectInlineAsmMemoryOperand(InOps[i+1], ConstraintID, SelOps)) + if (SelectInlineAsmMemoryOperand(Ops[i + 1], ConstraintID, SelOps)) report_fatal_error("Could not match memory address. Inline asm" " failure!"); @@ -2267,15 +2270,19 @@ void SelectionDAGISel::SelectInlineAsmMemoryOperands(std::vector &Ops, : InlineAsm::Kind::Func, SelOps.size()); Flags.setMemConstraint(ConstraintID); - Ops.push_back(CurDAG->getTargetConstant(Flags, DL, MVT::i32)); - llvm::append_range(Ops, SelOps); + Handles.emplace_back(CurDAG->getTargetConstant(Flags, DL, MVT::i32)); + Handles.insert(Handles.end(), SelOps.begin(), SelOps.end()); i += 2; } } // Add the glue input back if present. - if (e != InOps.size()) - Ops.push_back(InOps.back()); + if (e != Ops.size()) + Handles.emplace_back(Ops.back()); + + Ops.clear(); + for (auto &handle : Handles) + Ops.push_back(handle.getValue()); } /// findGlueUse - Return use of MVT::Glue value produced by the specified