diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp --- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -529,10 +529,12 @@ assert(cast(Def->getType())->getAddressSpace() == cast(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(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(Def)) && + CI->getOpcode() == Instruction::CastOps::IntToPtr) + return BaseDefiningValueResult(Def, true); return findBaseDefiningValue(Def); } diff --git a/llvm/test/Transforms/RewriteStatepointsForGC/base-inttoptr.ll b/llvm/test/Transforms/RewriteStatepointsForGC/base-inttoptr.ll new file mode 100644 --- /dev/null +++ b/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 +}