Skip to content

Commit 187a8e3

Browse files
authored
[InstSimplify] Support ptrtoaddr in pointer subtraction fold (#162672)
Add a new m_PtrToIntOrAddr() matcher which matches both ptrtoint and ptrtoaddr. Pointer arithmetic only works on the address bits, so supporting ptrtoaddr is always fine here.
1 parent 0dff52b commit 187a8e3

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,18 @@ inline PtrToIntSameSize_match<OpTy> m_PtrToIntSameSize(const DataLayout &DL,
21842184
return PtrToIntSameSize_match<OpTy>(DL, Op);
21852185
}
21862186

2187+
/// Matches PtrToAddr.
2188+
template <typename OpTy>
2189+
inline CastOperator_match<OpTy, Instruction::PtrToAddr>
2190+
m_PtrToAddr(const OpTy &Op) {
2191+
return CastOperator_match<OpTy, Instruction::PtrToAddr>(Op);
2192+
}
2193+
2194+
/// Matches PtrToInt or PtrToAddr.
2195+
template <typename OpTy> inline auto m_PtrToIntOrAddr(const OpTy &Op) {
2196+
return m_CombineOr(m_PtrToInt(Op), m_PtrToAddr(Op));
2197+
}
2198+
21872199
/// Matches IntToPtr.
21882200
template <typename OpTy>
21892201
inline CastOperator_match<OpTy, Instruction::IntToPtr>

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -853,10 +853,12 @@ static Value *simplifySubInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
853853
return W;
854854

855855
// Variations on GEP(base, I, ...) - GEP(base, i, ...) -> GEP(null, I-i, ...).
856-
if (match(Op0, m_PtrToInt(m_Value(X))) && match(Op1, m_PtrToInt(m_Value(Y))))
856+
if (match(Op0, m_PtrToIntOrAddr(m_Value(X))) &&
857+
match(Op1, m_PtrToIntOrAddr(m_Value(Y)))) {
857858
if (Constant *Result = computePointerDifference(Q.DL, X, Y))
858859
return ConstantFoldIntegerCast(Result, Op0->getType(), /*IsSigned*/ true,
859860
Q.DL);
861+
}
860862

861863
// i1 sub -> xor.
862864
if (MaxRecurse && Op0->getType()->isIntOrIntVectorTy(1))

llvm/test/Transforms/InstCombine/ptrtoaddr.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,27 @@ define i32 @ptrtoaddr_sub_consts_offset_addrsize() {
130130
;
131131
ret i32 sub (i32 ptrtoaddr (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) @g.as1, i32 42) to i32), i32 ptrtoaddr (ptr addrspace(1) @g.as1 to i32))
132132
}
133+
134+
define i64 @ptrtoaddr_sub_known_offset(ptr %p) {
135+
; CHECK-LABEL: define i64 @ptrtoaddr_sub_known_offset(
136+
; CHECK-SAME: ptr [[P:%.*]]) {
137+
; CHECK-NEXT: ret i64 42
138+
;
139+
%p2 = getelementptr inbounds i8, ptr %p, i64 42
140+
%p.addr = ptrtoaddr ptr %p to i64
141+
%p2.addr = ptrtoaddr ptr %p2 to i64
142+
%sub = sub i64 %p2.addr, %p.addr
143+
ret i64 %sub
144+
}
145+
146+
define i32 @ptrtoaddr_sub_known_offset_addrsize(ptr addrspace(1) %p) {
147+
; CHECK-LABEL: define i32 @ptrtoaddr_sub_known_offset_addrsize(
148+
; CHECK-SAME: ptr addrspace(1) [[P:%.*]]) {
149+
; CHECK-NEXT: ret i32 42
150+
;
151+
%p2 = getelementptr inbounds i8, ptr addrspace(1) %p, i32 42
152+
%p.addr = ptrtoaddr ptr addrspace(1) %p to i32
153+
%p2.addr = ptrtoaddr ptr addrspace(1) %p2 to i32
154+
%sub = sub i32 %p2.addr, %p.addr
155+
ret i32 %sub
156+
}

0 commit comments

Comments
 (0)