Skip to content

Commit b6bbc4b

Browse files
committed
[InstCombine] Support ptrtoaddr of ptrmask fold
For now not trying to share the code with ptrtoint, as there's very little code. Also fix IRBuilder::CreatePtrToAddr to actually create a PtrToAddr instruction...
1 parent 7900e63 commit b6bbc4b

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2191,7 +2191,7 @@ class IRBuilderBase {
21912191
FMFSource);
21922192
}
21932193
Value *CreatePtrToAddr(Value *V, const Twine &Name = "") {
2194-
return CreateCast(Instruction::PtrToInt, V,
2194+
return CreateCast(Instruction::PtrToAddr, V,
21952195
BB->getDataLayout().getAddressType(V->getType()), Name);
21962196
}
21972197
Value *CreatePtrToInt(Value *V, Type *DestTy,

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,6 +2228,18 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
22282228
}
22292229

22302230
Instruction *InstCombinerImpl::visitPtrToAddr(PtrToAddrInst &CI) {
2231+
Value *SrcOp = CI.getPointerOperand();
2232+
Type *Ty = CI.getType();
2233+
2234+
// (ptrtoaddr (ptrmask P, M))
2235+
// -> (and (ptrtoaddr P), M)
2236+
// This is generally beneficial as `and` is better supported than `ptrmask`.
2237+
Value *Ptr, *Mask;
2238+
if (match(SrcOp, m_OneUse(m_Intrinsic<Intrinsic::ptrmask>(m_Value(Ptr),
2239+
m_Value(Mask)))) &&
2240+
Mask->getType() == Ty)
2241+
return BinaryOperator::CreateAnd(Builder.CreatePtrToAddr(Ptr), Mask);
2242+
22312243
// FIXME: Implement variants of ptrtoint folds.
22322244
return commonCastTransforms(CI);
22332245
}

llvm/test/Transforms/InstCombine/ptrtoaddr.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,27 @@ define ptr addrspace(1) @gep_sub_ptrtoaddr_different_obj_addrsize(ptr addrspace(
237237
call void @use.i32(i32 %addr)
238238
ret ptr addrspace(1) %gep
239239
}
240+
241+
define i64 @ptrtoaddr_of_ptrmask(ptr %p, i64 %mask) {
242+
; CHECK-LABEL: define i64 @ptrtoaddr_of_ptrmask(
243+
; CHECK-SAME: ptr [[P:%.*]], i64 [[MASK:%.*]]) {
244+
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoaddr ptr [[P]] to i64
245+
; CHECK-NEXT: [[ADDR:%.*]] = and i64 [[MASK]], [[TMP1]]
246+
; CHECK-NEXT: ret i64 [[ADDR]]
247+
;
248+
%masked = call ptr @llvm.ptrmask(ptr %p, i64 %mask)
249+
%addr = ptrtoaddr ptr %masked to i64
250+
ret i64 %addr
251+
}
252+
253+
define i32 @ptrtoaddr_of_ptrmask_addrsize(ptr addrspace(1) %p, i32 %mask) {
254+
; CHECK-LABEL: define i32 @ptrtoaddr_of_ptrmask_addrsize(
255+
; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[MASK:%.*]]) {
256+
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoaddr ptr addrspace(1) [[P]] to i32
257+
; CHECK-NEXT: [[ADDR:%.*]] = and i32 [[MASK]], [[TMP1]]
258+
; CHECK-NEXT: ret i32 [[ADDR]]
259+
;
260+
%masked = call ptr addrspace(1) @llvm.ptrmask(ptr addrspace(1) %p, i32 %mask)
261+
%addr = ptrtoaddr ptr addrspace(1) %masked to i32
262+
ret i32 %addr
263+
}

0 commit comments

Comments
 (0)