[llvm] r368986 - Add ptrmask intrinsic

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 15 03:12:26 PDT 2019


Author: fhahn
Date: Thu Aug 15 03:12:26 2019
New Revision: 368986

URL: http://llvm.org/viewvc/llvm-project?rev=368986&view=rev
Log:
Add ptrmask intrinsic

This patch adds a ptrmask intrinsic which allows masking out bits of a
pointer that must be zero when accessing it, because of ABI alignment
requirements or a restriction of the meaningful bits of a pointer
through the data layout.

This avoids doing a ptrtoint/inttoptr round trip in some cases (e.g. tagged
pointers) and allows us to not lose information about the underlying
object.

Reviewers: nlopes, efriedma, hfinkel, sanjoy, jdoerfert, aqjune

Reviewed by: sanjoy, jdoerfert

Differential Revision: https://reviews.llvm.org/D59065

Added:
    llvm/trunk/test/CodeGen/AArch64/lower-ptrmask.ll
    llvm/trunk/test/CodeGen/X86/lower-ptrmask.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/IR/Intrinsics.td
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=368986&r1=368985&r2=368986&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Thu Aug 15 03:12:26 2019
@@ -16895,6 +16895,42 @@ a constant.
 On the other hand, if constant folding is not run, it will never
 evaluate to true, even in simple cases.
 
