Skip to content

Commit 85c09c9

Browse files
committed
bench: add more issues
1 parent 9d6049b commit 85c09c9

File tree

5 files changed

+211
-1
lines changed

5 files changed

+211
-1
lines changed

dataset/127534.json

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"bug_id": "127534",
3+
"issue_url": "https://github.com/llvm/llvm-project/issues/127534",
4+
"bug_type": "crash",
5+
"base_commit": "6de5d1e46d1812de2bbbbe8d8d2c811e4d16acbe",
6+
"knowledge_cutoff": "2025-02-17T18:29:15Z",
7+
"lit_test_dir": [
8+
"llvm/test/Transforms/LoopSimplifyCFG"
9+
],
10+
"hints": {
11+
"fix_commit": "41437a6067b2f9dc8e7c458ff6417397796be31c",
12+
"components": [
13+
"LoopSimplifyCFG"
14+
],
15+
"bug_location_lineno": {
16+
"llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp": [
17+
[
18+
369,
19+
375
20+
]
21+
]
22+
},
23+
"bug_location_funcname": {
24+
"llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp": [
25+
"handleDeadExits"
26+
]
27+
}
28+
},
29+
"patch": "commit 41437a6067b2f9dc8e7c458ff6417397796be31c\nAuthor: Aleksandr Popov <42888396+aleks-tmb@users.noreply.github.com>\nDate: Fri Feb 21 12:26:39 2025 +0100\n\n [LoopSimplifyCFG] Fix SCEV invalidation after removing dead exit (#127536)\n \n Fixes #127534\n\ndiff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp\nindex 765b76e54068..4524446e5947 100644\n--- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp\n+++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp\n@@ -369,7 +369,7 @@ private:\n DeadInstructions.emplace_back(LandingPad);\n \n for (Instruction *I : DeadInstructions) {\n- SE.forgetBlockAndLoopDispositions(I);\n+ SE.forgetValue(I);\n I->replaceAllUsesWith(PoisonValue::get(I->getType()));\n I->eraseFromParent();\n }\n",
30+
"tests": [
31+
{
32+
"file": "llvm/test/Transforms/LoopSimplifyCFG/pr117537.ll",
33+
"commands": [
34+
"opt -S -passes='print<scalar-evolution>,loop-mssa(licm,loop-simplifycfg,loop-predication)' -verify-scev < %s"
35+
],
36+
"tests": [
37+
{
38+
"test_name": "<module>",
39+
"test_body": "\n; Make sure we don't assert due to insufficient SCEV invalidation.\n\ndefine i64 @\"main\"(ptr addrspace(1) %p, i1 %check) {\n;\nentry:\n br label %loop0.pre\n\nloop0.pre:\n br i1 %check, label %exit, label %loop0\n\nloop0:\n %length = load atomic i32, ptr addrspace(1) %p unordered, align 4\n %28 = icmp ugt i32 %length, 1\n br i1 %28, label %loop0.out, label %loop1.preheader\n\nloop0.out:\n %t = add i32 0, 1\n br i1 false, label %loop1.preheader, label %mid\n\nloop1.preheader:\n %length.lcssa = phi i32 [ %length, %loop0.out ], [ %length, %loop0 ]\n %local = phi i32 [ 0, %loop0 ], [ %t, %loop0.out ]\n br label %loop1\n\nloop1:\n %iv1 = phi i32 [ 4, %loop1.preheader ], [ %iv1.next, %loop1.guarded ]\n %82 = icmp ult i32 %iv1, %length.lcssa\n %wc = call i1 @llvm.experimental.widenable.condition()\n %guard.chk = and i1 %82, %wc\n br i1 %guard.chk, label %loop1.guarded, label %deopt-exit\n\nloop1.guarded:\n %iv1.next = add nuw nsw i32 %iv1, 1\n %chk = icmp ugt i32 %iv1, 310\n br i1 %chk, label %loop1.exit, label %loop1\n\ndeopt-exit:\n %100 = call i64 (...) @llvm.experimental.deoptimize.i64(i32 13) [ \"deopt\"() ]\n ret i64 %100\n\nloop1.exit:\n ret i64 0\n\nmid:\n br label %loop0.pre\n\nexit:\n ret i64 0\n}\n\ndeclare i64 @foo()\n\ndeclare i64 @llvm.experimental.deoptimize.i64(...)\n\n; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite)\ndeclare noundef i1 @llvm.experimental.widenable.condition()"
40+
}
41+
]
42+
}
43+
],
44+
"issue": {
45+
"title": "[SCEV] Assertion `isAvailableAtLoopEntry(RHS, L) && \"RHS is not available at Loop Entry\"' failed",
46+
"body": "During our local testing, we encountered the assertion failure `isAvailableAtLoopEntry(RHS, L) && \"RHS is not available at Loop Entry\".\n\nReduced reproducer:\n\n```llvm\ntarget datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2\"\ntarget triple = \"x86_64-unknown-linux-gnu\"\n\ndefine i64 @\"main\"(ptr addrspace(1) %p, i1 %check) {\nentry:\n br label %loop0.pre\n\nloop0.pre:\n br i1 %check, label %exit, label %loop0\n\nloop0:\n %length = load atomic i32, ptr addrspace(1) %p unordered, align 4\n %28 = icmp ugt i32 %length, 1\n br i1 %28, label %loop0.out, label %loop1.preheader\n\nloop0.out:\n %t = add i32 0, 1\n br i1 false, label %loop1.preheader, label %mid\n\nloop1.preheader:\n %length.lcssa = phi i32 [ %length, %loop0.out ], [ %length, %loop0 ]\n %local = phi i32 [ 0, %loop0 ], [ %t, %loop0.out ]\n br label %loop1\n\nloop1:\n %iv1 = phi i32 [ 4, %loop1.preheader ], [ %iv1.next, %loop1.guarded ]\n %82 = icmp ult i32 %iv1, %length.lcssa\n %wc = call i1 @llvm.experimental.widenable.condition()\n %guard.chk = and i1 %82, %wc\n br i1 %guard.chk, label %loop1.guarded, label %deopt-exit\n\nloop1.guarded:\n %iv1.next = add nuw nsw i32 %iv1, 1\n %chk = icmp ugt i32 %iv1, 310\n br i1 %chk, label %loop1.exit, label %loop1\n\ndeopt-exit:\n %100 = call i64 (...) @llvm.experimental.deoptimize.i64(i32 13) [ \"deopt\"() ]\n ret i64 %100\n\nloop1.exit:\n ret i64 0\n\nmid:\n br label %loop0.pre\n\nexit:\n ret i64 0\n}\n\ndeclare i64 @foo()\n\ndeclare i64 @llvm.experimental.deoptimize.i64(...)\n\n; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite)\ndeclare noundef i1 @llvm.experimental.widenable.condition()\n```\n\n\nSteps to reproduce:\n`$opt -passes='print<scalar-evolution>,loop-mssa(licm,loop-simplifycfg,loop-predication)'`\n\nProof: https://godbolt.org/z/8hsbahTjq\n\nLooks like `LoopSimplifyCFGPass` is guilty - it doesn\u2019t invalidate SCEV when removing a dead exit:\n\n```c++\n void handleDeadExits() {\n...\n for (Instruction *I : DeadInstructions) {\n SE.forgetBlockAndLoopDispositions(I);\n I->replaceAllUsesWith(PoisonValue::get(I->getType()));\n I->eraseFromParent();\n }\n```\n\n",
47+
"author": "aleks-tmb",
48+
"labels": [
49+
"crash",
50+
"llvm:transforms"
51+
],
52+
"comments": [
53+
{
54+
"author": "aleks-tmb",
55+
"body": "The `LoopSimplifyCFG` pass removes `%length.lcssa.ph`, but later, in the `LoopPredication` pass, we encounter an assertion failure for the `%length.lcssa` SCEV, which remains equal to `%length`\n\n<img width=\"935\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/4d630238-569e-4d2b-b760-b09d54b4450f\" />\n\n![Image](https://github.com/user-attachments/assets/49481d3d-102c-42e1-8836-5c970461993d)"
56+
},
57+
{
58+
"author": "aleks-tmb",
59+
"body": "It seems the reason why forgetBlockAndLoopDispositions doesn't cover this case is that `%length.lcssa.ph` doesn't have an existing SCEV, since the instruction was just added by the previous LICM pass."
60+
},
61+
{
62+
"author": "nikic",
63+
"body": "There is some pretty tricky interaction between LCSSA formation and SCEV invalidation, see:\nhttps://github.com/llvm/llvm-project/blob/7f69a399df384c86428d0c97e3afbc8146324226/llvm/lib/Transforms/Utils/LCSSA.cpp#L206-L211\n\nBasically, when forming LCSSA form, we take care not to break the invalidation chain, so that invalidation of the LCSSA phi node is sufficient.\n\nI think the LICM predecessor splitting effectively does manual LCSSA formation and doesn't maintain this special logic.\n\nI think the extra forgetValue() call works around this issue and variants of this might appear elsewhere. But TBH I'm not totally sure."
64+
}
65+
]
66+
},
67+
"verified": true
68+
}

0 commit comments

Comments
 (0)