[PATCH] D154009: [InstCombine] Folding `(inttoptr (and (ptrtoint Ptr), Mask))` -> `@llvm.ptrmask(Ptr, Mask)`

Noah Goldstein via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 28 14:18:01 PDT 2023


goldstein.w.n created this revision.
goldstein.w.n added reviewers: nikic, RKSimon.
Herald added subscribers: StephenFan, hiraditya, arichardson.
Herald added a project: All.
goldstein.w.n requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This works if `Ptr` has `noundef`: https://alive2.llvm.org/ce/z/S6yEwr

Alive2 does not support `@llvm.ptrmask`, but `@llvm.ptrmask` is
documented as equivilent to:
`(getelementptr i8 Ptr, (sub (and (ptrtoint Ptr), Mask), (ptrtoint Ptr)))`

See: https://llvm.org/docs/LangRef.html#llvm-ptrmask-intrinsic

Alive2 also doesn't handle `inttoptr`, so the proof compares:

  define i64 @src_ptrtoint(ptr noundef %p, i64 %m) {
    %pi = ptrtoint ptr %p to i64
    %pi_masked = and i64 %pi, %m
    ret i64 %pi_masked
  }
  
  define i64 @tgt_ptrtoint(ptr noundef %p, i64 %m) {
    %pi = ptrtoint ptr %p to i64
    %pi_m = and i64 %pi, %m
    %pi_off = sub i64 %pi_m, %pi
    %pm = getelementptr i8, ptr %p, i64 %pi_off
    %pi_masked = ptrtoint ptr %pm to i64
    ret i64 %pi_masked
  }

Which verifies


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154009

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
  llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll
  llvm/test/Transforms/InstCombine/to-ptrmask.ll


Index: llvm/test/Transforms/InstCombine/to-ptrmask.ll
===================================================================
--- llvm/test/Transforms/InstCombine/to-ptrmask.ll
+++ llvm/test/Transforms/InstCombine/to-ptrmask.ll
@@ -7,9 +7,7 @@
 define ptr @intoptr_mask(ptr noundef %p, i64 %m) {
 ; CHECK-LABEL: define ptr @intoptr_mask
 ; CHECK-SAME: (ptr noundef [[P:%.*]], i64 [[M:%.*]]) {
-; CHECK-NEXT:    [[PI:%.*]] = ptrtoint ptr [[P]] to i64
-; CHECK-NEXT:    [[PI_MASKED:%.*]] = and i64 [[PI]], [[M]]
-; CHECK-NEXT:    [[PM:%.*]] = inttoptr i64 [[PI_MASKED]] to ptr
+; CHECK-NEXT:    [[PM:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 [[M]])
 ; CHECK-NEXT:    ret ptr [[PM]]
 ;
   %pi = ptrtoint ptr %p to i64
Index: llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll
===================================================================
--- llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll
+++ llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll
@@ -121,9 +121,7 @@
 ; CHECK-LABEL: define void @maybenullAfterPtr2Int() {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
-; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 4294967292
-; CHECK-NEXT:    [[I2P:%.*]] = inttoptr i64 [[TMP1]] to ptr
+; CHECK-NEXT:    [[I2P:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr nonnull [[A]], i64 4294967292)
 ; CHECK-NEXT:    call void @foo(ptr [[I2P]])
 ; CHECK-NEXT:    ret void
 ;
Index: llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1913,6 +1913,21 @@
   if (Instruction *I = commonCastTransforms(CI))
     return I;
 
+  // Convert:
+  // (inttoptr (and (ptrtoint Ptr), Mask))
+  //    -> llvm.ptrmask(Ptr, Mask)
+  // IFF
+  //    Ptr is noundef
+  //    Non-vec type (ptrmask of vec is weird).
+  Value *Ptr, *Mask;
+  if (!CI.getType()->isVectorTy() &&
+      match(CI.getOperand(0),
+            m_OneUse(m_c_And(m_PtrToInt(m_Value(Ptr)), m_Value(Mask)))) &&
+      isGuaranteedNotToBeUndefOrPoison(Ptr))
+    return replaceInstUsesWith(CI, Builder.CreateIntrinsic(Ptr->getType(),
+                                                           Intrinsic::ptrmask,
+                                                           {Ptr, Mask}));
+
   return nullptr;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154009.535531.patch
Type: text/x-patch
Size: 2504 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230628/80575164/attachment-0001.bin>


More information about the llvm-commits mailing list