Index: llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -476,6 +476,12 @@ if (auto *BC = dyn_cast(I)) return findBaseDefiningValue(BC->getOperand(0)); + // We assume that functions in the source language only return base + // pointers. This should probably be generalized via attributes to support + // both source language and internal functions. + if (isa(I) || isa(I)) + return BaseDefiningValueResult(I, true); + // A PHI or Select is a base defining value. The outer findBasePointer // algorithm is responsible for constructing a base value for this BDV. assert((isa(I) || isa(I)) && Index: llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-vector.ll =================================================================== --- llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-vector.ll +++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-vector.ll @@ -261,3 +261,19 @@ call void @use_vec(<4 x i64 addrspace(1) *> %vec2) ret void } + +declare <4 x i64 addrspace(1)*> @def_vec() "gc-leaf-function" + +define void @test12(<4 x i64 addrspace(1)*> %vec1) gc "statepoint-example" { +; CHECK-LABEL: @test12( +; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf{{.*}}<4 x i64 addrspace(1)*> %vec) +; CHECK-NEXT: %vec.relocated = call coldcc <4 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v4p1i8( +; CHECK-NEXT: %vec.relocated.casted = bitcast <4 x i8 addrspace(1)*> %vec.relocated to <4 x i64 addrspace(1)*> +; CHECK-NEXT: call void @use_vec(<4 x i64 addrspace(1)*> %vec.relocated.casted) +; CHECK-NEXT: ret void +entry: + %vec = call <4 x i64 addrspace(1)*> @def_vec() + call void @do_safepoint() [ "deopt"() ] + call void @use_vec(<4 x i64 addrspace(1)*> %vec) + ret void +} Index: llvm/trunk/test/Transforms/RewriteStatepointsForGC/invokes.ll =================================================================== --- llvm/trunk/test/Transforms/RewriteStatepointsForGC/invokes.ll +++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/invokes.ll @@ -30,6 +30,32 @@ ret i64 addrspace(1)* %obj1 } +declare <4 x i64 addrspace(1)*> @some_vector_call(<4 x i64 addrspace(1)*>) + +define <4 x i64 addrspace(1)*> @test_basic_vector(<4 x i64 addrspace(1)*> %objs, <4 x i64 addrspace(1)*> %objs1) gc "statepoint-example" personality i32 ()* @personality_function { +; CHECK-LABEL: @test_basic_vector +entry: +; CHECK: invoke{{.*}}llvm.experimental.gc.statepoint{{.*}}some_vector_call + %ret_val = invoke <4 x i64 addrspace(1)*> @some_vector_call(<4 x i64 addrspace(1)*> %objs) + to label %normal_return unwind label %exceptional_return + +; CHECK-LABEL: normal_return: +; CHECK: gc.result +; CHECK: ret <4 x i64 addrspace(1)*> + +normal_return: + ret <4 x i64 addrspace(1)*> %ret_val + +; CHECK-LABEL: exceptional_return: +; CHECK: landingpad +; CHECK: ret <4 x i64 addrspace(1)*> + +exceptional_return: + %landing_pad4 = landingpad token + cleanup + ret <4 x i64 addrspace(1)*> %objs1 +} + define i64 addrspace(1)* @test_two_invokes(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality_function { ; CHECK-LABEL: entry: entry: