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

AArch64 infinite recursion at llvm::DAGTypeLegalizer::RemapId(unsigned int&) #57251

Open
DataCorrupted opened this issue Aug 19, 2022 · 2 comments
Labels
backend:AArch64 llvm:hang Compiler hang (infinite loop)

Comments

@DataCorrupted
Copy link
Member

DataCorrupted commented Aug 19, 2022

When compiling the following piece of code, AARch64 will fall into an infinite loop. While x64_64 is fine with it.

Reproduce

llc -mtriple=aarch64 <filename>
llc -mtriple=x86_64 <filename>
; ModuleID = 'aarch64-dag-crashes/id:000001,sig:11,src:016155+013757,time:72939681,execs:21049155,op:libAFLCustomIRMutator.so,pos:0'
source_filename = "M"

define void @f() {
BB:
  %A3 = alloca i16, align 2
  %A2 = alloca i16, align 2
  %A = alloca <4 x i16>, align 8
  %L = load <4 x i16>, <4 x i16>* %A, align 8
  %B = sub <4 x i16> %L, %L
  %B1 = srem <4 x i16> %B, %B
  %E = extractelement <4 x i16> %B, i8 0
  %I = insertelement <4 x i16> %B1, i16 %E, i16 0
  store <4 x i16> %I, <4 x i16>* %A, align 8
  %E1 = extractelement <4 x i16> %I, i16 %E
  store i16 %E1, i16* %A2, align 2
  %E2 = extractelement <4 x i16> %B, i16 %E1
  %E3 = extractelement <4 x i16> %I, i16 %E2
  store i16 %E3, i16* %A3, align 2
  ret void
}

Error message

PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0.      Program arguments: .../llvm-project/build-debug/bin/llc -mtriple=aarch64 id:000001,sig:11,src:016155+013757,time:72939681,execs:21049155,op:libAFLCustomIRMutator.so,pos:0.ll
1.      Running pass 'Function Pass Manager' on module 'id:000001,sig:11,src:016155+013757,time:72939681,execs:21049155,op:libAFLCustomIRMutator.so,pos:0.ll'.
2.      Running pass 'AArch64 Instruction Selection' on function '@f'
  #0 0x00000000030fa65a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) .../llvm-project/llvm/lib/Support/Unix/Signals.inc:569:11
  #1 0x00000000030fa80b PrintStackTraceSignalHandler(void*) .../llvm-project/llvm/lib/Support/Unix/Signals.inc:636:1
  #2 0x00000000030f8e56 llvm::sys::RunSignalHandlers() .../llvm-project/llvm/lib/Support/Signals.cpp:103:5
  #3 0x00000000030faf35 SignalHandler(int) .../llvm-project/llvm/lib/Support/Unix/Signals.inc:407:1
  #4 0x00007f6a59964980 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12980)
  #5 0x0000000002f1f5f8 llvm::SmallDenseMap<unsigned int, unsigned int, 8u, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>::getBuckets() const .../llvm-project/llvm/include/llvm/ADT/DenseMap.h:1160:0
  #6 0x0000000002f1f595 llvm::DenseMapBase<llvm::SmallDenseMap<unsigned int, unsigned int, 8u, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>, unsigned int, unsigned int, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>::getBuckets() const .../llvm-project/llvm/include/llvm/ADT/DenseMap.h:517:5
  #7 0x0000000002f1f391 bool llvm::DenseMapBase<llvm::SmallDenseMap<unsigned int, unsigned int, 8u, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>, unsigned int, unsigned int, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>::LookupBucketFor<unsigned int>(unsigned int const&, llvm::detail::DenseMapPair<unsigned int, unsigned int> const*&) const .../llvm-project/llvm/include/llvm/ADT/DenseMap.h:610:33
  #8 0x0000000002f1f2d5 bool llvm::DenseMapBase<llvm::SmallDenseMap<unsigned int, unsigned int, 8u, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>, unsigned int, unsigned int, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>::LookupBucketFor<unsigned int>(unsigned int const&, llvm::detail::DenseMapPair<unsigned int, unsigned int>*&) .../llvm-project/llvm/include/llvm/ADT/DenseMap.h:661:10
  #9 0x0000000002f1ad9d llvm::DenseMapBase<llvm::SmallDenseMap<unsigned int, unsigned int, 8u, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>, unsigned int, unsigned int, llvm::DenseMapInfo<unsigned int, void>, llvm::detail::DenseMapPair<unsigned int, unsigned int>>::find(unsigned int const&) .../llvm-project/llvm/include/llvm/ADT/DenseMap.h:152:9
 #10 0x0000000002f1756c llvm::DAGTypeLegalizer::RemapId(unsigned int&) .../llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:585:27
 #11 0x0000000002f17617 llvm::DAGTypeLegalizer::RemapId(unsigned int&) .../llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:591:10
 #12 0x0000000002f17617 llvm::DAGTypeLegalizer::RemapId(unsigned int&) .../llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:591:10
 #13 0x0000000002f17617 llvm::DAGTypeLegalizer::RemapId(unsigned int&) .../llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:591:10
