Skip to content

[SelectionDAG] Fix the assertion failure in Release build after #91747 #93416

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

Closed
wants to merge 1 commit into from

Conversation

KanRobert
Copy link
Contributor

@KanRobert KanRobert commented May 26, 2024

In #91747, we changed the SDNode from X86ISD::SUB (FROM) to X86ISD::CCMP (TO) in the DAGCombine. The value type of X86ISD::SUB can be i8, i32 while the value type of X86ISD::CCMP is i32.

That means the SDValue(FROM, 0) is unused and may be removed. However, transferDbgValues assumes the value is not null, which is called by ReplaceAllUsesWith(SDNode *, const SDValue *). So we need to check if the value has any use before calling the function.

Note: We already have same check in ReplaceAllUsesWith(SDNode *, SDNode *).

This fix the error

SelectionDAG.cpp:10942: void
llvm::SelectionDAG::transferDbgValues(llvm::SDValue, llvm::SDValue,
unsigned int, unsigned int, bool): Assertion `FromNode && ToNode &&
"Can't modify dbg values"' failed.

for tests

llvm/test/CodeGen/X86/apx/ccmp.ll
llvm/test/CodeGen/X86/apx/ctest.ll

in Release build when LLVM_ENABLE_ASSERTIONS is on.

…91747

In llvm#91747, we change the SDNode from `X86ISD::SUB` (FROM) to
`X86ISD::CCMP` (TO) in the DAGCombine. The value type of X86ISD::SUB
can be `i8, i32` while the value type of X86ISD::CCMP is `i32`.

That means the `SDValue(FROM, 0)` is unused and may be removed.
However, `transferDbgValues` assumes the value is not null, which is
called by `ReplaceAllUsesWith(SDNode *, const SDValue *)`.
So we need to check if the value has any use before calling the function.

Note: We already have same check in `ReplaceAllUsesWith(SDNode *, SDNode *)`.

This fix the error

```
SelectionDAG.cpp:10942: void
llvm::SelectionDAG::transferDbgValues(llvm::SDValue, llvm::SDValue,
unsigned int, unsigned int, bool): Assertion `FromNode && ToNode &&
"Can't modify dbg values"' failed.
```

for tests

llvm/test/CodeGen/X86/apx/ccmp.ll
llvm/test/CodeGen/X86/apx/ctest.ll

in Release build when LLVM_ENABLE_ASSERTIONS is on.
@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label May 26, 2024
@llvmbot
Copy link
Member

llvmbot commented May 26, 2024

@llvm/pr-subscribers-llvm-selectiondag

Author: Shengchen Kan (KanRobert)

Changes

In #91747, we change the SDNode from X86ISD::SUB (FROM) to X86ISD::CCMP (TO) in the DAGCombine. The value type of X86ISD::SUB can be i8, i32 while the value type of X86ISD::CCMP is i32.

That means the SDValue(FROM, 0) is unused and may be removed. However, transferDbgValues assumes the value is not null, which is called by ReplaceAllUsesWith(SDNode *, const SDValue *). So we need to check if the value has any use before calling the function.

Note: We already have same check in ReplaceAllUsesWith(SDNode *, SDNode *).

This fix the error

SelectionDAG.cpp:10942: void
llvm::SelectionDAG::transferDbgValues(llvm::SDValue, llvm::SDValue,
unsigned int, unsigned int, bool): Assertion `FromNode && ToNode &&
"Can't modify dbg values"' failed.

for tests

llvm/test/CodeGen/X86/apx/ccmp.ll
llvm/test/CodeGen/X86/apx/ctest.ll

in Release build when LLVM_ENABLE_ASSERTIONS is on.


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

1 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+6-4)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b05649c6ce955..f21b17102bde5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -11293,10 +11293,12 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, const SDValue *To) {
     return ReplaceAllUsesWith(SDValue(From, 0), To[0]);
 
   for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) {
-    // Preserve Debug Info.
-    transferDbgValues(SDValue(From, i), To[i]);
-    // Preserve extra info.
-    copyExtraInfo(From, To[i].getNode());
+    if (From->hasAnyUseOfValue(i)) {
+      // Preserve Debug Info.
+      transferDbgValues(SDValue(From, i), To[i]);
+      // Preserve extra info.
+      copyExtraInfo(From, To[i].getNode());
+    }
   }
 
   // Iterate over just the existing users of From. See the comments in

// Preserve Debug Info.
transferDbgValues(SDValue(From, i), To[i]);
// Preserve extra info.
copyExtraInfo(From, To[i].getNode());
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like you're reading uninitialized memory here. The number of results must match exactly, which is not true when you're replacing (i8, i32) with just (i32).

@KanRobert
Copy link
Contributor Author

See the new solution #93434

@KanRobert KanRobert closed this May 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants