Skip to content

Commit 3dc498e

Browse files
vtjnashKristofferC
authored andcommitted
[GCLowering] correctly handle GC.preserve for demoted objects (#34241)
1 parent e10b320 commit 3dc498e

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

src/codegen.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4317,20 +4317,22 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval)
43174317
for (size_t i = 0; i < nargs; ++i) {
43184318
argv[i] = emit_expr(ctx, args[i]);
43194319
}
4320-
size_t nargsboxed = 0;
4321-
Value **vals = (Value**)alloca(sizeof(Value *) * nargs);
4320+
std::vector<Value*> vals;
43224321
for (size_t i = 0; i < nargs; ++i) {
4323-
if (!argv[i].isboxed) {
4324-
// This is intentionally not an error to allow writing
4325-
// generic code more easily.
4326-
continue;
4327-
} else if (argv[i].constant) {
4322+
const jl_cgval_t &ai = argv[i];
4323+
if (ai.constant)
43284324
continue;
4325+
if (ai.isboxed) {
4326+
vals.push_back(ai.Vboxed);
4327+
}
4328+
else if (!jl_is_pointerfree(ai.typ)) {
4329+
Type *at = julia_type_to_llvm(ai.typ);
4330+
vals.push_back(emit_unbox(ctx, at, ai, ai.typ));
43294331
}
4330-
vals[nargsboxed++] = argv[i].Vboxed;
43314332
}
4332-
Value *token = ctx.builder.CreateCall(prepare_call(gc_preserve_begin_func),
4333-
ArrayRef<Value*>(vals, nargsboxed));
4333+
Value *token = vals.empty()
4334+
? (Value*)ConstantTokenNone::get(jl_LLVMContext)
4335+
: ctx.builder.CreateCall(prepare_call(gc_preserve_begin_func), vals);
43344336
jl_cgval_t tok(token, NULL, false, (jl_value_t*)jl_void_type, NULL);
43354337
return tok;
43364338
}
@@ -4343,7 +4345,8 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval)
43434345
}
43444346
jl_cgval_t token = emit_expr(ctx, args[0]);
43454347
assert(token.V->getType()->isTokenTy());
4346-
ctx.builder.CreateCall(prepare_call(gc_preserve_end_func), {token.V});
4348+
if (!isa<ConstantTokenNone>(token.V))
4349+
ctx.builder.CreateCall(prepare_call(gc_preserve_end_func), {token.V});
43474350
return jl_cgval_t((jl_value_t*)jl_void_type);
43484351
}
43494352
else {

src/llvm-late-gc-lowering.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,9 +1340,21 @@ State LateLowerGCFrame::LocalScan(Function &F) {
13401340
Value *V = U;
13411341
if (isa<Constant>(V))
13421342
continue;
1343-
int Num = Number(S, V);
1344-
if (Num >= 0)
1345-
args.push_back(Num);
1343+
if (isa<PointerType>(V->getType())) {
1344+
if (isSpecialPtr(V->getType())) {
1345+
int Num = Number(S, V);
1346+
if (Num >= 0)
1347+
args.push_back(Num);
1348+
}
1349+
} else {
1350+
std::vector<int> Nums = NumberAll(S, V);
1351+
for (int Num : Nums) {
1352+
if (Num < 0)
1353+
continue;
1354+
if (Num >= 0)
1355+
args.push_back(Num);
1356+
}
1357+
}
13461358
}
13471359
S.GCPreserves[CI] = args;
13481360
continue;

test/llvmpasses/gcroots.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,30 @@ top:
288288
ret void
289289
}
290290

291+
define void @gc_preserve_vec([2 x <2 x %jl_value_t addrspace(10)*>] addrspace(11)* nocapture nonnull readonly dereferenceable(16)) {
292+
; CHECK-LABEL: @gc_preserve_vec
293+
; CHECK: %gcframe = alloca %jl_value_t addrspace(10)*, i32 6
294+
top:
295+
%ptls = call %jl_value_t*** @julia.ptls_states()
296+
%v = load [2 x <2 x %jl_value_t addrspace(10)*>], [2 x <2 x %jl_value_t addrspace(10)*>] addrspace(11)* %0, align 8
297+
; CHECK-DAG: [[EXTRACT11:%.*]] = extractvalue [2 x <2 x %jl_value_t addrspace(10)*>] %v, 0
298+
; CHECK-DAG: [[EXTRACT12:%.*]] = extractvalue [2 x <2 x %jl_value_t addrspace(10)*>] %v, 0
299+
; CHECK-DAG: [[EXTRACT21:%.*]] = extractvalue [2 x <2 x %jl_value_t addrspace(10)*>] %v, 1
300+
; CHECK-DAG: [[EXTRACT22:%.*]] = extractvalue [2 x <2 x %jl_value_t addrspace(10)*>] %v, 1
301+
; CHECK-DAG: [[V11:%.*]] = extractelement <2 x %jl_value_t addrspace(10)*> [[EXTRACT11]], i32 0
302+
; CHECK-DAG: [[V12:%.*]] = extractelement <2 x %jl_value_t addrspace(10)*> [[EXTRACT12]], i32 1
303+
; CHECK-DAG: [[V21:%.*]] = extractelement <2 x %jl_value_t addrspace(10)*> [[EXTRACT21]], i32 0
304+
; CHECK-DAG: [[V22:%.*]] = extractelement <2 x %jl_value_t addrspace(10)*> [[EXTRACT22]], i32 1
305+
; CHECK-DAG: store %jl_value_t addrspace(10)* [[V11]]
306+
; CHECK-DAG: store %jl_value_t addrspace(10)* [[V12]]
307+
; CHECK-DAG: store %jl_value_t addrspace(10)* [[V21]]
308+
; CHECK-DAG: store %jl_value_t addrspace(10)* [[V22]]
309+
%tok = call token (...) @llvm.julia.gc_preserve_begin([2 x <2 x %jl_value_t addrspace(10)*>] %v, i64 addrspace(10)* null, %jl_value_t*** %ptls)
310+
call void @jl_safepoint()
311+
ret void
312+
}
313+
314+
291315
@gv1 = external global %jl_value_t*
292316
@gv2 = external global %jl_value_t addrspace(10)*
293317

0 commit comments

Comments
 (0)