Nikita Popov 32ec6d91a1
[SCEV] Make invalidation in SCEVCallbackVH more thorough (#68316)
When a SCEVCallbackVH is RAUWed, we currently do a def-use walk and
remove dependent instructions from the ValueExprMap. However, unlike
SCEVs usual invalidation, this does not forget memoized values.

The end result is that we might end up removing a SCEVUnknown from the
map, while that expression still has users. Due to that, we may later
fail to invalide those expressions. In particular, invalidation of loop
dispositions only does something if there is an expression for the
value, which would not be the case here.

Fix this by using the standard forgetValue() API, instead of rolling a
custom variant.

Fixes https://github.com/llvm/llvm-project/issues/68285.
2023-10-10 10:55:57 +02:00

90 lines
3.9 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
; RUN: opt -S -passes="loop-mssa(simple-loop-unswitch<nontrivial>),loop(loop-unroll-full),loop-simplify,verify<scalar-evolution>" < %s | FileCheck %s
; Should not caused a SCEV verification failure due to incorrect
; loop dispositions.
define void @g(ptr %b, i32 %arg, i1 %tobool.not) {
; CHECK-LABEL: define void @g(
; CHECK-SAME: ptr [[B:%.*]], i32 [[ARG:%.*]], i1 [[TOBOOL_NOT:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
; CHECK: entry.split.us:
; CHECK-NEXT: br label [[FOR_BODY_US:%.*]]
; CHECK: for.body.us:
; CHECK-NEXT: br label [[LAND_END_US:%.*]]
; CHECK: land.end.us:
; CHECK-NEXT: store i16 0, ptr [[B]], align 1
; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: entry.split:
; CHECK-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]]
; CHECK: for.body.peel.begin:
; CHECK-NEXT: br label [[FOR_BODY_PEEL:%.*]]
; CHECK: for.body.peel:
; CHECK-NEXT: br label [[LAND_RHS_PEEL:%.*]]
; CHECK: land.rhs.peel:
; CHECK-NEXT: [[AND_PEEL:%.*]] = and i32 -1, [[ARG]]
; CHECK-NEXT: [[TOBOOL2_PEEL:%.*]] = icmp ne i32 [[AND_PEEL]], 0
; CHECK-NEXT: [[DOTPRE_PEEL:%.*]] = load i32, ptr [[B]], align 1
; CHECK-NEXT: br label [[LAND_END_PEEL:%.*]]
; CHECK: land.end.peel:
; CHECK-NEXT: [[IV2_PEEL:%.*]] = phi i32 [ [[DOTPRE_PEEL]], [[LAND_RHS_PEEL]] ]
; CHECK-NEXT: [[IV3_PEEL:%.*]] = phi i1 [ [[TOBOOL2_PEEL]], [[LAND_RHS_PEEL]] ]
; CHECK-NEXT: [[LAND_EXT_PEEL:%.*]] = zext i1 [[IV3_PEEL]] to i16
; CHECK-NEXT: [[CMP3_PEEL:%.*]] = icmp ne i16 0, [[LAND_EXT_PEEL]]
; CHECK-NEXT: [[CONV4_PEEL:%.*]] = zext i1 [[CMP3_PEEL]] to i16
; CHECK-NEXT: store i16 [[LAND_EXT_PEEL]], ptr [[B]], align 1
; CHECK-NEXT: [[CMP_PEEL:%.*]] = icmp slt i32 [[IV2_PEEL]], 0
; CHECK-NEXT: br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END_SPLIT:%.*]]
; CHECK: for.body.peel.next:
; CHECK-NEXT: br label [[FOR_BODY_PEEL_NEXT1:%.*]]
; CHECK: for.body.peel.next1:
; CHECK-NEXT: br label [[ENTRY_SPLIT_PEEL_NEWPH:%.*]]
; CHECK: entry.split.peel.newph:
; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[ARG]], 0
; CHECK-NEXT: [[LAND_EXT:%.*]] = zext i1 [[TOBOOL2]] to i16
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: br label [[LAND_RHS:%.*]]
; CHECK: land.rhs:
; CHECK-NEXT: [[DOTPRE:%.*]] = load i32, ptr [[B]], align 1
; CHECK-NEXT: br label [[LAND_END:%.*]]
; CHECK: land.end:
; CHECK-NEXT: store i16 [[LAND_EXT]], ptr [[B]], align 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DOTPRE]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_SPLIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: for.end.split.loopexit:
; CHECK-NEXT: br label [[FOR_END_SPLIT]]
; CHECK: for.end.split:
; CHECK-NEXT: br label [[FOR_END]]
; CHECK: for.end:
; CHECK-NEXT: ret void
;
entry:
br label %for.body
for.body: ; preds = %land.end, %entry
%iv1 = phi i16 [ 0, %entry ], [ %trunc, %land.end ]
br i1 %tobool.not, label %land.end, label %land.rhs
land.rhs: ; preds = %for.body
%and = and i32 -1, %arg
%tobool2 = icmp ne i32 %and, 0
%.pre = load i32, ptr %b, align 1
br label %land.end
land.end: ; preds = %land.rhs, %for.body
%iv2 = phi i32 [ 0, %for.body ], [ %.pre, %land.rhs ]
%iv3 = phi i1 [ false, %for.body ], [ %tobool2, %land.rhs ]
%land.ext = zext i1 %iv3 to i16
%cmp3 = icmp ne i16 %iv1, %land.ext
%conv4 = zext i1 %cmp3 to i16
store i16 %land.ext, ptr %b, align 1
%cmp = icmp slt i32 %iv2, 0
%trunc = trunc i32 %arg to i16
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %land.end
ret void
}