Skip to content

Commit 9cdec25

Browse files
authored
Merge pull request #23564 from JuliaLang/kf/gcmemcpy
Don't ignore memcpy in GC root placement
2 parents f4edae1 + 3c68dcd commit 9cdec25

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/llvm-late-gc-lowering.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,8 +729,16 @@ State LateLowerGCFrame::LocalScan(Function &F) {
729729
Instruction &I = *it;
730730
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
731731
if (isa<IntrinsicInst>(CI)) {
732-
// Intrinsics are never GC uses/defs
733-
continue;
732+
// Most intrinsics are not gc uses/defs, however some have
733+
// memory operands and could thus be GC uses. To be conservative,
734+
// we only skip processing for those that we know we emit often
735+
// and cannot possibly be GC uses.
736+
IntrinsicInst *II = cast<IntrinsicInst>(CI);
737+
if (isa<DbgInfoIntrinsic>(CI) ||
738+
II->getIntrinsicID() == Intrinsic::lifetime_start ||
739+
II->getIntrinsicID() == Intrinsic::lifetime_end) {
740+
continue;
741+
}
734742
}
735743
MaybeNoteDef(S, BBS, CI, BBS.Safepoints);
736744
NoteOperandUses(S, BBS, I, BBS.UpExposedUses);
@@ -744,6 +752,10 @@ State LateLowerGCFrame::LocalScan(Function &F) {
744752
if (CI->canReturnTwice()) {
745753
S.ReturnsTwice.push_back(CI);
746754
}
755+
if (isa<IntrinsicInst>(CI)) {
756+
// Intrinsics are never safepoints.
757+
continue;
758+
}
747759
if (auto callee = CI->getCalledFunction()) {
748760
// Known functions emitted in codegen that are not safepoints
749761
if (callee == pointer_from_objref_func || callee->getName() == "memcmp") {

test/llvmpasses/gcroots.ll

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ define %jl_value_t addrspace(10)* @no_redundant_rerooting(i64 %a, i1 %cond) {
192192
top:
193193
%ptls = call %jl_value_t*** @jl_get_ptls_states()
194194
%aboxed = call %jl_value_t addrspace(10)* @jl_box_int64(i64 signext %a)
195-
; CHECK: store %jl_value_t addrspace(10)* %aboxed
195+
; CHECK: store %jl_value_t addrspace(10)* %aboxed
196196
; CHECK-NEXT: call void @jl_safepoint()
197197
call void @jl_safepoint()
198198
br i1 %cond, label %blocka, label %blockb
@@ -207,3 +207,19 @@ blockb:
207207
call void @jl_safepoint()
208208
ret %jl_value_t addrspace(10)* %aboxed
209209
}
210+
211+
declare void @llvm.memcpy.p064.p10i8.i64(i64*, i8 addrspace(10)*, i64, i32, i1)
212+
213+
define void @memcpy_use(i64 %a, i64 *%aptr) {
214+
; CHECK-LABEL: @memcpy_use
215+
; CHECK: %gcframe = alloca %jl_value_t addrspace(10)*, i32 3
216+
top:
217+
%ptls = call %jl_value_t*** @jl_get_ptls_states()
218+
%aboxed = call %jl_value_t addrspace(10)* @jl_box_int64(i64 signext %a)
219+
; CHECK: store %jl_value_t addrspace(10)* %aboxed
220+
call void @jl_safepoint()
221+
%acast = bitcast %jl_value_t addrspace(10)* %aboxed to i8 addrspace(10)*
222+
call void @llvm.memcpy.p064.p10i8.i64(i64* %aptr, i8 addrspace(10)* %acast, i64 8, i32 1, i1 false)
223+
ret void
224+
}
225+

0 commit comments

Comments
 (0)