
Set phi inputs to poison whenever we find a dead edge (either during initial worklist population or the main InstCombine run), instead of only doing this for successors of dead blocks. This means that the phi operand is set to poison even if for critical edges without an intermediate block. There are quite a few test changes, because the pattern is fairly common in vectorizer output, for cases where we know the vectorized loop will be entered.
92 lines
3.3 KiB
LLVM
92 lines
3.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
|
|
; RUN: opt -passes='loop-mssa(loop-rotate,licm),instcombine,indvars,loop-unroll' -S %s | FileCheck %s
|
|
;
|
|
; PR18361: ScalarEvolution::getAddRecExpr():
|
|
; Assertion `isLoopInvariant(Operands[i],...
|
|
;
|
|
; After a series of loop optimizations, SCEV's LoopDispositions grow stale.
|
|
; In particular, LoopSimplify hoists %cmp4, resulting in this SCEV for %add:
|
|
; {(zext i1 %cmp4 to i32),+,1}<nw><%for.cond1.preheader>
|
|
;
|
|
; When recomputing the SCEV for %ashr, we truncate the operands to get:
|
|
; (zext i1 %cmp4 to i16)
|
|
;
|
|
; This SCEV was never mapped to a value so never invalidated. It's
|
|
; loop disposition is still marked as non-loop-invariant, which is
|
|
; inconsistent with the AddRec.
|
|
|
|
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-apple-macosx"
|
|
|
|
@d = common global i32 0, align 4
|
|
@a = common global i32 0, align 4
|
|
@c = common global i32 0, align 4
|
|
@b = common global i32 0, align 4
|
|
|
|
; Check that the def-use chain that leads to the bad SCEV is still
|
|
; there.
|
|
define void @foo() {
|
|
; CHECK-LABEL: define void @foo() {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i32 0, ptr @d, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @c, align 4
|
|
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER:%.*]]
|
|
; CHECK: for.cond1.preheader:
|
|
; CHECK-NEXT: br label [[FOR_BODY3:%.*]]
|
|
; CHECK: for.body3:
|
|
; CHECK-NEXT: store i32 1, ptr @a, align 4
|
|
; CHECK-NEXT: store i32 1, ptr @d, align 4
|
|
; CHECK-NEXT: [[CMP4_LE_LE_INV:%.*]] = icmp sgt i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[CMP4_LE_LE_INV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: store i32 0, ptr @b, align 4
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.inc7, %entry
|
|
%storemerge = phi i32 [ 0, %entry ], [ %inc8, %for.inc7 ]
|
|
%f.0 = phi i32 [ undef, %entry ], [ %f.1, %for.inc7 ]
|
|
store i32 %storemerge, ptr @d, align 4
|
|
%cmp = icmp slt i32 %storemerge, 1
|
|
br i1 %cmp, label %for.cond1, label %for.end9
|
|
|
|
for.cond1: ; preds = %for.cond, %for.body3
|
|
%storemerge1 = phi i32 [ %inc, %for.body3 ], [ 0, %for.cond ]
|
|
%f.1 = phi i32 [ %xor, %for.body3 ], [ %f.0, %for.cond ]
|
|
store i32 %storemerge1, ptr @a, align 4
|
|
%cmp2 = icmp slt i32 %storemerge1, 1
|
|
br i1 %cmp2, label %for.body3, label %for.inc7
|
|
|
|
for.body3: ; preds = %for.cond1
|
|
%0 = load i32, ptr @c, align 4
|
|
%cmp4 = icmp sge i32 %storemerge1, %0
|
|
%conv = zext i1 %cmp4 to i32
|
|
%1 = load i32, ptr @d, align 4
|
|
%add = add nsw i32 %conv, %1
|
|
%sext = shl i32 %add, 16
|
|
%conv6 = ashr exact i32 %sext, 16
|
|
%xor = xor i32 %conv6, 1
|
|
%inc = add nsw i32 %storemerge1, 1
|
|
br label %for.cond1
|
|
|
|
for.inc7: ; preds = %for.cond1
|
|
%2 = load i32, ptr @d, align 4
|
|
%inc8 = add nsw i32 %2, 1
|
|
br label %for.cond
|
|
|
|
for.end9: ; preds = %for.cond
|
|
%cmp10 = icmp sgt i32 %f.0, 0
|
|
br i1 %cmp10, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %for.end9
|
|
store i32 0, ptr @b, align 4
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.then, %for.end9
|
|
ret void
|
|
}
|