Issue 115602
Summary opt-20 crashed with pass loop-extract
Labels new issue
Assignees
Reporter iamanonymouscs
    opt-20 Segmentation fault with pass ```loop-extract```

Test case: 
```
$ cat mutant.c
int a[];
int b[][4][6];
int c, d, e;
int __attribute__((cold)) f() {
 int g;
  for (;; e++) {
    d = 0;
    for (; d < 4; d++) {
 for (; c; c++) {
        g = 0;
        for (; g < 2; g++)
 a[g] = b[g][d][e];
      }
      for (; g < 4; g++)
        for (; c < 2;)
          c = b[g][d][c];
    }
  }
}
```

I used the following command to generate LLVM IR with ```-O3```:
```
$ clang -S -emit-llvm -O3 mutant.c -o mutant.ll
$ cat mutant.ll
@d = dso_local local_unnamed_addr global i32 0, align 4
@c = dso_local local_unnamed_addr global i32 0, align 4
@e = dso_local local_unnamed_addr global i32 0, align 4
@a = dso_local local_unnamed_addr global [1 x i32] zeroinitializer, align 4
@b = dso_local local_unnamed_addr global [1 x [4 x [6 x i32]]] zeroinitializer, align 16

define dso_local noundef i32 @f() local_unnamed_addr {
entry:
  %c.promoted = load i32, ptr @c, align 4
  %e.promoted = load i32, ptr @e, align 4
  %0 = sext i32 %e.promoted to i64
  br label %for.cond

for.cond:
 %indvars.iv77 = phi i64 [ %indvars.iv.next78, %for.inc35 ], [ %0, %entry ]
  %c.promoted5367 = phi i32 [ %c.promoted5362, %for.inc35 ], [ %c.promoted, %entry ]
  br label %for.cond2thread-pre-split

for.cond2thread-pre-split:
 %indvars.iv73 = phi i64 [ 0, %for.cond ], [ %indvars.iv.next74, %for.inc32 ]
  %c.promoted5366 = phi i32 [ %c.promoted5367, %for.cond ], [ %c.promoted5362, %for.inc32 ]
  %c.promoted5459 = phi i32 [ %c.promoted5367, %for.cond ], [ %c.promoted55, %for.inc32 ]
 %tobool.not45 = icmp eq i32 %c.promoted5459, 0
  br i1 %tobool.not45, label %for.inc32, label %for.cond4.preheader.preheader

for.cond4.preheader.preheader:
 %arrayidx10.c = getelementptr inbounds [0 x [4 x [6 x i32]]], ptr @b, i64 0, i64 1, i64 %indvars.iv73, i64 %indvars.iv77
  %1 = load i32, ptr %arrayidx10.c, align 4
  store i32 %1, ptr getelementptr inbounds (i8, ptr @a, i64 4), align 4
  br label %for.cond4.preheader

for.cond4.preheader:
  %2 = phi i32 [ %inc14, %for.cond4.preheader ], [ %c.promoted5459, %for.cond4.preheader.preheader ]
  %inc14 = add nsw i32 %2, 1
  %tobool.not = icmp eq i32 %inc14, 0
  br i1 %tobool.not, label %for.cond19thread-pre-split, label %for.cond4.preheader

for.cond19thread-pre-split:
  %indvars.iv70 = phi i64 [ %indvars.iv.next71, %for.inc29 ], [ 2, %for.cond4.preheader ]
 %c.promoted5364 = phi i32 [ %c.promoted5363, %for.inc29 ], [ 0, %for.cond4.preheader ]
  %c.promoted57 = phi i32 [ %c.promoted56, %for.inc29 ], [ 0, %for.cond4.preheader ]
  %.lcssa4850 = phi i32 [ %.lcssa47, %for.inc29 ], [ 0, %for.cond4.preheader ]
  %cmp2046 = icmp slt i32 %.lcssa4850, 2
  br i1 %cmp2046, label %for.body21, label %for.inc29

for.body21:
  %3 = phi i32 [ %4, %for.body21 ], [ %.lcssa4850, %for.cond19thread-pre-split ]
  %idxprom26 = sext i32 %3 to i64
  %arrayidx27 = getelementptr inbounds [0 x [4 x [6 x i32]]], ptr @b, i64 0, i64 %indvars.iv70, i64 %indvars.iv73, i64 %idxprom26
  %4 = load i32, ptr %arrayidx27, align 4
  %cmp20 = icmp slt i32 %4, 2
  br i1 %cmp20, label %for.body21, label %for.inc29

for.inc29:
 %c.promoted5363 = phi i32 [ %c.promoted5364, %for.cond19thread-pre-split ], [ %4, %for.body21 ]
  %c.promoted56 = phi i32 [ %c.promoted57, %for.cond19thread-pre-split ], [ %4, %for.body21 ]
  %.lcssa47 = phi i32 [ %.lcssa4850, %for.cond19thread-pre-split ], [ %4, %for.body21 ]
 %indvars.iv.next71 = add nuw nsw i64 %indvars.iv70, 1
  %exitcond.not = icmp eq i64 %indvars.iv.next71, 4
  br i1 %exitcond.not, label %for.inc32, label %for.cond19thread-pre-split

for.inc32:
  %c.promoted5362 = phi i32 [ %c.promoted5366, %for.cond2thread-pre-split ], [ %c.promoted5363, %for.inc29 ]
  %c.promoted55 = phi i32 [ 0, %for.cond2thread-pre-split ], [ %c.promoted56, %for.inc29 ]
  %indvars.iv.next74 = add nuw nsw i64 %indvars.iv73, 1
  %exitcond76.not = icmp eq i64 %indvars.iv.next74, 4
 br i1 %exitcond76.not, label %for.inc35, label %for.cond2thread-pre-split

for.inc35:
  %indvars.iv.next78 = add nsw i64 %indvars.iv77, 1
  br label %for.cond
}
```

