Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] A replaced SDValue is used to call getNode function #82881

Merged
merged 1 commit into from
Feb 29, 2024
Merged

[Fix] A replaced SDValue is used to call getNode function #82881

merged 1 commit into from
Feb 29, 2024

Conversation

RicoAfoat
Copy link
Contributor

@RicoAfoat RicoAfoat commented Feb 24, 2024

Fixes #82431 - see #82431 for more infomation.

Bug Trace:

Zext in the modified code piece might be replaced by other SDValue and deleted during SelectInlineAsmMemoryOperand method, but it remains as element in Ops vector which will be used to call getNode builder, which is illegal.

// llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
void SelectionDAGISel::Select_INLINEASM(SDNode *N) {
  SDLoc DL(N);

  std::vector<SDValue> Ops(N->op_begin(), N->op_end());
  SelectInlineAsmMemoryOperands(Ops, DL); // t39 is builded and deleted here, but it remains in Ops

  const EVT VTs[] = {MVT::Other, MVT::Glue};
  SDValue New = CurDAG->getNode(N->getOpcode(), DL, VTs, Ops);// t39 is a DELETED_NODE, assertion fails in builder
  New->setNodeId(-1);
  ReplaceUses(N, New.getNode());
  CurDAG->RemoveDeadNode(N);
}
// llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
                                               X86ISelAddressMode &AM,
                                               unsigned Depth) {
  ...
  if (Opc == ISD::ZERO_EXTEND && !VT.isVector() && N.hasOneUse()) {
    ...
    if (((SrcOpc == ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
         CurDAG->isADDLike(Src)) &&
        Src.hasOneUse()) {
      if (CurDAG->isBaseWithConstantOffset(Src)) {
        ...
        if (!foldOffsetIntoAddress(Offset * AM.Scale, AM)) {
          ...
          CurDAG->ReplaceAllUsesWith(N, ExtAdd); //t39 is replaced here, but later it will be used as 
          CurDAG->RemoveDeadNode(N.getNode());// parameters to call a builder method.
          return Res ? Res : ExtSrc;
        }
      }
    }
  }
 ...
  return N;
}

Reason Why Modify Like This:

  1. SelectInlineAsmMemoryOperands is a method which all target machine architecture share, bug only happens in x86, can't be fixed here.
  2. Due to the way SelectInlineAsmMemoryOperand interact with SelectInlineAsmMemoryOperand, it is hard to modify element in Ops after it is pushed into.
  3. (In file llvm/lib/Target/X86/X86ISelDAGToDAG.cpp)matchAddressRecursively in case ISD::ZERO_EXTEND generates Zext and NewShl, but the generation is not consistent with how matchAddressRecursively deal with ISD::SHL. The latter calls matchIndexRecursively to replace Zext. I modified this so that the correct AM.IndexReg in this situation will enter Ops.

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 24, 2024

@llvm/pr-subscribers-backend-x86

Author: RicoAfoat (RicoAfoat)

Changes

See #82431 for more infomation.

Bug Trace:

Zext in the modified code piece might be replaced by other SDValue and deleted during SelectInlineAsmMemoryOperand method, but it remains as element in Ops vector which will be used to call getNode builder, which is illegal.

// llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
void SelectionDAGISel::Select_INLINEASM(SDNode *N) {
  SDLoc DL(N);

  std::vector&lt;SDValue&gt; Ops(N-&gt;op_begin(), N-&gt;op_end());
  SelectInlineAsmMemoryOperands(Ops, DL); // t39 is builded and deleted here, but it remains in Ops

  const EVT VTs[] = {MVT::Other, MVT::Glue};
  SDValue New = CurDAG-&gt;getNode(N-&gt;getOpcode(), DL, VTs, Ops);// t39 is a DELETED_NODE, assertion fails in builder
  New-&gt;setNodeId(-1);
  ReplaceUses(N, New.getNode());
  CurDAG-&gt;RemoveDeadNode(N);
}
// llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
                                               X86ISelAddressMode &amp;AM,
                                               unsigned Depth) {
  ...
  if (Opc == ISD::ZERO_EXTEND &amp;&amp; !VT.isVector() &amp;&amp; N.hasOneUse()) {
    ...
    if (((SrcOpc == ISD::ADD &amp;&amp; Src-&gt;getFlags().hasNoUnsignedWrap()) ||
         CurDAG-&gt;isADDLike(Src)) &amp;&amp;
        Src.hasOneUse()) {
      if (CurDAG-&gt;isBaseWithConstantOffset(Src)) {
        ...
        if (!foldOffsetIntoAddress(Offset * AM.Scale, AM)) {
          ...
          CurDAG-&gt;ReplaceAllUsesWith(N, ExtAdd); //t39 is replaced here, but later it will be used as 
          CurDAG-&gt;RemoveDeadNode(N.getNode());// parameters to call a builder method.
          return Res ? Res : ExtSrc;
        }
      }
    }
  }
 ...
  return N;
}

