
When printing the result of SCEV's analysis, we can avoid printing the predicated backedge taken count and the predicates if the predicates are empty and no new information is provided. This helps to reduce the verbosity of the output.
215 lines
9.9 KiB
LLVM
215 lines
9.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
|
|
; RUN: opt "-passes=print<scalar-evolution>" -disable-output < %s 2>&1 | FileCheck %s
|
|
;
|
|
; This checks if the min and max expressions are properly recognized by
|
|
; ScalarEvolution even though they the ICmpInst and SelectInst have different
|
|
; types.
|
|
;
|
|
; #define max(a, b) (a > b ? a : b)
|
|
; #define min(a, b) (a < b ? a : b)
|
|
;
|
|
; void f(int *A, int N) {
|
|
; for (int i = 0; i < N; i++) {
|
|
; A[max(0, i - 3)] = Aptr 2;
|
|
; }
|
|
; }
|
|
;
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
define void @f(ptr %A, i32 %N) {
|
|
; CHECK-LABEL: 'f'
|
|
; CHECK-NEXT: Classifying expressions for: @f
|
|
; CHECK-NEXT: %i.0 = phi i32 [ 0, %bb ], [ %tmp23, %bb2 ]
|
|
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%bb1> U: [0,-2147483648) S: [0,-2147483648) Exits: (0 smax %N) LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %i.0.1 = sext i32 %i.0 to i64
|
|
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%bb1> U: [0,2147483648) S: [0,2147483648) Exits: (zext i32 (0 smax %N) to i64) LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %tmp3 = add nuw nsw i32 %i.0, 3
|
|
; CHECK-NEXT: --> {3,+,1}<nuw><%bb1> U: [3,-2147483645) S: [3,-2147483645) Exits: (3 + (0 smax %N))<nuw> LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %tmp5 = sext i32 %tmp3 to i64
|
|
; CHECK-NEXT: --> (sext i32 {3,+,1}<nuw><%bb1> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: (sext i32 (3 + (0 smax %N))<nuw> to i64) LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %tmp6 = sext i32 %N to i64
|
|
; CHECK-NEXT: --> (sext i32 %N to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: (sext i32 %N to i64) LoopDispositions: { %bb1: Invariant }
|
|
; CHECK-NEXT: %tmp9 = select i1 %tmp4, i64 %tmp5, i64 %tmp6
|
|
; CHECK-NEXT: --> ((sext i32 {3,+,1}<nuw><%bb1> to i64) smin (sext i32 %N to i64)) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: ((sext i32 (3 + (0 smax %N))<nuw> to i64) smin (sext i32 %N to i64)) LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %tmp11 = getelementptr inbounds i32, ptr %A, i64 %tmp9
|
|
; CHECK-NEXT: --> ((4 * ((sext i32 {3,+,1}<nuw><%bb1> to i64) smin (sext i32 %N to i64)))<nsw> + %A) U: full-set S: full-set Exits: ((4 * ((sext i32 (3 + (0 smax %N))<nuw> to i64) smin (sext i32 %N to i64)))<nsw> + %A) LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %tmp12 = load i32, ptr %tmp11, align 4
|
|
; CHECK-NEXT: --> %tmp12 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb1: Variant }
|
|
; CHECK-NEXT: %tmp13 = shl nsw i32 %tmp12, 1
|
|
; CHECK-NEXT: --> (2 * %tmp12) U: [0,-1) S: [-2147483648,2147483647) Exits: <<Unknown>> LoopDispositions: { %bb1: Variant }
|
|
; CHECK-NEXT: %tmp17 = add nsw i64 %i.0.1, -3
|
|
; CHECK-NEXT: --> {-3,+,1}<nsw><%bb1> U: [-3,2147483645) S: [-3,2147483645) Exits: (-3 + (zext i32 (0 smax %N) to i64))<nsw> LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %tmp19 = select i1 %tmp14, i64 0, i64 %tmp17
|
|
; CHECK-NEXT: --> (-3 + (3 smax {0,+,1}<nuw><nsw><%bb1>))<nsw> U: [0,2147483645) S: [0,2147483645) Exits: (-3 + (3 smax (zext i32 (0 smax %N) to i64)))<nsw> LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %tmp21 = getelementptr inbounds i32, ptr %A, i64 %tmp19
|
|
; CHECK-NEXT: --> (-12 + (4 * (3 smax {0,+,1}<nuw><nsw><%bb1>))<nuw><nsw> + %A) U: full-set S: full-set Exits: (-12 + (4 * (3 smax (zext i32 (0 smax %N) to i64)))<nuw><nsw> + %A) LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: %tmp23 = add nuw nsw i32 %i.0, 1
|
|
; CHECK-NEXT: --> {1,+,1}<nuw><%bb1> U: [1,-2147483647) S: [1,-2147483647) Exits: (1 + (0 smax %N))<nuw> LoopDispositions: { %bb1: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @f
|
|
; CHECK-NEXT: Loop %bb1: backedge-taken count is (0 smax %N)
|
|
; CHECK-NEXT: Loop %bb1: constant max backedge-taken count is i32 2147483647
|
|
; CHECK-NEXT: Loop %bb1: symbolic max backedge-taken count is (0 smax %N)
|
|
; CHECK-NEXT: Loop %bb1: Trip multiple is 1
|
|
;
|
|
bb:
|
|
br label %bb1
|
|
|
|
bb1: ; preds = %bb2, %bb
|
|
%i.0 = phi i32 [ 0, %bb ], [ %tmp23, %bb2 ]
|
|
%i.0.1 = sext i32 %i.0 to i64
|
|
%tmp = icmp slt i32 %i.0, %N
|
|
br i1 %tmp, label %bb2, label %bb24
|
|
|
|
bb2: ; preds = %bb1
|
|
%tmp3 = add nuw nsw i32 %i.0, 3
|
|
%tmp4 = icmp slt i32 %tmp3, %N
|
|
%tmp5 = sext i32 %tmp3 to i64
|
|
%tmp6 = sext i32 %N to i64
|
|
%tmp9 = select i1 %tmp4, i64 %tmp5, i64 %tmp6
|
|
; min(N, i+3)
|
|
%tmp11 = getelementptr inbounds i32, ptr %A, i64 %tmp9
|
|
%tmp12 = load i32, ptr %tmp11, align 4
|
|
%tmp13 = shl nsw i32 %tmp12, 1
|
|
%tmp14 = icmp sge i32 3, %i.0
|
|
%tmp17 = add nsw i64 %i.0.1, -3
|
|
%tmp19 = select i1 %tmp14, i64 0, i64 %tmp17
|
|
; max(0, i - 3)
|
|
%tmp21 = getelementptr inbounds i32, ptr %A, i64 %tmp19
|
|
store i32 %tmp13, ptr %tmp21, align 4
|
|
%tmp23 = add nuw nsw i32 %i.0, 1
|
|
br label %bb1
|
|
|
|
bb24: ; preds = %bb1
|
|
ret void
|
|
}
|
|
|
|
define i8 @umax_basic_eq_off1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: 'umax_basic_eq_off1'
|
|
; CHECK-NEXT: Classifying expressions for: @umax_basic_eq_off1
|
|
; CHECK-NEXT: %lhs = add i8 %y, 1
|
|
; CHECK-NEXT: --> (1 + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %rhs = add i8 %x, %y
|
|
; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
; CHECK-NEXT: --> ((1 umax %x) + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: Determining loop execution counts for: @umax_basic_eq_off1
|
|
;
|
|
%x.is.zero = icmp eq i8 %x, 0
|
|
%lhs = add i8 %y, 1
|
|
%rhs = add i8 %x, %y
|
|
%r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
ret i8 %r
|
|
}
|
|
define i8 @umax_basic_ne_off1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: 'umax_basic_ne_off1'
|
|
; CHECK-NEXT: Classifying expressions for: @umax_basic_ne_off1
|
|
; CHECK-NEXT: %lhs = add i8 %y, 1
|
|
; CHECK-NEXT: --> (1 + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %rhs = add i8 %x, %y
|
|
; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %rhs, i8 %lhs
|
|
; CHECK-NEXT: --> ((1 umax %x) + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: Determining loop execution counts for: @umax_basic_ne_off1
|
|
;
|
|
%x.is.zero = icmp ne i8 %x, 0
|
|
%lhs = add i8 %y, 1
|
|
%rhs = add i8 %x, %y
|
|
%r = select i1 %x.is.zero, i8 %rhs, i8 %lhs
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_basic_eq_off0(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: 'umax_basic_eq_off0'
|
|
; CHECK-NEXT: Classifying expressions for: @umax_basic_eq_off0
|
|
; CHECK-NEXT: %lhs = add i8 %y, 0
|
|
; CHECK-NEXT: --> %y U: full-set S: full-set
|
|
; CHECK-NEXT: %rhs = add i8 %x, %y
|
|
; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: Determining loop execution counts for: @umax_basic_eq_off0
|
|
;
|
|
%x.is.zero = icmp eq i8 %x, 0
|
|
%lhs = add i8 %y, 0
|
|
%rhs = add i8 %x, %y
|
|
%r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_basic_eq_off2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: 'umax_basic_eq_off2'
|
|
; CHECK-NEXT: Classifying expressions for: @umax_basic_eq_off2
|
|
; CHECK-NEXT: %lhs = add i8 %y, 2
|
|
; CHECK-NEXT: --> (2 + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %rhs = add i8 %x, %y
|
|
; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
; CHECK-NEXT: --> %r U: full-set S: full-set
|
|
; CHECK-NEXT: Determining loop execution counts for: @umax_basic_eq_off2
|
|
;
|
|
%x.is.zero = icmp eq i8 %x, 0
|
|
%lhs = add i8 %y, 2
|
|
%rhs = add i8 %x, %y
|
|
%r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_basic_eq_var_off(i8 %x, i8 %y, i8 %c) {
|
|
; CHECK-LABEL: 'umax_basic_eq_var_off'
|
|
; CHECK-NEXT: Classifying expressions for: @umax_basic_eq_var_off
|
|
; CHECK-NEXT: %lhs = add i8 %y, %c
|
|
; CHECK-NEXT: --> (%y + %c) U: full-set S: full-set
|
|
; CHECK-NEXT: %rhs = add i8 %x, %y
|
|
; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
; CHECK-NEXT: --> %r U: full-set S: full-set
|
|
; CHECK-NEXT: Determining loop execution counts for: @umax_basic_eq_var_off
|
|
;
|
|
%x.is.zero = icmp eq i8 %x, 0
|
|
%lhs = add i8 %y, %c
|
|
%rhs = add i8 %x, %y
|
|
%r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_basic_eq_narrow(i4 %x.narrow, i8 %y) {
|
|
; CHECK-LABEL: 'umax_basic_eq_narrow'
|
|
; CHECK-NEXT: Classifying expressions for: @umax_basic_eq_narrow
|
|
; CHECK-NEXT: %x = zext i4 %x.narrow to i8
|
|
; CHECK-NEXT: --> (zext i4 %x.narrow to i8) U: [0,16) S: [0,16)
|
|
; CHECK-NEXT: %lhs = add i8 %y, 1
|
|
; CHECK-NEXT: --> (1 + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %rhs = add i8 %x, %y
|
|
; CHECK-NEXT: --> ((zext i4 %x.narrow to i8) + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
; CHECK-NEXT: --> ((1 umax (zext i4 %x.narrow to i8)) + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: Determining loop execution counts for: @umax_basic_eq_narrow
|
|
;
|
|
%x = zext i4 %x.narrow to i8
|
|
%x.is.zero = icmp eq i4 %x.narrow, 0
|
|
%lhs = add i8 %y, 1
|
|
%rhs = add i8 %x, %y
|
|
%r = select i1 %x.is.zero, i8 %lhs, i8 %rhs
|
|
ret i8 %r
|
|
}
|
|
define i8 @umax_basic_ne_narrow(i4 %x.narrow, i8 %y) {
|
|
; CHECK-LABEL: 'umax_basic_ne_narrow'
|
|
; CHECK-NEXT: Classifying expressions for: @umax_basic_ne_narrow
|
|
; CHECK-NEXT: %x = zext i4 %x.narrow to i8
|
|
; CHECK-NEXT: --> (zext i4 %x.narrow to i8) U: [0,16) S: [0,16)
|
|
; CHECK-NEXT: %lhs = add i8 %y, 1
|
|
; CHECK-NEXT: --> (1 + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %rhs = add i8 %x, %y
|
|
; CHECK-NEXT: --> ((zext i4 %x.narrow to i8) + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %rhs, i8 %lhs
|
|
; CHECK-NEXT: --> ((1 umax (zext i4 %x.narrow to i8)) + %y) U: full-set S: full-set
|
|
; CHECK-NEXT: Determining loop execution counts for: @umax_basic_ne_narrow
|
|
;
|
|
%x = zext i4 %x.narrow to i8
|
|
%x.is.zero = icmp ne i4 %x.narrow, 0
|
|
%lhs = add i8 %y, 1
|
|
%rhs = add i8 %x, %y
|
|
%r = select i1 %x.is.zero, i8 %rhs, i8 %lhs
|
|
ret i8 %r
|
|
}
|