[PATCH] D103492: [RS4GC] Treat inttoptr as base pointer

Sam Dirkswager via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 1 14:33:17 PDT 2021


tolziplohu created this revision.
tolziplohu added a reviewer: reames.
Herald added subscribers: hiraditya, arichardson.
tolziplohu requested review of this revision.
Herald added a project: LLVM.

Currently, RewriteStatepointsForGC doesn't support the `inttoptr` instruction.
This is a problem, because some optimizations can generate `inttoptr`s; for example, it may inline an `memcpy` followed by a load into an inttoptr.
Before optimization, the result of the load would be treated as a base pointer, but after, it wouldn't accept it.
On a build with assertions, it would crash with an error; on a release build, it would enter an infinite loop.
This patch makes RS4GC treat `inttoptr` instructions as base pointers, so the behavior after optimization is the same as before.

It can also be useful for (semi-)conservative garbage collectors for languages with polymorphism, like OCaml.
Integers may be marked as non-pointers with a high or low set bit, then casted to a GC pointer and passed to a polymorphic function.
After this patch, that's possible to do with just an `inttoptr`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103492

Files:
  llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
  llvm/test/Transforms/RewriteStatepointsForGC/base-inttoptr.ll


Index: llvm/test/Transforms/RewriteStatepointsForGC/base-inttoptr.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/RewriteStatepointsForGC/base-inttoptr.ll
@@ -0,0 +1,13 @@
+; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
+
+; Regression test to make sure RS4GC can handle inttoptr casts, which can be generated by other optimization passes
+; CHECK: test
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @foo()
+
+define i8 addrspace(1)* @test(i64 %i) gc "statepoint-example" {
+    %p = inttoptr i64 %i to i8 addrspace(1)*
+    call void @foo()
+    ret i8 addrspace(1)* %p
+}
Index: llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -529,10 +529,12 @@
     assert(cast<PointerType>(Def->getType())->getAddressSpace() ==
                cast<PointerType>(CI->getType())->getAddressSpace() &&
            "unsupported addrspacecast");
-    // If we find a cast instruction here, it means we've found a cast which is
-    // not simply a pointer cast (i.e. an inttoptr).  We don't know how to
-    // handle int->ptr conversion.
-    assert(!isa<CastInst>(Def) && "shouldn't find another cast here");
+    // If we find an inttoptr, we'll assume that's the base pointer.
+    // Optimization passes can generate inttoptrs from loads from memory,
+    // which we consider base pointers, so we treat inttoptr the same way.
+    if ((CI = dyn_cast<CastInst>(Def)) &&
+        CI->getOpcode() == Instruction::CastOps::IntToPtr)
+      return BaseDefiningValueResult(Def, true);
     return findBaseDefiningValue(Def);
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103492.349099.patch
Type: text/x-patch
Size: 1802 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210601/9f03ad48/attachment.bin>


More information about the llvm-commits mailing list