<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/115602>115602</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
opt-20 crashed with pass loop-extract
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
iamanonymouscs
</td>
</tr>
</table>
<pre>
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
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWltz46gS_jXkhbILoZv1kIdcJudMbXJ2ajI1--hCAsvsItAilMv8-lMgWzdjO9nkVJ2plC1D83XT_dE0jEjT8FIydgniaxDfXpDWbJW-5KQiUsnXSrVN0Vzkir5eqtosMIKPrKyYNMRwJeGGtMLAZ262sCZNA0GCuj-hVL1gL0aTwvSNAN0CdNV9_mCNgQVpGAiv4K5jJocjWBADq9YQaZZF18qlgaQzFoTXQ1u-a4uvo-4rmUsUAN9Aaj_YpH29JsZonreGrdcArwBeFUpQgDOAM7hxLRkE6W4ItGPKHgHCjdLQCoXXILyGDOBr9zceAiGkEIS3EI3GjUe67hsYuUcfwki06D78auy_0qNqpq506rB77JF20ta7JYhvHUq--wHia9p9sbFfO2CQ3o5_HuiJvHoOrSp6qw6koOv02VPM7RlZ0z8ODz4ufoVtwyg0WwY3Sgj1zGUJC1VVRFJoFCyZZJoYBu_vfz7Ar987wvdQi9_DATa8Ok5mQWQJF49wwSpuFkI8VXDxe9gTHC7U_lkI7xromyPU8Yk2ai1UQQR0n-tWSlIxuiaUalgKlRMBeYghsrQngpcSRj1E8XEI9nEI8mYIEF8H8MUiWXb-YlpxyQ0ngv9i2gedvxfaZo_uK-kVdX_H1QXJmEqUbbhkI51StZKyjZs_iNA-nXhM6dcxk0a_9kSCEOC4WNZaVcqwLuxCEerMwzewNtoCFwcOcAPZ2YHMPxA5-Ya9mM70CZRRkCe9dK6hIDkTVmij9LJQko590rf1UwI45pI-Ed0s-VOaOlX1lltQ6_xp_1KyF5OurJk7BVwWYQxtYGxbJ492_c55rs_nvThMRtrsvLrREwl8RtUgfEynzyPYbDUjdFFrtmhqwY3PRYdCR3wWHvgMjay2UDOj5_6MZpPEp3yWnPVZelr7Sf-eUB3F2Seqjk8oBjg2KldKLKUyUey08qKqIft7vwCmdlksNAo4D-YYVmJCA6fzoNXaHC1rzbaMUKaHJx9B_IJjkhCtySunLwFadgm-ZIYJZms2u-K5zG1Gaqx70MmUN8oRuX22REP7h2D_MKOlvzkdRTfwJ6Kp4Z6c1Bil2T4UwX7cscnhFV-NJkD2dkWurDsA9y3Y6M2RmOZq7GMsl0UQzYg6QjjO2R3TznFltoScOmcHoRTK5nnvOOfwYCQ5ENZH-d7sU0z3MjrIDlLZGeL7nOxBmfh6xDH0ll0kmGYAWz0Pjsdn4tMvsUn6ic4mqPCU0nna9iudYZ7bw5LP0bgURdOQaBUjn75db_pJs6tqjKJkIGEj-spjsMPC4QMq7sYeEMweW3HgS8P748XAtp3shF2hb9rjVdwNmi3eqbUnl8R81dIXG0KcHNRe4azkGqVLnP7vsvxshb0h5-9nMDI0OpfwceovQV1YvYSITvDgQyzoGsfb6XQln13r8xx_JOYDW47Qybvsz5Vh80ro48r3a_zE-n8zz9-o1pe1h52sfe52Mz85xxsbe-HGWnO4tc3HjraG6IBTY5h3FHSejeuQaiE-dsqzVfJZriUzvx8cHk4V4f5NyWtLfGDJPOLv0Ozfmnw7-u6c8obYh8dinyZvjX40jv5B8Dscb_gPq_w3Hfa6oUdqmd2Jd1q_eYrq8axPHMJP3n392DIJdxdgqjZ2n1G14RX_xYZbp_mFV02aBoS3py55D6-_LLpv5EjNcAGm6uG269v9l6vHL7Bp84obSGDellCzWmln7daYurGexHcA35XcbNt8WagK4DshnvZfi1qrP1lhAL7jTdOyBuA7SCSFXBaipcxd_hWaNFuYk-IvaxhbduofDSn-grSt6j5eaNndSX7TqtSkgkSXrd16rR3DPNm7ZxrscL-3UnJZ7u7UMZ44OrwB4ReAMVQSVoq2glmR4YYQ4z6ThgiiF4QQSjdFUUQbRnGUQOeW8AqEV81r0z1801waN9EfduYArwYhTZ7XqjGakQpgt3y5NO7iGa8AvmsbbX3M872ngwzgu5xLgO-Wy6GL5_f3Px-WjVoG2RIBfI1eGEmxLduyweBgZjBhGPkM_t7KR15KIv5NJBVMN_tr-o_bFDFbRIxswnMnZij_lMlntuQaKQrHisICp7Gtf5yiDudllayTaCG4bF8WpWy7jsLiJg40wvHM-GiMmcRZFoerkUPvlaq_yo3qfjFNmmnwbT_AV5_iWhzFYRyuJubFE_MCWkSYfIImlCURJhNNyVxTiNjnaAoRm2hKZ5ryPE0_RVOc26Q_0rSaa1oV8-B-6bKG0t9c5nULupWTGD-4JLJb20PzlSTiteHNA5GkZBqENwdDbB5KPocbKItXxZQb2Xh2K5yvgoR-XFMUpDhIaK_JJp1JmoyDFOdZNvKEdd0JL_wDr9m__9dQBAgXeZZNHLRPy3ESRUEWByuUBSP7dCutj77xmgkupxnk0Wguy-9sM53SkZn-ILpk5oEUW4dz5eu957km-tWmra9VLQ6llBK_t6ZuzR0XHpAPdR-ZzpU9y9rWcWicT0RbcunCc0S-MbRr27SyMFxJEN48Ke6oPsW6brmgTHeB3tFogqpqszZKie5XN4vfuKSnpH4yzTec6b1cbnve_f0W3qnadGs9Q1kwoRee0gvRMMe2jnogXL4DOGBhjifAsx0V2b37fTsqzmiGJpjRHJNFCK7Xdti6MUSbdTWY_WYtLJpqiWcuSdMshh3-ezyySrO4x_W8uuFedtDMlbdslBR9R4X_KMMLWykTA_kGfoWaVeqJDecC99rE_gfs36qAXA4vceAbVyBTTiXAqelq7l2l_ZMITt3_s3P5lzXNHTss6gDmmH8F52W_orkSZql0CfDdL4DvNoRu_vz2rz_iE9CqNf8Q_Y_0t7_j-OGPPy_oZUizMCMX7DJIwyCIswhlF9vLgiWbmIYsDIowDdIEFzmLNhuabfIipTS_4JcY4SgIUBaEYRJly4LlWZSuspjGSZ4WDESIVYSLpQ2u1X3hTi6XQRAnCF-4017j3tvBWLJn6Hpt9R_fXuhLx4i8LRsQIcEb0wwwhhvB9q_zOP8zOnqHZ3zYuGi1uPznJ6ydqU-X-L8BAAD___hKbXE">