mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-15 15:48:38 +00:00
[DSE] Fix bug in partial overwrite tracking
Summary: Found cases where DSE incorrectly add partially-overwritten intervals. Please see the test case for details. Reviewers: mcrosier, eeckstein, hfinkel Subscribers: mcrosier, llvm-commits Differential Revision: http://reviews.llvm.org/D21859 llvm-svn: 274237
This commit is contained in:
parent
437bb9ba7e
commit
78c02c3c2f
@ -385,18 +385,25 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later,
|
||||
// Find any intervals ending at, or after, LaterIntStart which start
|
||||
// before LaterIntEnd.
|
||||
auto ILI = IM.lower_bound(LaterIntStart);
|
||||
if (ILI != IM.end() && ILI->second < LaterIntEnd) {
|
||||
// This existing interval ends in the middle of
|
||||
// [LaterIntStart, LaterIntEnd), erase it adjusting our start.
|
||||
if (ILI != IM.end() && ILI->second <= LaterIntEnd) {
|
||||
// This existing interval is overlapped with the current store somewhere
|
||||
// in [LaterIntStart, LaterIntEnd]. Merge them by erasing the existing
|
||||
// intervals and adjusting our start and end.
|
||||
LaterIntStart = std::min(LaterIntStart, ILI->second);
|
||||
LaterIntEnd = std::max(LaterIntEnd, ILI->first);
|
||||
ILI = IM.erase(ILI);
|
||||
|
||||
while (ILI != IM.end() && ILI->first <= LaterIntEnd)
|
||||
ILI = IM.erase(ILI);
|
||||
|
||||
if (ILI != IM.end() && ILI->second < LaterIntEnd)
|
||||
// Continue erasing and adjusting our end in case other previous
|
||||
// intervals are also overlapped with the current store.
|
||||
//
|
||||
// |--- ealier 1 ---| |--- ealier 2 ---|
|
||||
// |------- later---------|
|
||||
//
|
||||
while (ILI != IM.end() && ILI->second <= LaterIntEnd) {
|
||||
assert(ILI->second > LaterIntStart && "Unexpected interval");
|
||||
LaterIntEnd = std::max(LaterIntEnd, ILI->first);
|
||||
ILI = IM.erase(ILI);
|
||||
}
|
||||
}
|
||||
|
||||
IM[LaterIntEnd] = LaterIntStart;
|
||||
|
@ -198,3 +198,42 @@ entry:
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
define signext i8 @test6(i32 *%ptr) {
|
||||
entry:
|
||||
; CHECK-LABEL: @test6
|
||||
|
||||
store i32 0, i32* %ptr
|
||||
|
||||
%bptr = bitcast i32* %ptr to i16*
|
||||
%bptr1 = getelementptr inbounds i16, i16* %bptr, i64 0
|
||||
%bptr2 = getelementptr inbounds i16, i16* %bptr, i64 1
|
||||
|
||||
store i16 1456, i16* %bptr2, align 1
|
||||
store i16 65535, i16* %bptr1, align 1
|
||||
|
||||
; CHECK-NOT: store i32 0, i32* %ptr
|
||||
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
define signext i8 @test7(i64 *%ptr) {
|
||||
entry:
|
||||
; CHECK-LABEL: @test7
|
||||
|
||||
store i64 0, i64* %ptr
|
||||
|
||||
%bptr = bitcast i64* %ptr to i16*
|
||||
%bptr1 = getelementptr inbounds i16, i16* %bptr, i64 0
|
||||
%bptr2 = getelementptr inbounds i16, i16* %bptr, i64 1
|
||||
%bptr3 = getelementptr inbounds i16, i16* %bptr, i64 2
|
||||
%bptr4 = getelementptr inbounds i16, i16* %bptr, i64 3
|
||||
|
||||
store i16 1346, i16* %bptr1, align 1
|
||||
store i16 1756, i16* %bptr3, align 1
|
||||
store i16 1456, i16* %bptr2, align 1
|
||||
store i16 5656, i16* %bptr4, align 1
|
||||
|
||||
; CHECK-NOT: store i64 0, i64* %ptr
|
||||
|
||||
ret i8 0
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user