mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
ccddc942de
The patch rL298481 was reverted due to crash on clang-with-lto-ubuntu build. The reason of the crash was type mismatch between either a or b and RHS in the following situation: LHS = sext(a +nsw b) > RHS. This is quite rare, but still possible situation. Normally we need to cast all {a, b, RHS} to their widest type. But we try to avoid creation of new SCEV that are not constants to avoid initiating recursive analysis that can take a lot of time and/or cache a bad value for iterations number. To deal with this, in this patch we reject this case and will not try to analyze it if the type of sum doesn't match with the type of RHS. In this situation we don't need to create any non-constant SCEVs. This patch also adds an assertion to the method IsProvedViaContext so that we could fail on it and not go further into range analysis etc (because in some situations these analyzes succeed even when the passed arguments have wrong types, what should not normally happen). The patch also contains a fix for a problem with too narrow scope of the analysis caused by wrong usage of predicates in recursive invocations. The regression test on the said failure: test/Analysis/ScalarEvolution/implied-via-addition.ll Reviewers: reames, apilipenko, anna, sanjoy Reviewed By: sanjoy Subscribers: mzolotukhin, mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D31238 llvm-svn: 299205
332 lines
10 KiB
LLVM
332 lines
10 KiB
LLVM
; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
|
|
|
|
declare void @llvm.experimental.guard(i1, ...)
|
|
|
|
define void @test_1(i32 %n) nounwind {
|
|
; Prove that (n > 1) ===> (n / 2 > 0).
|
|
; CHECK: Determining loop execution counts for: @test_1
|
|
; CHECK: Loop %header: backedge-taken count is (-1 + %n.div.2)<nsw>
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %n, 1
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i32 %indvar, 1
|
|
%exitcond = icmp sgt i32 %n.div.2, %indvar.next
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_1neg(i32 %n) nounwind {
|
|
; Prove that (n > 0) =\=> (n / 2 > 0).
|
|
; CHECK: Determining loop execution counts for: @test_1neg
|
|
; CHECK: Loop %header: backedge-taken count is (-1 + (1 smax %n.div.2))<nsw>
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %n, 0
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i32 %indvar, 1
|
|
%exitcond = icmp sgt i32 %n.div.2, %indvar.next
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_2(i32 %n) nounwind {
|
|
; Prove that (n >= 2) ===> (n / 2 > 0).
|
|
; CHECK: Determining loop execution counts for: @test_2
|
|
; CHECK: Loop %header: backedge-taken count is (-1 + %n.div.2)<nsw>
|
|
entry:
|
|
%cmp1 = icmp sge i32 %n, 2
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i32 %indvar, 1
|
|
%exitcond = icmp sgt i32 %n.div.2, %indvar.next
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_2neg(i32 %n) nounwind {
|
|
; Prove that (n >= 1) =\=> (n / 2 > 0).
|
|
; CHECK: Determining loop execution counts for: @test_2neg
|
|
; CHECK: Loop %header: backedge-taken count is (-1 + (1 smax %n.div.2))<nsw>
|
|
entry:
|
|
%cmp1 = icmp sge i32 %n, 1
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i32 %indvar, 1
|
|
%exitcond = icmp sgt i32 %n.div.2, %indvar.next
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_3(i32 %n) nounwind {
|
|
; Prove that (n > -2) ===> (n / 2 >= 0).
|
|
; CHECK: Determining loop execution counts for: @test_3
|
|
; CHECK: Loop %header: backedge-taken count is (1 + %n.div.2)<nsw>
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %n, -2
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i32 %indvar, 1
|
|
%exitcond = icmp sge i32 %n.div.2, %indvar
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_3neg(i32 %n) nounwind {
|
|
; Prove that (n > -3) =\=> (n / 2 >= 0).
|
|
; CHECK: Determining loop execution counts for: @test_3neg
|
|
; CHECK: Loop %header: backedge-taken count is (0 smax (1 + %n.div.2)<nsw>)
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %n, -3
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i32 %indvar, 1
|
|
%exitcond = icmp sge i32 %n.div.2, %indvar
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_4(i32 %n) nounwind {
|
|
; Prove that (n >= -1) ===> (n / 2 >= 0).
|
|
; CHECK: Determining loop execution counts for: @test_4
|
|
; CHECK: Loop %header: backedge-taken count is (1 + %n.div.2)<nsw>
|
|
entry:
|
|
%cmp1 = icmp sge i32 %n, -1
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i32 %indvar, 1
|
|
%exitcond = icmp sge i32 %n.div.2, %indvar
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_4neg(i32 %n) nounwind {
|
|
; Prove that (n >= -2) =\=> (n / 2 >= 0).
|
|
; CHECK: Determining loop execution counts for: @test_4neg
|
|
; CHECK: Loop %header: backedge-taken count is (0 smax (1 + %n.div.2)<nsw>)
|
|
entry:
|
|
%cmp1 = icmp sge i32 %n, -2
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i32 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i32 %indvar, 1
|
|
%exitcond = icmp sge i32 %n.div.2, %indvar
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_ext_01(i32 %n) nounwind {
|
|
; Prove that (n > 1) ===> (n / 2 > 0).
|
|
; CHECK: Determining loop execution counts for: @test_ext_01
|
|
; CHECK: Loop %header: backedge-taken count is (-1 + (sext i32 %n.div.2 to i64))<nsw>
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %n, 1
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
%n.div.2.ext = sext i32 %n.div.2 to i64
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i64 %indvar, 1
|
|
%exitcond = icmp sgt i64 %n.div.2.ext, %indvar.next
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_ext_01neg(i32 %n) nounwind {
|
|
; Prove that (n > 0) =\=> (n / 2 > 0).
|
|
; CHECK: Determining loop execution counts for: @test_ext_01neg
|
|
; CHECK: Loop %header: backedge-taken count is (-1 + (1 smax (sext i32 %n.div.2 to i64)))<nsw>
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %n, 0
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
%n.div.2.ext = sext i32 %n.div.2 to i64
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i64 %indvar, 1
|
|
%exitcond = icmp sgt i64 %n.div.2.ext, %indvar.next
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_ext_02(i32 %n) nounwind {
|
|
; Prove that (n >= 2) ===> (n / 2 > 0).
|
|
; CHECK: Determining loop execution counts for: @test_ext_02
|
|
; CHECK: Loop %header: backedge-taken count is (-1 + (sext i32 %n.div.2 to i64))<nsw>
|
|
entry:
|
|
%cmp1 = icmp sge i32 %n, 2
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
%n.div.2.ext = sext i32 %n.div.2 to i64
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i64 %indvar, 1
|
|
%exitcond = icmp sgt i64 %n.div.2.ext, %indvar.next
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_ext_02neg(i32 %n) nounwind {
|
|
; Prove that (n >= 1) =\=> (n / 2 > 0).
|
|
; CHECK: Determining loop execution counts for: @test_ext_02neg
|
|
; CHECK: Loop %header: backedge-taken count is (-1 + (1 smax (sext i32 %n.div.2 to i64)))<nsw>
|
|
entry:
|
|
%cmp1 = icmp sge i32 %n, 1
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
%n.div.2.ext = sext i32 %n.div.2 to i64
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i64 %indvar, 1
|
|
%exitcond = icmp sgt i64 %n.div.2.ext, %indvar.next
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_ext_03(i32 %n) nounwind {
|
|
; Prove that (n > -2) ===> (n / 2 >= 0).
|
|
; CHECK: Determining loop execution counts for: @test_ext_03
|
|
; CHECK: Loop %header: backedge-taken count is (1 + (sext i32 %n.div.2 to i64))<nsw>
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %n, -2
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
%n.div.2.ext = sext i32 %n.div.2 to i64
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i64 %indvar, 1
|
|
%exitcond = icmp sge i64 %n.div.2.ext, %indvar
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_ext_03neg(i32 %n) nounwind {
|
|
; Prove that (n > -3) =\=> (n / 2 >= 0).
|
|
; CHECK: Determining loop execution counts for: @test_ext_03neg
|
|
; CHECK: Loop %header: backedge-taken count is (0 smax (1 + (sext i32 %n.div.2 to i64))<nsw>)
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %n, -3
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
%n.div.2.ext = sext i32 %n.div.2 to i64
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i64 %indvar, 1
|
|
%exitcond = icmp sge i64 %n.div.2.ext, %indvar
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_ext_04(i32 %n) nounwind {
|
|
; Prove that (n >= -1) ===> (n / 2 >= 0).
|
|
; CHECK: Determining loop execution counts for: @test_ext_04
|
|
; CHECK: Loop %header: backedge-taken count is (1 + (sext i32 %n.div.2 to i64))<nsw>
|
|
entry:
|
|
%cmp1 = icmp sge i32 %n, -1
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
%n.div.2.ext = sext i32 %n.div.2 to i64
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i64 %indvar, 1
|
|
%exitcond = icmp sge i64 %n.div.2.ext, %indvar
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test_ext_04neg(i32 %n) nounwind {
|
|
; Prove that (n >= -2) =\=> (n / 2 >= 0).
|
|
; CHECK: Determining loop execution counts for: @test_ext_04neg
|
|
; CHECK: Loop %header: backedge-taken count is (0 smax (1 + (sext i32 %n.div.2 to i64))<nsw>)
|
|
entry:
|
|
%cmp1 = icmp sge i32 %n, -2
|
|
%n.div.2 = sdiv i32 %n, 2
|
|
%n.div.2.ext = sext i32 %n.div.2 to i64
|
|
call void(i1, ...) @llvm.experimental.guard(i1 %cmp1) [ "deopt"() ]
|
|
br label %header
|
|
|
|
header:
|
|
%indvar = phi i64 [ %indvar.next, %header ], [ 0, %entry ]
|
|
%indvar.next = add i64 %indvar, 1
|
|
%exitcond = icmp sge i64 %n.div.2.ext, %indvar
|
|
br i1 %exitcond, label %header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|