......
#253 0x0000000002f17617 llvm::DAGTypeLegalizer::RemapId(unsigned int&) .../llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:591:10
#254 0x0000000002f17617 llvm::DAGTypeLegalizer::RemapId(unsigned int&) .../llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:591:10
#255 0x0000000002f17617 llvm::DAGTypeLegalizer::RemapId(unsigned int&) .../llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:591:10
Segmentation fault

This has been observed on LLVM-14 and latest commit cfd2c5c.

Some analysis

Problem starts from LegalizeTypes.cpp:697

void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) {
         .....
          DAG.ReplaceAllUsesOfValueWith(OldVal, NewVal);
          if (OldValId != NewValId)
            ReplacedValues[OldValId] = NewValId;
}

 void NoteDeletion(SDNode *Old, SDNode *New) {
      if (OldId != NewId) {
        ReplacedValues[OldId] = NewId;
        .......
      }
}

For some reason, ReplaceAllUsesOfValueWith(...) eventually calls NoteDeletion(...). But by then OldVal and NewVal are switched.
Therefore, when NoteDeletion(...) in LegalizeTypes.h:185 are called, a reversed relation is added to ReplacedValues.
After ReplaceAllUsesOfValueWith(...), the original relation is also added to ReplacedValues, causing a loop, and later resulting infinite recursion.

My stack trace vagelly look like this when ReplacedValues is incorrectly updated :

    frame #0: 0x0000000002f1f848 llc`llvm::DAGTypeLegalizer::NoteDeletion(this=0x00007fffffffa698, Old=0x0000000006174c40, New=0x0000000006174b70) at LegalizeTypes.h:209:9
    frame #1: 0x0000000002f1b11f llc`(anonymous namespace)::NodeUpdateListener::NodeDeleted(this=0x00007fffffff9e80, N=0x0000000006174c40, E=0x0000000006174b70) at LegalizeTypes.cpp:631:9
    frame #2: 0x0000000002df541c llc`llvm::SelectionDAG::AddModifiedNodeToCSEMaps(this=0x00000000060fa2c0, N=0x0000000006174c40) at SelectionDAG.cpp:1173:14
    frame #3: 0x0000000002df585a llc`llvm::SelectionDAG::ReplaceAllUsesWith(this=0x00000000060fa2c0, From=0x0000000006174bd8, To=0x0000000006174968) at SelectionDAG.cpp:10311:5
    frame #4: 0x0000000002df53f0 llc`llvm::SelectionDAG::AddModifiedNodeToCSEMaps(this=0x00000000060fa2c0, N=0x0000000006174bd8) at SelectionDAG.cpp:1169:7
    frame #5: 0x0000000002e3ac23 llc`llvm::SelectionDAG::ReplaceAllUsesWith(this=0x00000000060fa2c0, FromN=SDValue @ 0x00007fffffff9ae0, To=SDValue @ 0x00007fffffff9ad0) at SelectionDAG.cpp:10250:5
    frame #6: 0x0000000002e37c6d llc`llvm::SelectionDAG::ReplaceAllUsesOfValueWith(this=0x00000000060fa2c0, From=SDValue @ 0x00007fffffff9be0, To=SDValue @ 0x00007fffffff9bd0) at SelectionDAG.cpp:10378:5
    frame #7: 0x0000000002f17961 llc`llvm::DAGTypeLegalizer::ReplaceValueWith(this=0x00007fffffffa698, From=SDValue @ 0x00007fffffff9fe0, To=SDValue @ 0x00007fffffff9fd0) at LegalizeTypes.cpp:732:15
    frame #8: 0x0000000002fa7949 llc`llvm::DAGTypeLegalizer::PromoteIntegerOperand(this=0x00007fffffffa698, N=0x00000000061746f8, OpNo=0) at LegalizeIntegerTypes.cpp:1754:3
    frame #9: 0x0000000002f16337 llc`llvm::DAGTypeLegalizer::run(this=0x00007fffffffa698) at LegalizeTypes.cpp:336:30

I'll keep working on it to provide more info. However, there are some Legalize details I am not really familiar with. If anyone can point me where to get more detail about Legalizer it'd be best.

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 19, 2022

@llvm/issue-subscribers-backend-aarch64

@fhahn fhahn added the llvm:hang Compiler hang (infinite loop) label Aug 20, 2022
@DataCorrupted
Copy link
Member Author

https://godbolt.org/z/rKv56aa8d

This problems still exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 llvm:hang Compiler hang (infinite loop)
Projects
None yet
Development

No branches or pull requests

4 participants