@@ -40,3 +40,134 @@ define i128 @ptrtoaddr_sext(ptr %p) {
4040 %ext = sext i64 %p.addr to i128
4141 ret i128 %ext
4242}
43+
44+ define i64 @sub_ptrtoaddr (ptr %p , i64 %offset ) {
45+ ; CHECK-LABEL: define i64 @sub_ptrtoaddr(
46+ ; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFSET:%.*]]) {
47+ ; CHECK-NEXT: ret i64 [[OFFSET]]
48+ ;
49+ %p2 = getelementptr i8 , ptr %p , i64 %offset
50+ %p.addr = ptr toaddr ptr %p to i64
51+ %p2.addr = ptr toaddr ptr %p2 to i64
52+ %sub = sub i64 %p2.addr , %p.addr
53+ ret i64 %sub
54+ }
55+
56+ define i64 @sub_ptrtoint_ptrtoaddr (ptr %p , i64 %offset ) {
57+ ; CHECK-LABEL: define i64 @sub_ptrtoint_ptrtoaddr(
58+ ; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFSET:%.*]]) {
59+ ; CHECK-NEXT: ret i64 [[OFFSET]]
60+ ;
61+ %p2 = getelementptr i8 , ptr %p , i64 %offset
62+ %p.int = ptrtoint ptr %p to i64
63+ %p2.addr = ptr toaddr ptr %p2 to i64
64+ %sub = sub i64 %p2.addr , %p.int
65+ ret i64 %sub
66+ }
67+
68+ define i32 @sub_ptrtoaddr_addrsize (ptr addrspace (1 ) %p , i32 %offset ) {
69+ ; CHECK-LABEL: define i32 @sub_ptrtoaddr_addrsize(
70+ ; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {
71+ ; CHECK-NEXT: ret i32 [[OFFSET]]
72+ ;
73+ %p2 = getelementptr i8 , ptr addrspace (1 ) %p , i32 %offset
74+ %p.addr = ptr toaddr ptr addrspace (1 ) %p to i32
75+ %p2.addr = ptr toaddr ptr addrspace (1 ) %p2 to i32
76+ %sub = sub i32 %p2.addr , %p.addr
77+ ret i32 %sub
78+ }
79+
80+ define i32 @sub_trunc_ptrtoaddr (ptr %p , i64 %offset ) {
81+ ; CHECK-LABEL: define i32 @sub_trunc_ptrtoaddr(
82+ ; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFSET:%.*]]) {
83+ ; CHECK-NEXT: [[SUB:%.*]] = trunc i64 [[OFFSET]] to i32
84+ ; CHECK-NEXT: ret i32 [[SUB]]
85+ ;
86+ %p2 = getelementptr i8 , ptr %p , i64 %offset
87+ %p.addr = ptr toaddr ptr %p to i64
88+ %p2.addr = ptr toaddr ptr %p2 to i64
89+ %p.addr.trunc = trunc i64 %p.addr to i32
90+ %p2.addr.trunc = trunc i64 %p2.addr to i32
91+ %sub = sub i32 %p2.addr.trunc , %p.addr.trunc
92+ ret i32 %sub
93+ }
94+
95+ define i16 @sub_trunc_ptrtoaddr_addrsize (ptr addrspace (1 ) %p , i32 %offset ) {
96+ ; CHECK-LABEL: define i16 @sub_trunc_ptrtoaddr_addrsize(
97+ ; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {
98+ ; CHECK-NEXT: [[SUB:%.*]] = trunc i32 [[OFFSET]] to i16
99+ ; CHECK-NEXT: ret i16 [[SUB]]
100+ ;
101+ %p2 = getelementptr i8 , ptr addrspace (1 ) %p , i32 %offset
102+ %p.addr = ptr toaddr ptr addrspace (1 ) %p to i32
103+ %p2.addr = ptr toaddr ptr addrspace (1 ) %p2 to i32
104+ %p.addr.trunc = trunc i32 %p.addr to i16
105+ %p2.addr.trunc = trunc i32 %p2.addr to i16
106+ %sub = sub i16 %p2.addr.trunc , %p.addr.trunc
107+ ret i16 %sub
108+ }
109+
110+ define i16 @sub_trunc_ptrtoint_ptrtoaddr_addrsize (ptr addrspace (1 ) %p , i32 %offset ) {
111+ ; CHECK-LABEL: define i16 @sub_trunc_ptrtoint_ptrtoaddr_addrsize(
112+ ; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {
113+ ; CHECK-NEXT: [[SUB:%.*]] = trunc i32 [[OFFSET]] to i16
114+ ; CHECK-NEXT: ret i16 [[SUB]]
115+ ;
116+ %p2 = getelementptr i8 , ptr addrspace (1 ) %p , i32 %offset
117+ %p.int = ptrtoint ptr addrspace (1 ) %p to i64
118+ %p2.addr = ptr toaddr ptr addrspace (1 ) %p2 to i32
119+ %p.int.trunc = trunc i64 %p.int to i16
120+ %p2.addr.trunc = trunc i32 %p2.addr to i16
121+ %sub = sub i16 %p2.addr.trunc , %p.int.trunc
122+ ret i16 %sub
123+ }
124+
125+ define i128 @sub_zext_ptrtoaddr (ptr %p , i64 %offset ) {
126+ ; CHECK-LABEL: define i128 @sub_zext_ptrtoaddr(
127+ ; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFSET:%.*]]) {
128+ ; CHECK-NEXT: [[SUB:%.*]] = zext i64 [[OFFSET]] to i128
129+ ; CHECK-NEXT: ret i128 [[SUB]]
130+ ;
131+ %p2 = getelementptr nuw i8 , ptr %p , i64 %offset
132+ %p.addr = ptr toaddr ptr %p to i64
133+ %p2.addr = ptr toaddr ptr %p2 to i64
134+ %p.addr.ext = zext i64 %p.addr to i128
135+ %p2.addr.ext = zext i64 %p2.addr to i128
136+ %sub = sub i128 %p2.addr.ext , %p.addr.ext
137+ ret i128 %sub
138+ }
139+
140+ define i64 @sub_zext_ptrtoaddr_addrsize (ptr addrspace (1 ) %p , i32 %offset ) {
141+ ; CHECK-LABEL: define i64 @sub_zext_ptrtoaddr_addrsize(
142+ ; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {
143+ ; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[OFFSET]] to i64
144+ ; CHECK-NEXT: ret i64 [[SUB]]
145+ ;
146+ %p2 = getelementptr nuw i8 , ptr addrspace (1 ) %p , i32 %offset
147+ %p.addr = ptr toaddr ptr addrspace (1 ) %p to i32
148+ %p2.addr = ptr toaddr ptr addrspace (1 ) %p2 to i32
149+ %p.addr.ext = zext i32 %p.addr to i64
150+ %p2.addr.ext = zext i32 %p2.addr to i64
151+ %sub = sub i64 %p2.addr.ext , %p.addr.ext
152+ ret i64 %sub
153+ }
154+
155+ define i128 @sub_zext_ptrtoint_ptrtoaddr_addrsize (ptr addrspace (1 ) %p , i32 %offset ) {
156+ ; CHECK-LABEL: define i128 @sub_zext_ptrtoint_ptrtoaddr_addrsize(
157+ ; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {
158+ ; CHECK-NEXT: [[P2:%.*]] = getelementptr nuw i8, ptr addrspace(1) [[P]], i32 [[OFFSET]]
159+ ; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr addrspace(1) [[P]] to i64
160+ ; CHECK-NEXT: [[P2_ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[P2]] to i32
161+ ; CHECK-NEXT: [[P_INT_EXT:%.*]] = zext i64 [[P_INT]] to i128
162+ ; CHECK-NEXT: [[P2_ADDR_EXT:%.*]] = zext i32 [[P2_ADDR]] to i128
163+ ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i128 [[P2_ADDR_EXT]], [[P_INT_EXT]]
164+ ; CHECK-NEXT: ret i128 [[SUB]]
165+ ;
166+ %p2 = getelementptr nuw i8 , ptr addrspace (1 ) %p , i32 %offset
167+ %p.int = ptrtoint ptr addrspace (1 ) %p to i64
168+ %p2.addr = ptr toaddr ptr addrspace (1 ) %p2 to i32
169+ %p.int.ext = zext i64 %p.int to i128
170+ %p2.addr.ext = zext i32 %p2.addr to i128
171+ %sub = sub i128 %p2.addr.ext , %p.int.ext
172+ ret i128 %sub
173+ }
0 commit comments