Reason Why Modify Like This:

  1. SelectInlineAsmMemoryOperands is a method which all target machine architecture share, bug only happens in x86, can't be fixed here.
  2. Due to the way SelectInlineAsmMemoryOperand interact with SelectInlineAsmMemoryOperand, it is hard to modify element in Ops after it is pushed into.
  3. (In file llvm/lib/Target/X86/X86ISelDAGToDAG.cpp)matchAddressRecursively in case ISD::ZERO_EXTEND generates Zext and NewShl, but the generation is not consistent with how matchAddressRecursively deal with ISD::SHL. The latter calls matchIndexRecursively to replace Zext. I modified this so that the correct AM.IndexReg in this situation will enter Ops.

Full diff: https://github.com/llvm/llvm-project/pull/82881.diff

1 Files Affected:

  • (modified) llvm/lib/Target/X86/X86ISelDAGToDAG.cpp (+5-4)
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index c8f80ced354538..50be61c56e951c 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -2732,13 +2732,14 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
       insertDAGNode(*CurDAG, N, Zext);
       SDValue NewShl = CurDAG->getNode(ISD::SHL, DL, VT, Zext, ShlAmt);
       insertDAGNode(*CurDAG, N, NewShl);
+      CurDAG->ReplaceAllUsesWith(N, NewShl);
+      CurDAG->RemoveDeadNode(N.getNode());
 
       // Convert the shift to scale factor.
       AM.Scale = 1 << ShAmtV;
-      AM.IndexReg = Zext;
-
-      CurDAG->ReplaceAllUsesWith(N, NewShl);
-      CurDAG->RemoveDeadNode(N.getNode());
+      // If matchIndexRecursively is not called here, 
+      // Zext may be replaced by other nodes but later used to call a builder method
+      AM.IndexReg = matchIndexRecursively(Zext, AM, Depth + 1);
       return false;
     }
 

Copy link

github-actions bot commented Feb 24, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@RicoAfoat RicoAfoat changed the title <Fix> incorrect IndexReg parameter [Fix] incorrect IndexReg parameter Feb 24, 2024
@RicoAfoat RicoAfoat changed the title [Fix] incorrect IndexReg parameter [Fix] A replaced SDValue is used to call getNode function Feb 24, 2024
@RKSimon RKSimon self-requested a review February 24, 2024 15:21
@RKSimon
Copy link
Collaborator

RKSimon commented Feb 24, 2024

Please can you add the #82431 test

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor comments

@@ -0,0 +1,15 @@
; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add FileCheck and run this through the update_llc_test_checks.py script to show the codegen

; calling for SelectionDAGISel::Select_INLINEASM getNode builder, see issue
; 82431 for more infomation.

define void @d(i8 %call, ptr %b) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(style) rename this @PR82431

Copy link
Contributor Author

@RicoAfoat RicoAfoat Feb 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excuse me, which name should I pick : @PR82881 or mention the related issue in another style ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historically, PR is an abbreviation for "Problem Report", so @PR82431 would be correct. See https://llvm.org/docs/TestingGuide.html#other-features

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently, https://llvm.org/PR82431 opens the wrong issue.

@RKSimon I've seen other people use GHxxxxx syntax. Could it be a better choice now?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR#### number should be the bug issue report, not the pull request. PR doesn't mean Pull Request it means Problem Report.

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - cheers

@RKSimon
Copy link
Collaborator

RKSimon commented Feb 27, 2024

@RicoAfoat Please can you cleanup the patch title/summary for the commit

@RKSimon
Copy link
Collaborator

RKSimon commented Feb 27, 2024

@RicoAfoat "[X86] Fix a replaced SDValue is used to call getNode function " doesn't explain much, maybe: "[X86] matchAddressRecursively - ensure dead nodes are replaced before matching the index register"

@RicoAfoat
Copy link
Contributor Author

RicoAfoat commented Feb 29, 2024

@RKSimon Sorry but I forgot to tell you that I don't have commit access. And buildkite start to fail on a strange flang testcase (it seems like it is an irrelevant test) although I only changed my commit message. Am I suppose to do anything else?

@RKSimon
Copy link
Collaborator

RKSimon commented Feb 29, 2024

@RicoAfoat I'll commit for - cheers

@RKSimon RKSimon merged commit 1e6627e into llvm:main Feb 29, 2024
3 of 4 checks passed
Copy link

@RicoAfoat Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested
by our build bots. If there is a problem with a build, you may recieve a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as
the builds can include changes from many authors. It is not uncommon for your
change to be included in a build that fails due to someone else's changes, or
infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail here.

If your change does cause a problem, it may be reverted, or you can revert it yourself.
This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants