xref: /llvm-project/llvm/test/Analysis/ScalarEvolution/pointer-rounding.ll (revision fd20eb55f1b62d90e4cc45438a5be993256c1f3a)
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
3
4define 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
16;
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
22}
23
24define 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
36;
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
42}
43
44define 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
58;
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
65}
66
67define 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
81;
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
88}
89
90define 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
106;
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
115}
116
117define 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
133;
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
142}
143
144define 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
160;
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
169}
170