Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[LV] Set SCEVCheckCond to nullptr whenever it was used.
Under some circumstances, SCEVExpander will insert new instructions when expanding a predicate, but the final result of the expansion can be a false constant. In those cases, the expanded instructions may later be used by other expansions, e.g. the trip count. This may trigger an assertion during SCEVExpander cleanup. To avoid this, always mark the result as used. Fixes #55100.
- Loading branch information
Showing
2 changed files
with
103 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
llvm/test/Transforms/LoopVectorize/pr55100-expand-scev-predicate-used.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | ||
; RUN: opt -passes='loop-vectorize' -force-vector-width=2 -force-vector-interleave=1 -S %s | FileCheck %s | ||
|
||
define void @test_pr55100(i32 %N) { | ||
; CHECK-LABEL: @test_pr55100( | ||
; CHECK-NEXT: entry: | ||
; CHECK-NEXT: [[TMP0:%.*]] = sub i32 0, [[N:%.*]] | ||
; CHECK-NEXT: br label [[LOOP_1_HEADER:%.*]] | ||
; CHECK: loop.1.header: | ||
; CHECK-NEXT: [[IV_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP_1_LATCH:%.*]] ] | ||
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i32 [[IV_1]], -1 | ||
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP0]], [[TMP1]] | ||
; CHECK-NEXT: [[UMIN2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP2]], i32 18) | ||
; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i32 [[UMIN2]], 1 | ||
; CHECK-NEXT: [[TMP4:%.*]] = mul nuw nsw i32 [[IV_1]], -1 | ||
; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP0]], [[TMP4]] | ||
; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP5]], i32 18) | ||
; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[IV_1]], 10 | ||
; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2_HEADER_PREHEADER:%.*]], label [[EXIT_LOOPEXIT1:%.*]] | ||
; CHECK: loop.2.header.preheader: | ||
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP3]], 2 | ||
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] | ||
; CHECK: vector.ph: | ||
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP3]], 2 | ||
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[N_MOD_VF]], 0 | ||
; CHECK-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i32 2, i32 [[N_MOD_VF]] | ||
; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP3]], [[TMP7]] | ||
; CHECK-NEXT: [[IND_END:%.*]] = trunc i32 [[N_VEC]] to i16 | ||
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] | ||
; CHECK: vector.body: | ||
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] | ||
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = trunc i32 [[INDEX]] to i16 | ||
; CHECK-NEXT: [[TMP8:%.*]] = add i16 [[OFFSET_IDX]], 0 | ||
; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[N]], [[IV_1]] | ||
; CHECK-NEXT: [[TMP10:%.*]] = sext i16 [[TMP8]] to i32 | ||
; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP9]], [[TMP10]] | ||
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2 | ||
; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] | ||
; CHECK-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] | ||
; CHECK: middle.block: | ||
; CHECK-NEXT: br label [[SCALAR_PH]] | ||
; CHECK: scalar.ph: | ||
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i16 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[LOOP_2_HEADER_PREHEADER]] ] | ||
; CHECK-NEXT: br label [[LOOP_2_HEADER:%.*]] | ||
; CHECK: vector.scevcheck: | ||
; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[UMIN]] to i16 | ||
; CHECK-NEXT: unreachable | ||
; CHECK: loop.2.header: | ||
; CHECK-NEXT: [[IV_2:%.*]] = phi i16 [ [[IV_2_NEXT:%.*]], [[LOOP_2_LATCH:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] | ||
; CHECK-NEXT: [[C_3:%.*]] = icmp slt i16 [[IV_2]], 18 | ||
; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_2_LATCH]], label [[LOOP_1_LATCH]] | ||
; CHECK: loop.2.latch: | ||
; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[N]], [[IV_1]] | ||
; CHECK-NEXT: [[IV_2_EXT:%.*]] = sext i16 [[IV_2]] to i32 | ||
; CHECK-NEXT: [[ADD_2:%.*]] = add i32 [[ADD_1]], [[IV_2_EXT]] | ||
; CHECK-NEXT: [[C_4:%.*]] = icmp ult i32 [[ADD_2]], 1 | ||
; CHECK-NEXT: [[IV_2_NEXT]] = add i16 [[IV_2]], 1 | ||
; CHECK-NEXT: br i1 [[C_4]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_2_HEADER]], !llvm.loop [[LOOP2:![0-9]+]] | ||
; CHECK: loop.1.latch: | ||
; CHECK-NEXT: [[IV_1_NEXT]] = add i32 [[IV_1]], 1 | ||
; CHECK-NEXT: br label [[LOOP_1_HEADER]] | ||
; CHECK: exit.loopexit: | ||
; CHECK-NEXT: br label [[EXIT:%.*]] | ||
; CHECK: exit.loopexit1: | ||
; CHECK-NEXT: br label [[EXIT]] | ||
; CHECK: exit: | ||
; CHECK-NEXT: ret void | ||
; | ||
entry: | ||
br label %loop.1.header | ||
|
||
loop.1.header: | ||
%iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop.1.latch ] | ||
%c.2 = icmp ugt i32 %iv.1, 10 | ||
br i1 %c.2, label %loop.2.header, label %exit | ||
|
||
loop.2.header: | ||
%iv.2 = phi i16 [ 0, %loop.1.header ], [ %iv.2.next, %loop.2.latch ] | ||
%c.3 = icmp slt i16 %iv.2, 18 | ||
br i1 %c.3, label %loop.2.latch, label %loop.1.latch | ||
|
||
loop.2.latch: | ||
%add.1 = add i32 %N, %iv.1 | ||
%iv.2.ext = sext i16 %iv.2 to i32 | ||
%add.2 = add i32 %add.1, %iv.2.ext | ||
%c.4 = icmp ult i32 %add.2, 1 | ||
%iv.2.next = add i16 %iv.2, 1 | ||
br i1 %c.4, label %exit, label %loop.2.header | ||
|
||
loop.1.latch: | ||
%iv.1.next = add i32 %iv.1, 1 | ||
br label %loop.1.header | ||
|
||
exit: | ||
ret void | ||
} |