xref: /llvm-project/llvm/test/Transforms/InstCombine/phi-int2ptr-fold.ll (revision 2caaec65c04ea7d0e9568b7895b7a46d6100cb75)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instcombine -S -disable-i2p-p2i-opt < %s | FileCheck %s
3
4target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64"
5target triple = "x86_64-unknown-linux-gnu"
6
7; convert ptrtoint [ phi[ inttoptr (ptrtoint (x) ) ] ---> ptrtoint (phi[x])
8
9define i64 @func(ptr %X, ptr %Y, i1 %cond) {
10; CHECK-LABEL: @func(
11; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
12; CHECK:       bb1:
13; CHECK-NEXT:    br label [[EXIT:%.*]]
14; CHECK:       bb2:
15; CHECK-NEXT:    br label [[EXIT]]
16; CHECK:       exit:
17; CHECK-NEXT:    [[PHI_IN:%.*]] = phi ptr [ [[X:%.*]], [[BB1]] ], [ [[Y:%.*]], [[BB2]] ]
18; CHECK-NEXT:    [[X_P_I:%.*]] = ptrtoint ptr [[PHI_IN]] to i64
19; CHECK-NEXT:    ret i64 [[X_P_I]]
20;
21  br i1 %cond, label %bb1, label %bb2
22
23bb1:
24  %X.i = ptrtoint ptr %X to i64
25  %X.p = inttoptr i64 %X.i to ptr
26  br label %exit
27
28bb2:
29  %Y.i = ptrtoint ptr %Y to i64
30  %Y.p = inttoptr i64 %Y.i to ptr
31  br label %exit
32
33exit:
34  %phi = phi ptr [%X.p, %bb1], [%Y.p, %bb2]
35  %X.p.i = ptrtoint ptr %phi to i64
36  ret i64 %X.p.i
37}
38
39define i64 @func_single_operand(ptr %X, ptr %Y, i1 %cond) {
40; CHECK-LABEL: @func_single_operand(
41; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
42; CHECK:       bb1:
43; CHECK-NEXT:    br label [[EXIT]]
44; CHECK:       exit:
45; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[X:%.*]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ]
46; CHECK-NEXT:    [[X_P_I:%.*]] = ptrtoint ptr [[PHI]] to i64
47; CHECK-NEXT:    ret i64 [[X_P_I]]
48;
49  br i1 %cond, label %bb1, label %exit
50
51bb1:
52  %X.i = ptrtoint ptr %X to i64
53  %X.p = inttoptr i64 %X.i to ptr
54  br label %exit
55
56exit:
57  %phi = phi ptr [%X.p, %bb1], [%Y, %0]
58  %X.p.i = ptrtoint ptr %phi to i64
59  ret i64 %X.p.i
60}
61
62define i64 @func_pointer_different_types(ptr %X, ptr %Y, i1 %cond) {
63; CHECK-LABEL: @func_pointer_different_types(
64; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
65; CHECK:       bb1:
66; CHECK-NEXT:    br label [[EXIT]]
67; CHECK:       exit:
68; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[X:%.*]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ]
69; CHECK-NEXT:    [[X_P_I:%.*]] = ptrtoint ptr [[PHI]] to i64
70; CHECK-NEXT:    ret i64 [[X_P_I]]
71;
72  br i1 %cond, label %bb1, label %exit
73
74bb1:
75  %X.i = ptrtoint ptr %X to i64
76  %X.p = inttoptr i64 %X.i to ptr
77  br label %exit
78
79exit:
80  %phi = phi ptr [%X.p, %bb1], [%Y, %0]
81  %X.p.i = ptrtoint ptr %phi to i64
82  ret i64 %X.p.i
83}
84
85; Negative test - Wrong Integer type
86
87define i64 @func_integer_type_too_small(ptr %X, ptr %Y, i1 %cond) {
88; CHECK-LABEL: @func_integer_type_too_small(
89; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
90; CHECK:       bb1:
91; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[X:%.*]] to i64
92; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP1]], 4294967295
93; CHECK-NEXT:    [[X_P:%.*]] = inttoptr i64 [[TMP2]] to ptr
94; CHECK-NEXT:    br label [[EXIT]]
95; CHECK:       exit:
96; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[X_P]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ]
97; CHECK-NEXT:    [[X_P_I:%.*]] = ptrtoint ptr [[PHI]] to i64
98; CHECK-NEXT:    ret i64 [[X_P_I]]
99;
100  br i1 %cond, label %bb1, label %exit
101
102bb1:
103  %X.i = ptrtoint ptr %X to i32
104  %X.p = inttoptr i32 %X.i to ptr
105  br label %exit
106
107exit:
108  %phi = phi ptr [%X.p, %bb1], [%Y, %0]
109  %X.p.i = ptrtoint ptr %phi to i64
110  ret i64 %X.p.i
111}
112
113; Negative test - phi not used in ptrtoint
114
115define ptr @func_phi_not_use_in_ptr2int(ptr %X, ptr %Y, i1 %cond) {
116; CHECK-LABEL: @func_phi_not_use_in_ptr2int(
117; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
118; CHECK:       bb1:
119; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[X:%.*]] to i64
120; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP1]], 4294967295
121; CHECK-NEXT:    [[X_P:%.*]] = inttoptr i64 [[TMP2]] to ptr
122; CHECK-NEXT:    br label [[EXIT]]
123; CHECK:       exit:
124; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[X_P]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ]
125; CHECK-NEXT:    ret ptr [[PHI]]
126;
127  br i1 %cond, label %bb1, label %exit
128
129bb1:
130  %X.i = ptrtoint ptr %X to i32
131  %X.p = inttoptr i32 %X.i to ptr
132  br label %exit
133
134exit:
135  %phi = phi ptr [%X.p, %bb1], [%Y, %0]
136  ret ptr %phi
137}
138
139; Negative test - Pointers in different address spaces
140
141define i64 @func_ptr_different_addrspace(ptr addrspace(2) %X, ptr %Y, i1 %cond) {
142; CHECK-LABEL: @func_ptr_different_addrspace(
143; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
144; CHECK:       bb1:
145; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[X:%.*]] to i32
146; CHECK-NEXT:    [[X_I:%.*]] = zext i32 [[TMP1]] to i64
147; CHECK-NEXT:    [[X_P:%.*]] = inttoptr i64 [[X_I]] to ptr
148; CHECK-NEXT:    br label [[EXIT]]
149; CHECK:       exit:
150; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[X_P]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ]
151; CHECK-NEXT:    [[X_P_I:%.*]] = ptrtoint ptr [[PHI]] to i64
152; CHECK-NEXT:    ret i64 [[X_P_I]]
153;
154  br i1 %cond, label %bb1, label %exit
155
156bb1:
157  %X.i = ptrtoint ptr addrspace(2) %X to i64
158  %X.p = inttoptr i64 %X.i to ptr
159  br label %exit
160
161exit:
162  %phi = phi ptr [%X.p, %bb1], [%Y, %0]
163  %X.p.i = ptrtoint ptr %phi to i64
164  ret i64 %X.p.i
165}
166