Then I used opt to optimize mutant.ll with ```-pass=loop-extract```
```
$ opt -pass=loop-extract mutant.ll -o mutant.opt.ll
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: opt -passes=loop-extract mutant.ll -o mutant.opt.ll
1.      Running pass "loop-extract<>" on module "mutant.ll"
 #0 0x00007fccc4fed246 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0xea7246)
 #1 0x00007fccc4feae20 llvm::sys::RunSignalHandlers() (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0xea4e20)
 #2 0x00007fccc4fed90b (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0xea790b)
 #3 0x00007fccc3c27520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007fccc6599538 llvm::LoopInfo::erase(llvm::Loop*) (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0x2453538)
 #5 0x00007fccc61dc42a (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0x209642a)
 #6 0x00007fccc61dc30e (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0x209630e)
 #7 0x00007fccc61dbb77 (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0x2095b77)
 #8 0x00007fccc61db8c8 llvm::LoopExtractorPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0x20958c8)
 #9 0x00007fccc82b816d (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0x417216d)
#10 0x00007fccc5172b99 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/usr/lib/llvm-19/bin/../lib/libLLVM.so.19.0+0x102cb99)
#11 0x0000564419518091 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) (/usr/lib/llvm-19/bin/opt+0x29091)
#12 0x000056441950d3b2 optMain (/usr/lib/llvm-19/bin/opt+0x1e3b2)
#13 0x00007fccc3c0ed90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#14 0x00007fccc3c0ee40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#15 0x0000564419507795 _start (/usr/lib/llvm-19/bin/opt+0x18795)
Segmentation fault (core dumped)
```

Notice that if I remove ```cold``` attribute in mutant.c, opt didn't crash.
Validate Link (with cold attribute):  https://godbolt.org/z/fadfjPGW5
Validate Link (without cold attribute):  https://godbolt.org/z/W7Kq55MWj
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to