Nikita Popov 3cd4571405 [SCEV] Make use of non-null pointers for range calculation
We know that certain pointers (e.g. non-extern-weak globals or
allocas in default address space) are not null, in which case the
lowest address they can be allocated at is their alignment.

This allows us to calculate better exit counts for loops that have
an additional null check in the guarding condition
(see alloca_icmp_null_exit_count).

Differential Revision: https://reviews.llvm.org/D153624
2023-06-29 09:09:17 +02:00

193 lines
9.5 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 2
; RUN: opt -passes='print<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s
@glob.i32.align2 = global i32 zeroinitializer, align 2
@glob.i32.align8 = global i32 zeroinitializer, align 8
@glob.i32.align16 = global i32 zeroinitializer, align 16
@array4xi32 = global [4 x i32] zeroinitializer, align 16
define i64 @ptrtoint_align_2_size_4_add_5() {
; CHECK-LABEL: 'ptrtoint_align_2_size_4_add_5'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_2_size_4_add_5
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @glob.i32.align2 to i64), 5
; CHECK-NEXT: --> (5 + (ptrtoint ptr @glob.i32.align2 to i64))<nuw> U: [7,0) S: [5,0)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_2_size_4_add_5
;
entry:
%add = add i64 ptrtoint (ptr @glob.i32.align2 to i64), 5
ret i64 %add
}
define i64 @ptrtoint_align_2_size_4_add_6() {
; CHECK-LABEL: 'ptrtoint_align_2_size_4_add_6'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_2_size_4_add_6
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @glob.i32.align2 to i64), 6
; CHECK-NEXT: --> (6 + (ptrtoint ptr @glob.i32.align2 to i64)) U: [0,-1) S: [-9223372036854775808,9223372036854775807)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_2_size_4_add_6
;
entry:
%add = add i64 ptrtoint (ptr @glob.i32.align2 to i64), 6
ret i64 %add
}
define i64 @ptrtoint_align_8_size_4_add_7() {
; CHECK-LABEL: 'ptrtoint_align_8_size_4_add_7'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_8_size_4_add_7
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @glob.i32.align8 to i64), 7
; CHECK-NEXT: --> (7 + (ptrtoint ptr @glob.i32.align8 to i64))<nuw><nsw> U: [15,0) S: [-9223372036854775801,-9223372036854775808)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_8_size_4_add_7
;
entry:
%add = add i64 ptrtoint (ptr @glob.i32.align8 to i64), 7
ret i64 %add
}
define i64 @ptrtoint_align_8_size_4_add_8() {
; CHECK-LABEL: 'ptrtoint_align_8_size_4_add_8'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_8_size_4_add_8
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @glob.i32.align8 to i64), 8
; CHECK-NEXT: --> (8 + (ptrtoint ptr @glob.i32.align8 to i64)) U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_8_size_4_add_8
;
entry:
%add = add i64 ptrtoint (ptr @glob.i32.align8 to i64), 8
ret i64 %add
}
define i64 @ptrtoint_align_16_size_4_add_15() {
; CHECK-LABEL: 'ptrtoint_align_16_size_4_add_15'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_4_add_15
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @glob.i32.align16 to i64), 15
; CHECK-NEXT: --> (15 + (ptrtoint ptr @glob.i32.align16 to i64))<nuw><nsw> U: [31,0) S: [-9223372036854775793,-9223372036854775808)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_4_add_15
;
entry:
%add = add i64 ptrtoint (ptr @glob.i32.align16 to i64), 15
ret i64 %add
}
define i64 @ptrtoint_align_16_size_4_add_16() {
; CHECK-LABEL: 'ptrtoint_align_16_size_4_add_16'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_4_add_16
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @glob.i32.align16 to i64), 16
; CHECK-NEXT: --> (16 + (ptrtoint ptr @glob.i32.align16 to i64)) U: [0,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_4_add_16
;
entry:
%add = add i64 ptrtoint (ptr @glob.i32.align16 to i64), 16
ret i64 %add
}
define i64 @ptrtoint_align_16_size_16_add_16() {
; CHECK-LABEL: 'ptrtoint_align_16_size_16_add_16'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_16_add_16
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @array4xi32 to i64), 16
; CHECK-NEXT: --> (16 + (ptrtoint ptr @array4xi32 to i64))<nuw> U: [32,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_16_add_16
;
entry:
%add = add i64 ptrtoint (ptr @array4xi32 to i64), 16
ret i64 %add
}
define i64 @ptrtoint_align_16_size_16_add_31() {
; CHECK-LABEL: 'ptrtoint_align_16_size_16_add_31'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_16_add_31
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @array4xi32 to i64), 31
; CHECK-NEXT: --> (31 + (ptrtoint ptr @array4xi32 to i64))<nuw> U: [47,0) S: [31,0)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_16_add_31
;
entry:
%add = add i64 ptrtoint (ptr @array4xi32 to i64), 31
ret i64 %add
}
define i64 @ptrtoint_align_16_size_16_add_32() {
; CHECK-LABEL: 'ptrtoint_align_16_size_16_add_32'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_16_add_32
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @array4xi32 to i64), 32
; CHECK-NEXT: --> (32 + (ptrtoint ptr @array4xi32 to i64)) U: [0,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_16_add_32
;
entry:
%add = add i64 ptrtoint (ptr @array4xi32 to i64), 32
ret i64 %add
}
define i64 @ptrtoint_align_16_size_16_add_33() {
; CHECK-LABEL: 'ptrtoint_align_16_size_16_add_33'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_16_add_33
; CHECK-NEXT: %add = add i64 ptrtoint (ptr @array4xi32 to i64), 33
; CHECK-NEXT: --> (33 + (ptrtoint ptr @array4xi32 to i64)) U: [49,2) S: [-9223372036854775775,-9223372036854775790)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_16_add_33
;
entry:
%add = add i64 ptrtoint (ptr @array4xi32 to i64), 33
ret i64 %add
}
define i64 @ptrtoint_align_16_size_16_add_16_umax_sub() {
; CHECK-LABEL: 'ptrtoint_align_16_size_16_add_16_umax_sub'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_16_add_16_umax_sub
; CHECK-NEXT: %add.16 = add i64 ptrtoint (ptr @array4xi32 to i64), 16
; CHECK-NEXT: --> (16 + (ptrtoint ptr @array4xi32 to i64))<nuw> U: [32,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: %umax = call i64 @llvm.umax.i64(i64 ptrtoint (ptr @array4xi32 to i64), i64 %add.16)
; CHECK-NEXT: --> (16 + (ptrtoint ptr @array4xi32 to i64))<nuw> U: [32,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: %add = add i64 %umax, 16
; CHECK-NEXT: --> (32 + (ptrtoint ptr @array4xi32 to i64)) U: [0,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: %sub = sub i64 %add, ptrtoint (ptr @array4xi32 to i64)
; CHECK-NEXT: --> 32 U: [32,33) S: [32,33)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_16_add_16_umax_sub
;
entry:
%add.16 = add i64 ptrtoint (ptr @array4xi32 to i64), 16
%umax = call i64 @llvm.umax.i64(i64 ptrtoint (ptr @array4xi32 to i64), i64 %add.16)
%add = add i64 %umax, 16
%sub = sub i64 %add, ptrtoint (ptr @array4xi32 to i64)
ret i64 %sub
}
define i64 @ptrtoint_align_16_size_16_add_31_umax_sub() {
; CHECK-LABEL: 'ptrtoint_align_16_size_16_add_31_umax_sub'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_16_add_31_umax_sub
; CHECK-NEXT: %add.31 = add i64 ptrtoint (ptr @array4xi32 to i64), 31
; CHECK-NEXT: --> (31 + (ptrtoint ptr @array4xi32 to i64))<nuw> U: [47,0) S: [31,0)
; CHECK-NEXT: %umax = call i64 @llvm.umax.i64(i64 ptrtoint (ptr @array4xi32 to i64), i64 %add.31)
; CHECK-NEXT: --> (31 + (ptrtoint ptr @array4xi32 to i64))<nuw> U: [47,0) S: [31,0)
; CHECK-NEXT: %add = add i64 %umax, 16
; CHECK-NEXT: --> (47 + (ptrtoint ptr @array4xi32 to i64)) U: [63,16) S: [-9223372036854775761,-9223372036854775776)
; CHECK-NEXT: %sub = sub i64 %add, ptrtoint (ptr @array4xi32 to i64)
; CHECK-NEXT: --> 47 U: [47,48) S: [47,48)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_16_add_31_umax_sub
;
entry:
%add.31 = add i64 ptrtoint (ptr @array4xi32 to i64), 31
%umax = call i64 @llvm.umax.i64(i64 ptrtoint (ptr @array4xi32 to i64), i64 %add.31)
%add = add i64 %umax, 16
%sub = sub i64 %add, ptrtoint (ptr @array4xi32 to i64)
ret i64 %sub
}
define i64 @ptrtoint_align_16_size_16_add_32_umax_sub() {
; CHECK-LABEL: 'ptrtoint_align_16_size_16_add_32_umax_sub'
; CHECK-NEXT: Classifying expressions for: @ptrtoint_align_16_size_16_add_32_umax_sub
; CHECK-NEXT: %add.32 = add i64 ptrtoint (ptr @array4xi32 to i64), 32
; CHECK-NEXT: --> (32 + (ptrtoint ptr @array4xi32 to i64)) U: [0,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: %umax = call i64 @llvm.umax.i64(i64 ptrtoint (ptr @array4xi32 to i64), i64 %add.32)
; CHECK-NEXT: --> ((32 + (ptrtoint ptr @array4xi32 to i64)) umax (ptrtoint ptr @array4xi32 to i64)) U: [16,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: %add = add i64 %umax, 16
; CHECK-NEXT: --> (16 + ((32 + (ptrtoint ptr @array4xi32 to i64)) umax (ptrtoint ptr @array4xi32 to i64))) U: [0,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: %sub = sub i64 %add, ptrtoint (ptr @array4xi32 to i64)
; CHECK-NEXT: --> (16 + (-1 * (ptrtoint ptr @array4xi32 to i64)) + ((32 + (ptrtoint ptr @array4xi32 to i64)) umax (ptrtoint ptr @array4xi32 to i64))) U: [0,-15) S: [-9223372036854775808,9223372036854775793)
; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_align_16_size_16_add_32_umax_sub
;
entry:
%add.32 = add i64 ptrtoint (ptr @array4xi32 to i64), 32
%umax = call i64 @llvm.umax.i64(i64 ptrtoint (ptr @array4xi32 to i64), i64 %add.32)
%add = add i64 %umax, 16
%sub = sub i64 %add, ptrtoint (ptr @array4xi32 to i64)
ret i64 %sub
}
declare i64 @llvm.umax.i64(i64, i64)