+.. _int_ptrmask:
+
+'``llvm.ptrmask``' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+::
+
+      declare ptrty llvm.ptrmask(ptrty %ptr, intty %mask) readnone speculatable
+
+Arguments:
+""""""""""
+
+The first argument is a pointer. The second argument is an integer.
+
+Overview:
+""""""""""
+
+The ``llvm.ptrmask`` intrinsic masks out bits of the pointer according to a mask.
+This allows stripping data from tagged pointers without converting them to an
+integer (ptrtoint/inttoptr). As a consequence, we can preserve more information
+to facilitate alias analysis and underlying-object detection.
+
+Semantics:
+""""""""""
+
+The result of ``ptrmask(ptr, mask)`` is equivalent to
+``getelementptr ptr, (ptrtoint(ptr) & mask) - ptrtoint(ptr)``. Both the returned
+pointer and the first argument are based on the same underlying object (for more
+information on the *based on* terminology see
+:ref:`the pointer aliasing rules <pointeraliasing>`). If the bitwidth of the
+mask argument does not match the pointer size of the target, the mask is
+zero-extended or truncated accordingly.
+
 Stack Map Intrinsics
 --------------------
 

Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=368986&r1=368985&r2=368986&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Thu Aug 15 03:12:26 2019
@@ -1059,6 +1059,10 @@ def int_clear_cache : Intrinsic<[], [llv
 // Intrinsic to detect whether its argument is a constant.
 def int_is_constant : Intrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem, IntrWillReturn], "llvm.is.constant">;
 
+// Intrinsic to mask out bits of a pointer.
+def int_ptrmask: Intrinsic<[llvm_anyptr_ty], [llvm_anyptr_ty, llvm_anyint_ty],
+                           [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+
 //===-------------------------- Masked Intrinsics -------------------------===//
 //
 def int_masked_store : Intrinsic<[], [llvm_anyvector_ty,

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=368986&r1=368985&r2=368986&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Aug 15 03:12:26 2019
@@ -6859,6 +6859,17 @@ void SelectionDAGBuilder::visitIntrinsic
     setValue(&I, Val);
     return;
   }
+  case Intrinsic::ptrmask: {
+    SDValue Ptr = getValue(I.getOperand(0));
+    SDValue Const = getValue(I.getOperand(1));
+
+    EVT DestVT =
+        EVT(DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout()));
+
+    setValue(&I, DAG.getNode(ISD::AND, getCurSDLoc(), DestVT, Ptr,
+                             DAG.getZExtOrTrunc(Const, getCurSDLoc(), DestVT)));
+    return;
+  }
   }
 }
 

Added: llvm/trunk/test/CodeGen/AArch64/lower-ptrmask.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/lower-ptrmask.ll?rev=368986&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/lower-ptrmask.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/lower-ptrmask.ll Thu Aug 15 03:12:26 2019
@@ -0,0 +1,29 @@
+; RUN: llc -mtriple=arm64-apple-iphoneos -stop-after=finalize-isel %s -o - | FileCheck %s
+
+declare i8* @llvm.ptrmask.p0i8.i64(i8* , i64)
+
+; CHECK-LABEL: name: test1
+; CHECK:         %0:gpr64 = COPY $x0
+; CHECK-NEXT:    %1:gpr64sp = ANDXri %0, 8052
+; CHECK-NEXT:    $x0 = COPY %1
+; CHECK-NEXT:    RET_ReallyLR implicit $x0
+
+define i8* @test1(i8* %src) {
+  %ptr = call i8* @llvm.ptrmask.p0i8.i64(i8* %src, i64 72057594037927928)
+  ret i8* %ptr
+}
+
+declare i8* @llvm.ptrmask.p0i8.i32(i8*, i32)
+
+; CHECK-LABEL: name: test2
+; CHECK:         %0:gpr64 = COPY $x0
+; CHECK-NEXT:    %1:gpr32 = MOVi32imm 10000
+; CHECK-NEXT:    %2:gpr64 = SUBREG_TO_REG 0, killed %1, %subreg.sub_32
+; CHECK-NEXT:    %3:gpr64 = ANDXrr %0, killed %2
+; CHECK-NEXT:    $x0 = COPY %3
+; CHECK-NEXT:    RET_ReallyLR implicit $x0
+
+define i8* @test2(i8* %src) {
+  %ptr = call i8* @llvm.ptrmask.p0i8.i32(i8* %src, i32 10000)
+  ret i8* %ptr
+}

Added: llvm/trunk/test/CodeGen/X86/lower-ptrmask.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lower-ptrmask.ll?rev=368986&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/lower-ptrmask.ll (added)
+++ llvm/trunk/test/CodeGen/X86/lower-ptrmask.ll Thu Aug 15 03:12:26 2019
@@ -0,0 +1,31 @@
+; RUN: llc -mtriple=x86_64-apple-macosx -stop-after=finalize-isel %s -o - | FileCheck %s
+
+declare i8* @llvm.ptrmask.p0i8.i64(i8* , i64)
+
+; CHECK-LABEL: name: test1
+; CHECK:         %0:gr64 = COPY $rdi
+; CHECK-NEXT:    %1:gr64 = MOV64ri 72057594037927928
+; CHECK-NEXT:    %2:gr64 = AND64rr %0, killed %1, implicit-def dead $eflags
+; CHECK-NEXT:    $rax = COPY %2
+; CHECK-NEXT:    RET 0, $rax
+
+define i8* @test1(i8* %src) {
+  %ptr = call i8* @llvm.ptrmask.p0i8.i64(i8* %src, i64 72057594037927928)
+  ret i8* %ptr
+}
+
+declare i8* @llvm.ptrmask.p0i8.i32(i8*, i32)
+
+; CHECK-LABEL: name: test2
+; CHECK:         %0:gr64 = COPY $rdi
+; CHECK-NEXT:    %1:gr32 = COPY %0.sub_32bit
+; CHECK-NEXT:    %2:gr32 = AND32ri %1, 10000, implicit-def dead $eflags
+; CHECK-NEXT:    %3:gr64 = SUBREG_TO_REG 0, killed %2, %subreg.sub_32bit
+; CHECK-NEXT:    $rax = COPY %3
+; CHECK-NEXT:    RET 0, $rax
+
+
+define i8* @test2(i8* %src) {
+  %ptr = call i8* @llvm.ptrmask.p0i8.i32(i8* %src, i32 10000)
+  ret i8* %ptr
+}




More information about the llvm-commits mailing list