Relative to the previous landing attempt, this introduces an additional flag on forgetMemoizedResults() to not remove SCEVUnknown phis from the value map. The invalidation after BECount calculation wants to leave these alone and skips them in its own use-def walk, but we can still end up invalidating them via forgetMemoizedResults() if there is another IR value with the same SCEV. This is intended as a temporary workaround only, and the need for this should go away once the getBackedgeTakenInfo() invalidation is refactored in the spirit of D114263. ----- This adds validation for consistency of ValueExprMap and ExprValueMap, and fixes identified issues: * Addrec construction directly wrote to ValueExprMap in a few places, without updating ExprValueMap. Add a helper to ensures they stay consistent. The adjustment in forgetSymbolicName() explicitly drops the old value from the map, so that we don't rely on it being overwritten. * forgetMemoizedResultsImpl() was dropping the SCEV from ExprValueMap, but not dropping the corresponding entries from ValueExprMap. Differential Revision: https://reviews.llvm.org/D113349
62 lines
2.3 KiB
LLVM
62 lines
2.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -loop-reduce < %s | FileCheck %s
|
|
|
|
; Test an assertion failure from D113349, where the SCEV for the outer phi
|
|
; gets computed and registered in the value map while attempting to compute it.
|
|
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
define void @test() {
|
|
; CHECK-LABEL: @test(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
|
|
; CHECK: loop.header:
|
|
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64* [ [[SCEVGEP:%.*]], [[LOOP_LATCH:%.*]] ], [ inttoptr (i64 -8 to i64*), [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: br i1 true, label [[LOOP_EXIT:%.*]], label [[LOOP2_PREHEADER:%.*]]
|
|
; CHECK: loop.exit:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: loop2.preheader:
|
|
; CHECK-NEXT: br label [[LOOP2_HEADER:%.*]]
|
|
; CHECK: loop2.header:
|
|
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi i64* [ [[SCEVGEP2:%.*]], [[LOOP2_HEADER]] ], [ [[LSR_IV]], [[LOOP2_PREHEADER]] ]
|
|
; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i64, i64* [[LSR_IV1]], i64 1
|
|
; CHECK-NEXT: [[SCEVGEP23:%.*]] = bitcast i64* [[SCEVGEP2]] to i8*
|
|
; CHECK-NEXT: br i1 false, label [[LOOP2_HEADER]], label [[LOOP2_CONT:%.*]]
|
|
; CHECK: loop2.cont:
|
|
; CHECK-NEXT: [[V:%.*]] = load i8, i8* [[SCEVGEP23]], align 1
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[V]], 0
|
|
; CHECK-NEXT: br i1 [[C]], label [[LOOP_EXIT]], label [[LOOP_LATCH]]
|
|
; CHECK: loop.latch:
|
|
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i64, i64* [[LSR_IV]], i64 1
|
|
; CHECK-NEXT: br label [[LOOP_HEADER]]
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%ptr = phi i64* [ %ptr.next, %loop.latch ], [ null, %entry ]
|
|
br i1 true, label %loop.exit, label %loop2.preheader
|
|
|
|
loop.exit:
|
|
ret void
|
|
|
|
loop2.preheader:
|
|
br label %loop2.header
|
|
|
|
loop2.header:
|
|
%ptr2 = phi i64* [ %ptr, %loop2.preheader ], [ %ptr2.next, %loop2.header ]
|
|
%ptr2.next = getelementptr inbounds i64, i64* %ptr2, i64 1
|
|
br i1 false, label %loop2.header, label %loop2.cont
|
|
|
|
loop2.cont:
|
|
%ptr2.i8 = bitcast i64* %ptr2 to i8*
|
|
%v = load i8, i8* %ptr2.i8
|
|
%c = icmp ne i8 %v, 0
|
|
br i1 %c, label %loop.exit, label %loop.latch
|
|
|
|
loop.latch:
|
|
%ptr.next = getelementptr inbounds i64, i64* %ptr, i64 1
|
|
br label %loop.header
|
|
}
|