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