Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Analysis / ScalarEvolution / pointer-rounding.ll
blob6d6143367756e9f0a941745da3e2328c25fa3e63
1 ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
2 ; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
4 define ptr @pointer_align_down(ptr %obj) {
5 ; CHECK-LABEL: 'pointer_align_down'
6 ; CHECK-NEXT:  Classifying expressions for: @pointer_align_down
7 ; CHECK-NEXT:    %i = ptrtoint ptr %obj to i64
8 ; CHECK-NEXT:    --> (ptrtoint ptr %obj to i64) U: full-set S: full-set
9 ; CHECK-NEXT:    %i2 = and i64 %i, 15
10 ; CHECK-NEXT:    --> (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64) U: [0,16) S: [0,16)
11 ; CHECK-NEXT:    %i3 = sub nsw i64 0, %i2
12 ; CHECK-NEXT:    --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1)
13 ; CHECK-NEXT:    %i4 = getelementptr i8, ptr %obj, i64 %i3
14 ; CHECK-NEXT:    --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> + %obj) U: full-set S: full-set
15 ; CHECK-NEXT:  Determining loop execution counts for: @pointer_align_down
17   %i = ptrtoint ptr %obj to i64
18   %i2 = and i64 %i, 15
19   %i3 = sub nsw i64 0, %i2
20   %i4 = getelementptr i8, ptr %obj, i64 %i3
21   ret ptr %i4
24 define ptr @pointer_align_down_different_donor(ptr %obj_to_align, ptr %obj_donor) {
25 ; CHECK-LABEL: 'pointer_align_down_different_donor'
26 ; CHECK-NEXT:  Classifying expressions for: @pointer_align_down_different_donor
27 ; CHECK-NEXT:    %i = ptrtoint ptr %obj_donor to i64
28 ; CHECK-NEXT:    --> (ptrtoint ptr %obj_donor to i64) U: full-set S: full-set
29 ; CHECK-NEXT:    %i2 = and i64 %i, 15
30 ; CHECK-NEXT:    --> (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64) U: [0,16) S: [0,16)
31 ; CHECK-NEXT:    %i3 = sub nsw i64 0, %i2
32 ; CHECK-NEXT:    --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1)
33 ; CHECK-NEXT:    %i4 = getelementptr i8, ptr %obj_to_align, i64 %i3
34 ; CHECK-NEXT:    --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %obj_to_align) U: full-set S: full-set
35 ; CHECK-NEXT:  Determining loop execution counts for: @pointer_align_down_different_donor
37   %i = ptrtoint ptr %obj_donor to i64
38   %i2 = and i64 %i, 15
39   %i3 = sub nsw i64 0, %i2
40   %i4 = getelementptr i8, ptr %obj_to_align, i64 %i3
41   ret ptr %i4
44 define ptr @pointer_align_up(ptr noundef %obj) {
45 ; CHECK-LABEL: 'pointer_align_up'
46 ; CHECK-NEXT:  Classifying expressions for: @pointer_align_up
47 ; CHECK-NEXT:    %intptr = ptrtoint ptr %obj to i64
48 ; CHECK-NEXT:    --> (ptrtoint ptr %obj to i64) U: full-set S: full-set
49 ; CHECK-NEXT:    %over_boundary = add i64 %intptr, 15
50 ; CHECK-NEXT:    --> (15 + (ptrtoint ptr %obj to i64)) U: full-set S: full-set
51 ; CHECK-NEXT:    %aligned_intptr = and i64 %over_boundary, -16
52 ; CHECK-NEXT:    --> (16 * ((15 + (ptrtoint ptr %obj to i64)) /u 16))<nuw> U: [0,-15) S: [-9223372036854775808,9223372036854775793)
53 ; CHECK-NEXT:    %diff = sub i64 %aligned_intptr, %intptr
54 ; CHECK-NEXT:    --> ((16 * ((15 + (ptrtoint ptr %obj to i64)) /u 16))<nuw> + (-1 * (ptrtoint ptr %obj to i64))) U: full-set S: full-set
55 ; CHECK-NEXT:    %aligned_result = getelementptr i8, ptr %obj, i64 %diff
56 ; CHECK-NEXT:    --> ((16 * ((15 + (ptrtoint ptr %obj to i64)) /u 16))<nuw> + (-1 * (ptrtoint ptr %obj to i64)) + %obj) U: full-set S: full-set
57 ; CHECK-NEXT:  Determining loop execution counts for: @pointer_align_up
59   %intptr = ptrtoint ptr %obj to i64
60   %over_boundary = add i64 %intptr, 15
61   %aligned_intptr = and i64 %over_boundary, -16
62   %diff = sub i64 %aligned_intptr, %intptr
63   %aligned_result = getelementptr i8, ptr %obj, i64 %diff
64   ret ptr %aligned_result
67 define ptr @pointer_align_up_different_donor(ptr noundef %obj_to_align, ptr %obj_donor) {
68 ; CHECK-LABEL: 'pointer_align_up_different_donor'
69 ; CHECK-NEXT:  Classifying expressions for: @pointer_align_up_different_donor
70 ; CHECK-NEXT:    %intptr = ptrtoint ptr %obj_donor to i64
71 ; CHECK-NEXT:    --> (ptrtoint ptr %obj_donor to i64) U: full-set S: full-set
72 ; CHECK-NEXT:    %over_boundary = add i64 %intptr, 15
73 ; CHECK-NEXT:    --> (15 + (ptrtoint ptr %obj_donor to i64)) U: full-set S: full-set
74 ; CHECK-NEXT:    %aligned_intptr = and i64 %over_boundary, -16
75 ; CHECK-NEXT:    --> (16 * ((15 + (ptrtoint ptr %obj_donor to i64)) /u 16))<nuw> U: [0,-15) S: [-9223372036854775808,9223372036854775793)
76 ; CHECK-NEXT:    %diff = sub i64 %aligned_intptr, %intptr
77 ; CHECK-NEXT:    --> ((16 * ((15 + (ptrtoint ptr %obj_donor to i64)) /u 16))<nuw> + (-1 * (ptrtoint ptr %obj_donor to i64))) U: full-set S: full-set
78 ; CHECK-NEXT:    %aligned_result = getelementptr i8, ptr %obj_to_align, i64 %diff
79 ; CHECK-NEXT:    --> ((16 * ((15 + (ptrtoint ptr %obj_donor to i64)) /u 16))<nuw> + (-1 * (ptrtoint ptr %obj_donor to i64)) + %obj_to_align) U: full-set S: full-set
80 ; CHECK-NEXT:  Determining loop execution counts for: @pointer_align_up_different_donor
82   %intptr = ptrtoint ptr %obj_donor to i64
83   %over_boundary = add i64 %intptr, 15
84   %aligned_intptr = and i64 %over_boundary, -16
85   %diff = sub i64 %aligned_intptr, %intptr
86   %aligned_result = getelementptr i8, ptr %obj_to_align, i64 %diff
87   ret ptr %aligned_result
90 define ptr @pointer_align_up_with_select(ptr %obj) {
91 ; CHECK-LABEL: 'pointer_align_up_with_select'
92 ; CHECK-NEXT:  Classifying expressions for: @pointer_align_up_with_select
93 ; CHECK-NEXT:    %i = ptrtoint ptr %obj to i64
94 ; CHECK-NEXT:    --> (ptrtoint ptr %obj to i64) U: full-set S: full-set
95 ; CHECK-NEXT:    %i2 = and i64 %i, 15
96 ; CHECK-NEXT:    --> (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64) U: [0,16) S: [0,16)
97 ; CHECK-NEXT:    %i4 = sub nsw i64 0, %i2
98 ; CHECK-NEXT:    --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1)
99 ; CHECK-NEXT:    %i5 = getelementptr i8, ptr %obj, i64 %i4
100 ; CHECK-NEXT:    --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> + %obj) U: full-set S: full-set
101 ; CHECK-NEXT:    %i6 = getelementptr i8, ptr %i5, i64 16
102 ; CHECK-NEXT:    --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> + %obj) U: full-set S: full-set
103 ; CHECK-NEXT:    %i7 = select i1 %i3, ptr %obj, ptr %i6
104 ; CHECK-NEXT:    --> %i7 U: full-set S: full-set
105 ; CHECK-NEXT:  Determining loop execution counts for: @pointer_align_up_with_select
107   %i = ptrtoint ptr %obj to i64
108   %i2 = and i64 %i, 15
109   %i3 = icmp eq i64 %i2, 0
110   %i4 = sub nsw i64 0, %i2
111   %i5 = getelementptr i8, ptr %obj, i64 %i4
112   %i6 = getelementptr i8, ptr %i5, i64 16
113   %i7 = select i1 %i3, ptr %obj, ptr %i6
114   ret ptr %i7
117 define ptr @pointer_align_up_with_select_different_donor(ptr %obj_to_align, ptr %obj_donor) {
118 ; CHECK-LABEL: 'pointer_align_up_with_select_different_donor'
119 ; CHECK-NEXT:  Classifying expressions for: @pointer_align_up_with_select_different_donor
120 ; CHECK-NEXT:    %i = ptrtoint ptr %obj_donor to i64
121 ; CHECK-NEXT:    --> (ptrtoint ptr %obj_donor to i64) U: full-set S: full-set
122 ; CHECK-NEXT:    %i2 = and i64 %i, 15
123 ; CHECK-NEXT:    --> (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64) U: [0,16) S: [0,16)
124 ; CHECK-NEXT:    %i4 = sub nsw i64 0, %i2
125 ; CHECK-NEXT:    --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1)
126 ; CHECK-NEXT:    %i5 = getelementptr i8, ptr %obj_to_align, i64 %i4
127 ; CHECK-NEXT:    --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %obj_to_align) U: full-set S: full-set
128 ; CHECK-NEXT:    %i6 = getelementptr i8, ptr %i5, i64 16
129 ; CHECK-NEXT:    --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %obj_to_align) U: full-set S: full-set
130 ; CHECK-NEXT:    %i7 = select i1 %i3, ptr %obj_to_align, ptr %i6
131 ; CHECK-NEXT:    --> %i7 U: full-set S: full-set
132 ; CHECK-NEXT:  Determining loop execution counts for: @pointer_align_up_with_select_different_donor
134   %i = ptrtoint ptr %obj_donor to i64
135   %i2 = and i64 %i, 15
136   %i3 = icmp eq i64 %i2, 0
137   %i4 = sub nsw i64 0, %i2
138   %i5 = getelementptr i8, ptr %obj_to_align, i64 %i4
139   %i6 = getelementptr i8, ptr %i5, i64 16
140   %i7 = select i1 %i3, ptr %obj_to_align, ptr %i6
141   ret ptr %i7
144 define ptr @pointer_align_up_with_select_different_objects_bad(ptr %first_obj, ptr %second_obj, ptr %obj_donor) {
145 ; CHECK-LABEL: 'pointer_align_up_with_select_different_objects_bad'
146 ; CHECK-NEXT:  Classifying expressions for: @pointer_align_up_with_select_different_objects_bad
147 ; CHECK-NEXT:    %i = ptrtoint ptr %obj_donor to i64
148 ; CHECK-NEXT:    --> (ptrtoint ptr %obj_donor to i64) U: full-set S: full-set
149 ; CHECK-NEXT:    %i2 = and i64 %i, 15
150 ; CHECK-NEXT:    --> (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64) U: [0,16) S: [0,16)
151 ; CHECK-NEXT:    %i4 = sub nsw i64 0, %i2
152 ; CHECK-NEXT:    --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1)
153 ; CHECK-NEXT:    %i5 = getelementptr i8, ptr %second_obj, i64 %i4
154 ; CHECK-NEXT:    --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %second_obj) U: full-set S: full-set
155 ; CHECK-NEXT:    %i6 = getelementptr i8, ptr %i5, i64 16
156 ; CHECK-NEXT:    --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %second_obj) U: full-set S: full-set
157 ; CHECK-NEXT:    %i7 = select i1 %i3, ptr %first_obj, ptr %i6
158 ; CHECK-NEXT:    --> %i7 U: full-set S: full-set
159 ; CHECK-NEXT:  Determining loop execution counts for: @pointer_align_up_with_select_different_objects_bad
161   %i = ptrtoint ptr %obj_donor to i64
162   %i2 = and i64 %i, 15
163   %i3 = icmp eq i64 %i2, 0
164   %i4 = sub nsw i64 0, %i2
165   %i5 = getelementptr i8, ptr %second_obj, i64 %i4
166   %i6 = getelementptr i8, ptr %i5, i64 16
167   %i7 = select i1 %i3, ptr %first_obj, ptr %i6
168   ret ptr %i7