Skip to content

Commit b240b93

Browse files
mshelegopszymich
authored andcommitted
Fix for copy elimination undo
During a copy elimination attempt LRs are coalesced, which causes the deletion of a smaller LR. When an attempt is not successful the deleted LR is not restored leading to a crash. (cherry picked from commit 39b96a3)
1 parent 18ae7d4 commit b240b93

File tree

2 files changed

+70
-27
lines changed

2 files changed

+70
-27
lines changed

IGC/VectorCompiler/lib/GenXCodeGen/GenXCoalescing.cpp

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ namespace {
401401
void applyCopiesOptimized();
402402
void applyCopiesForValue(const std::set<CopyData> &CDSet);
403403
template <typename Iter>
404-
Iter mergeCopiesTillFailed(SimpleValue CopySV, Iter BeginIt, Iter EndIt);
404+
LiveRange* mergeCopiesTillFailed(SimpleValue CopySV, Iter &It, Iter EndIt);
405405
// Helpers
406406
DominatorTree *getDomTree(Function *F) const {
407407
return DTWrapper->getDomTree(F);
@@ -1930,15 +1930,14 @@ void GenXCoalescing::applyCopiesForValue(const std::set<CopyData> &CDSet) {
19301930
// is used to detect possible interference.
19311931
auto CopySV = SimpleValue(CurrCopy, Idx);
19321932
Liveness->removeValueNoDelete(CopySV);
1933-
auto *CopyLR = Liveness->buildLiveRange(CopySV);
19341933
auto *DestLR = Liveness->getLiveRange(DestSV);
19351934

19361935
LLVM_DEBUG(dbgs() << "Created copy for LR: "; DestLR->print(dbgs());
19371936
dbgs() << "\nValue that was copied: "; SourceSV.print(dbgs());
19381937
dbgs() << "\nCopy inst: "; CopySV.print(dbgs()); dbgs() << "\n");
19391938

19401939
// Try to apply this copy in other copy candidates.
1941-
It = mergeCopiesTillFailed(CopySV, ++It, EndIt);
1940+
auto *CopyLR = mergeCopiesTillFailed(CopySV, ++It, EndIt);
19421941

19431942
LLVM_DEBUG(dbgs() << "Finished processing all candidates for that copy\n";
19441943
dbgs() << "Final copy val LR: "; CopyLR->print(dbgs());
@@ -1962,26 +1961,26 @@ void GenXCoalescing::applyCopiesForValue(const std::set<CopyData> &CDSet) {
19621961
* For more details, check applyCopiesOptimized description.
19631962
*/
19641963
template <typename Iter>
1965-
Iter GenXCoalescing::mergeCopiesTillFailed(SimpleValue CopySV, Iter BeginIt,
1966-
Iter EndIt) {
1967-
if (BeginIt == EndIt)
1968-
return EndIt;
1969-
1964+
LiveRange *GenXCoalescing::mergeCopiesTillFailed(SimpleValue CopySV, Iter &It,
1965+
Iter EndIt) {
19701966
auto *CopyLR = Liveness->buildLiveRange(CopySV);
1971-
auto *DestLR = Liveness->getLiveRange(BeginIt->Dest);
1967+
if (It == EndIt)
1968+
return CopyLR;
1969+
1970+
auto *DestLR = Liveness->getLiveRange(It->Dest);
19721971
Instruction *CurrCopy = cast<Instruction>(CopySV.getValue());
19731972

1974-
for (auto It = BeginIt; It != EndIt; ++It) {
1973+
while (It != EndIt) {
19751974
// Interference detection
19761975
if (Liveness->interfere(DestLR, CopyLR)) {
19771976
LLVM_DEBUG(dbgs() << "Interference detected\n");
1978-
return It;
1977+
return CopyLR;
19791978
}
19801979
// Dominance detection
19811980
if (!getDomTree(CurrCopy->getFunction())
19821981
->dominates(CurrCopy, cast<Instruction>(It->Dest.getValue()))) {
19831982
LLVM_DEBUG(dbgs() << "Copy doesn't dominate user\n");
1984-
return It;
1983+
return CopyLR;
19851984
}
19861985

19871986
// Copy may be redundant. Check interference after copy applied.
@@ -1992,8 +1991,9 @@ Iter GenXCoalescing::mergeCopiesTillFailed(SimpleValue CopySV, Iter BeginIt,
19921991
if (It->Source.getValue()->getType() == CurrCopy->getType()) {
19931992
*It->UseInDest = CurrCopy;
19941993
} else {
1995-
IGC_ASSERT_MESSAGE(It->Source.getIndex() == 0,
1996-
"Must be non-aggregated type: should come from bitcast");
1994+
IGC_ASSERT_MESSAGE(
1995+
It->Source.getIndex() == 0,
1996+
"Must be non-aggregated type: should come from bitcast");
19971997
IRBuilder<> Builder(CurrCopy->getNextNode());
19981998
BCI = cast<BitCastInst>(Builder.CreateBitCast(
19991999
CurrCopy, It->Source.getValue()->getType(), "red_copy_type_conv"));
@@ -2004,23 +2004,23 @@ Iter GenXCoalescing::mergeCopiesTillFailed(SimpleValue CopySV, Iter BeginIt,
20042004
}
20052005

20062006
Liveness->rebuildLiveRange(CopyLR);
2007-
if (!Liveness->twoAddrInterfere(DestLR, CopyLR)) {
2008-
LLVM_DEBUG(dbgs() << "Success. Moving to next candidate\n");
2009-
continue;
2007+
if (Liveness->twoAddrInterfere(DestLR, CopyLR)) {
2008+
// Undo copy elimination
2009+
LLVM_DEBUG(dbgs() << "Interference detected\n");
2010+
*It->UseInDest = OldValue;
2011+
if (BCI) {
2012+
Liveness->removeValue(BCI);
2013+
BCI->eraseFromParent();
2014+
}
2015+
Liveness->rebuildLiveRange(CopyLR);
2016+
return CopyLR;
20102017
}
20112018

2012-
// Undo copy elimination
2013-
LLVM_DEBUG(dbgs() << "Interference detected\n");
2014-
*It->UseInDest = OldValue;
2015-
if (BCI) {
2016-
Liveness->removeValue(BCI);
2017-
BCI->eraseFromParent();
2018-
}
2019-
Liveness->rebuildLiveRange(CopyLR);
2020-
return It;
2019+
LLVM_DEBUG(dbgs() << "Success. Moving to next candidate\n");
2020+
It++;
20212021
}
20222022

2023-
return EndIt;
2023+
return CopyLR;
20242024
}
20252025

20262026
/***********************************************************************
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2024 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; RUN: %opt %use_old_pass_manager% -GenXModule -GenXUnbalingWrapper -GenXNumberingWrapper \
10+
; RUN: -GenXLiveRangesWrapper -GenXCoalescingWrapper -march=genx64 \
11+
; RUN: -mcpu=XeHPC -mtriple=spir64-unknown-unknown -S < %s
12+
13+
; Check that undoing copy elimination doesn't cause a crash caused by LR deletion
14+
15+
define spir_kernel void @test() #0 {
16+
entry:
17+
%add.i = add nuw i64 0, 0
18+
%cmp6.not.i.i.not.not.iv32cast = bitcast i64 %add.i to <2 x i32>
19+
br label %for.body.i.lr.ph
20+
21+
for.body.i.lr.ph: ; preds = %entry
22+
br label %for.body.i
23+
24+
for.body.i: ; preds = %for.body.i.for.body.i_crit_edge, %for.body.i.lr.ph
25+
%Gen.sroa.0.0.i8 = phi i64 [ %add.i, %for.body.i.lr.ph ], [ %int_emu.select.recast, %for.body.i.for.body.i_crit_edge ]
26+
%bitcast = bitcast i64 %Gen.sroa.0.0.i8 to <1 x i64>
27+
%rdregioni = call <16 x i64> @llvm.genx.rdregioni.v16i64.v1i64.i16(<1 x i64> %bitcast, i32 0, i32 0, i32 0, i16 0, i32 0)
28+
%int_emu.select.partial_join = call <2 x i32> @llvm.genx.wrregioni.v2i32.v1i32.i16.i1(<2 x i32> %cmp6.not.i.i.not.not.iv32cast, <1 x i32> zeroinitializer, i32 0, i32 0, i32 0, i16 0, i32 0, i1 false)
29+
%int_emu.select.recast = bitcast <2 x i32> %int_emu.select.partial_join to i64
30+
br i1 false, label %for.body.i.for.body.i_crit_edge, label %for.body.i.exit_crit_edge
31+
32+
for.body.i.exit_crit_edge: ; preds = %for.body.i
33+
ret void
34+
35+
for.body.i.for.body.i_crit_edge: ; preds = %for.body.i
36+
br label %for.body.i
37+
}
38+
39+
declare <2 x i32> @llvm.genx.wrregioni.v2i32.v1i32.i16.i1(<2 x i32>, <1 x i32>, i32, i32, i32, i16, i32, i1)
40+
41+
declare <16 x i64> @llvm.genx.rdregioni.v16i64.v1i64.i16(<1 x i64>, i32, i32, i32, i16, i32)
42+
43+
attributes #0 = { "CMGenxMain" }

0 commit comments

Comments
 (0)