Skip to content

Commit 81afdbc

Browse files
authored
codegen: remove UB from uninitialized bitstypes in new (#52169)
In the time since the creation of issue #26764, there _is_ now 'a way to say to llvm "I don't care what this value is, but it always has to be the same"' using the `freeze` instruction, so we can use that to instruct LLVM to not give us undefined behavior when users are using uninitialized memory. There should not be an impact if users were already avoiding this paradigm and are fully initializing their structs. Fixes #26764
1 parent 625bbde commit 81afdbc

9 files changed

+125
-33
lines changed

src/ccall.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -1003,8 +1003,9 @@ static Value *box_ccall_result(jl_codectx_t &ctx, Value *result, Value *runtime_
10031003
// XXX: need to handle parameterized zero-byte types (singleton)
10041004
const DataLayout &DL = ctx.builder.GetInsertBlock()->getModule()->getDataLayout();
10051005
unsigned nb = DL.getTypeStoreSize(result->getType());
1006+
unsigned align = sizeof(void*); // Allocations are at least pointer aligned
10061007
MDNode *tbaa = jl_is_mutable(rt) ? ctx.tbaa().tbaa_mutab : ctx.tbaa().tbaa_immut;
1007-
Value *strct = emit_allocobj(ctx, nb, runtime_dt);
1008+
Value *strct = emit_allocobj(ctx, nb, runtime_dt, true, align);
10081009
setName(ctx.emission_context, strct, "ccall_result_box");
10091010
init_bits_value(ctx, strct, result, tbaa);
10101011
return strct;
@@ -1383,6 +1384,10 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
13831384
assert(i < nccallargs && i + fc_args_start <= nargs);
13841385
jl_value_t *argi = args[fc_args_start + i];
13851386
argv[i] = emit_expr(ctx, argi);
1387+
if (argv[i].typ == jl_bottom_type) {
1388+
JL_GC_POP();
1389+
return jl_cgval_t();
1390+
}
13861391
}
13871392

13881393
// emit roots
@@ -1984,7 +1989,7 @@ jl_cgval_t function_sig_t::emit_a_ccall(
19841989
// XXX: result needs to be zero'd and given a GC root here
19851990
// and has incorrect write barriers.
19861991
// instead this code path should behave like `unsafe_load`
1987-
result = emit_allocobj(ctx, (jl_datatype_t*)rt);
1992+
result = emit_allocobj(ctx, (jl_datatype_t*)rt, true);
19881993
setName(ctx.emission_context, result, "ccall_sret_box");
19891994
sretty = ctx.types().T_jlvalue;
19901995
sretboxed = true;
@@ -2141,7 +2146,7 @@ jl_cgval_t function_sig_t::emit_a_ccall(
21412146
else if (jlretboxed && !retboxed) {
21422147
assert(jl_is_datatype(rt));
21432148
if (static_rt) {
2144-
Value *strct = emit_allocobj(ctx, (jl_datatype_t*)rt);
2149+
Value *strct = emit_allocobj(ctx, (jl_datatype_t*)rt, true);
21452150
setName(ctx.emission_context, strct, "ccall_ret_box");
21462151
MDNode *tbaa = jl_is_mutable(rt) ? ctx.tbaa().tbaa_mutab : ctx.tbaa().tbaa_immut;
21472152
int boxalign = julia_alignment(rt);

src/cgutils.cpp

+25-14
Original file line numberDiff line numberDiff line change
@@ -2896,7 +2896,7 @@ static Value *emit_genericmemoryowner(jl_codectx_t &ctx, Value *t)
28962896

28972897
// --- boxing ---
28982898

2899-
static Value *emit_allocobj(jl_codectx_t &ctx, jl_datatype_t *jt);
2899+
static Value *emit_allocobj(jl_codectx_t &ctx, jl_datatype_t *jt, bool fully_initialized);
29002900

29012901
static void init_bits_value(jl_codectx_t &ctx, Value *newv, Value *v, MDNode *tbaa,
29022902
unsigned alignment = sizeof(void*)) // min alignment in julia's gc is pointer-aligned
@@ -3206,7 +3206,7 @@ static Value *box_union(jl_codectx_t &ctx, const jl_cgval_t &vinfo, const SmallB
32063206
jl_cgval_t vinfo_r = jl_cgval_t(vinfo, (jl_value_t*)jt, NULL);
32073207
box = _boxed_special(ctx, vinfo_r, t);
32083208
if (!box) {
3209-
box = emit_allocobj(ctx, jt);
3209+
box = emit_allocobj(ctx, jt, true);
32103210
setName(ctx.emission_context, box, "unionbox");
32113211
init_bits_cgval(ctx, box, vinfo_r, jl_is_mutable(jt) ? ctx.tbaa().tbaa_mutab : ctx.tbaa().tbaa_immut);
32123212
}
@@ -3333,7 +3333,7 @@ static Value *boxed(jl_codectx_t &ctx, const jl_cgval_t &vinfo, bool is_promotab
33333333
if (do_promote && is_promotable) {
33343334
auto IP = ctx.builder.saveIP();
33353335
ctx.builder.SetInsertPoint(vinfo.promotion_point);
3336-
box = emit_allocobj(ctx, (jl_datatype_t*)jt);
3336+
box = emit_allocobj(ctx, (jl_datatype_t*)jt, true);
33373337
Value *decayed = decay_derived(ctx, box);
33383338
AllocaInst *originalAlloca = cast<AllocaInst>(vinfo.V);
33393339
box->takeName(originalAlloca);
@@ -3349,7 +3349,7 @@ static Value *boxed(jl_codectx_t &ctx, const jl_cgval_t &vinfo, bool is_promotab
33493349
auto arg_typename = [&] JL_NOTSAFEPOINT {
33503350
return "box::" + std::string(jl_symbol_name(((jl_datatype_t*)(jt))->name->name));
33513351
};
3352-
box = emit_allocobj(ctx, (jl_datatype_t*)jt);
3352+
box = emit_allocobj(ctx, (jl_datatype_t*)jt, true);
33533353
setName(ctx.emission_context, box, arg_typename);
33543354
init_bits_cgval(ctx, box, vinfo, jl_is_mutable(jt) ? ctx.tbaa().tbaa_mutab : ctx.tbaa().tbaa_immut);
33553355
}
@@ -3478,23 +3478,27 @@ static void emit_cpointercheck(jl_codectx_t &ctx, const jl_cgval_t &x, const Twi
34783478
// allocation for known size object
34793479
// returns a prjlvalue
34803480
static Value *emit_allocobj(jl_codectx_t &ctx, size_t static_size, Value *jt,
3481-
unsigned align=sizeof(void*)) // Allocations are at least pointer alingned
3481+
bool fully_initialized, unsigned align)
34823482
{
34833483
++EmittedAllocObjs;
34843484
Value *current_task = get_current_task(ctx);
34853485
Function *F = prepare_call(jl_alloc_obj_func);
34863486
auto call = ctx.builder.CreateCall(F, {current_task, ConstantInt::get(ctx.types().T_size, static_size), maybe_decay_untracked(ctx, jt)});
34873487
call->setAttributes(F->getAttributes());
34883488
if (static_size > 0)
3489-
call->addRetAttr(Attribute::getWithDereferenceableBytes(ctx.builder.getContext(), static_size));
3490-
call->addRetAttr(Attribute::getWithAlignment(ctx.builder.getContext(), Align(align)));
3489+
call->addRetAttr(Attribute::getWithDereferenceableBytes(call->getContext(), static_size));
3490+
call->addRetAttr(Attribute::getWithAlignment(call->getContext(), Align(align)));
3491+
#if JL_LLVM_VERSION >= 150000
3492+
if (fully_initialized)
3493+
call->addFnAttr(Attribute::get(call->getContext(), Attribute::AllocKind, uint64_t(AllocFnKind::Alloc | AllocFnKind::Uninitialized)));
3494+
#endif
34913495
return call;
34923496
}
34933497

3494-
static Value *emit_allocobj(jl_codectx_t &ctx, jl_datatype_t *jt)
3498+
static Value *emit_allocobj(jl_codectx_t &ctx, jl_datatype_t *jt, bool fully_initialized)
34953499
{
34963500
return emit_allocobj(ctx, jl_datatype_size(jt), ctx.builder.CreateIntToPtr(emit_tagfrom(ctx, jt), ctx.types().T_pjlvalue),
3497-
julia_alignment((jl_value_t*)jt));
3501+
fully_initialized, julia_alignment((jl_value_t*)jt));
34983502
}
34993503

35003504
// allocation for unknown object from an untracked pointer
@@ -3716,14 +3720,20 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
37163720
strct = NULL;
37173721
}
37183722
else if (init_as_value) {
3719-
if (tracked.count)
3723+
if (tracked.count) {
37203724
strct = Constant::getNullValue(lt);
3721-
else
3725+
}
3726+
else {
37223727
strct = UndefValue::get(lt);
3728+
if (nargs < nf)
3729+
strct = ctx.builder.CreateFreeze(strct);
3730+
}
37233731
}
37243732
else {
37253733
strct = emit_static_alloca(ctx, lt);
37263734
setName(ctx.emission_context, strct, arg_typename);
3735+
if (nargs < nf)
3736+
ctx.builder.CreateStore(ctx.builder.CreateFreeze(UndefValue::get(lt)), strct);
37273737
if (tracked.count)
37283738
undef_derived_strct(ctx, strct, sty, ctx.tbaa().tbaa_stack);
37293739
}
@@ -3893,7 +3903,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
38933903
return ret;
38943904
}
38953905
}
3896-
Value *strct = emit_allocobj(ctx, sty);
3906+
Value *strct = emit_allocobj(ctx, sty, nargs >= nf);
38973907
setName(ctx.emission_context, strct, arg_typename);
38983908
jl_cgval_t strctinfo = mark_julia_type(ctx, strct, true, ty);
38993909
strct = decay_derived(ctx, strct);
@@ -3926,13 +3936,14 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
39263936
return strctinfo;
39273937
}
39283938
else {
3929-
// 0 fields, ghost or bitstype
3939+
// 0 fields, ghost or primitive type
39303940
if (jl_datatype_nbits(sty) == 0)
39313941
return ghostValue(ctx, sty);
3942+
// n.b. this is not valid IR form to construct a primitive type (use bitcast for example)
39323943
bool isboxed;
39333944
Type *lt = julia_type_to_llvm(ctx, ty, &isboxed);
39343945
assert(!isboxed);
3935-
return mark_julia_type(ctx, UndefValue::get(lt), false, ty);
3946+
return mark_julia_type(ctx, ctx.builder.CreateFreeze(UndefValue::get(lt)), false, ty);
39363947
}
39373948
}
39383949

src/codegen.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ static const auto jl_alloc_obj_func = new JuliaFunction<TypeFnContextAndSizeT>{
10521052
auto FnAttrs = AttrBuilder(C);
10531053
FnAttrs.addAllocSizeAttr(1, None); // returns %1 bytes
10541054
#if JL_LLVM_VERSION >= 150000
1055-
FnAttrs.addAllocKindAttr(AllocFnKind::Alloc | AllocFnKind::Uninitialized);
1055+
FnAttrs.addAllocKindAttr(AllocFnKind::Alloc);
10561056
#endif
10571057
#if JL_LLVM_VERSION >= 160000
10581058
FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref) | inaccessibleMemOnly(ModRefInfo::ModRef));
@@ -5217,7 +5217,7 @@ static void emit_vi_assignment_unboxed(jl_codectx_t &ctx, jl_varinfo_t &vi, Valu
52175217
}
52185218
else {
52195219
Value *dest = vi.value.V;
5220-
if (vi.pTIndex)
5220+
if (vi.pTIndex) // TODO: use lifetime-end here instead
52215221
ctx.builder.CreateStore(UndefValue::get(cast<AllocaInst>(vi.value.V)->getAllocatedType()), vi.value.V);
52225222
Type *store_ty = julia_type_to_llvm(ctx, rval_info.constant ? jl_typeof(rval_info.constant) : rval_info.typ);
52235223
Type *dest_ty = store_ty->getPointerTo();
@@ -7018,7 +7018,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con
70187018
outboxed = (output_type != (jl_value_t*)jl_voidpointer_type);
70197019
if (outboxed) {
70207020
assert(jl_datatype_size(output_type) == sizeof(void*) * 4);
7021-
Value *strct = emit_allocobj(ctx, (jl_datatype_t*)output_type);
7021+
Value *strct = emit_allocobj(ctx, (jl_datatype_t*)output_type, true);
70227022
setName(ctx.emission_context, strct, "cfun_result");
70237023
Value *derived_strct = emit_bitcast(ctx, decay_derived(ctx, strct), ctx.types().T_size->getPointerTo());
70247024
MDNode *tbaa = best_tbaa(ctx.tbaa(), output_type);
@@ -7194,7 +7194,7 @@ static Function *gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlret
71947194
if (!lty->isAggregateType()) // keep "aggregate" type values in place as pointers
71957195
theArg = ctx.builder.CreateAlignedLoad(lty, theArg, Align(julia_alignment(ty)));
71967196
}
7197-
assert(dyn_cast<UndefValue>(theArg) == NULL);
7197+
assert(!isa<UndefValue>(theArg));
71987198
args[idx] = theArg;
71997199
idx++;
72007200
}
@@ -8962,6 +8962,7 @@ static jl_llvm_functions_t
89628962
}
89638963

89648964
for (PHINode *PN : ToDelete) {
8965+
// This basic block is statically unreachable, thus so is this PHINode
89658966
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
89668967
PN->eraseFromParent();
89678968
}

src/intrinsics.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,8 @@ static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv)
639639
return mark_julia_type(ctx, vx, false, bt);
640640
}
641641
else {
642-
Value *box = emit_allocobj(ctx, nb, bt_value_rt);
642+
unsigned align = sizeof(void*); // Allocations are at least pointer aligned
643+
Value *box = emit_allocobj(ctx, nb, bt_value_rt, true, align);
643644
setName(ctx.emission_context, box, "bitcast_box");
644645
init_bits_value(ctx, box, vx, ctx.tbaa().tbaa_immut);
645646
return mark_julia_type(ctx, box, true, bt->name->wrapper);
@@ -698,7 +699,8 @@ static jl_cgval_t generic_cast(
698699
else {
699700
Value *targ_rt = boxed(ctx, targ);
700701
emit_concretecheck(ctx, targ_rt, std::string(jl_intrinsic_name(f)) + ": target type not a leaf primitive type");
701-
Value *box = emit_allocobj(ctx, nb, targ_rt);
702+
unsigned align = sizeof(void*); // Allocations are at least pointer aligned
703+
Value *box = emit_allocobj(ctx, nb, targ_rt, true, align);
702704
setName(ctx.emission_context, box, "cast_box");
703705
init_bits_value(ctx, box, ans, ctx.tbaa().tbaa_immut);
704706
return mark_julia_type(ctx, box, true, jlto->name->wrapper);
@@ -749,7 +751,7 @@ static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
749751
else if (!deserves_stack(ety)) {
750752
assert(jl_is_datatype(ety));
751753
uint64_t size = jl_datatype_size(ety);
752-
Value *strct = emit_allocobj(ctx, (jl_datatype_t*)ety);
754+
Value *strct = emit_allocobj(ctx, (jl_datatype_t*)ety, true);
753755
setName(ctx.emission_context, strct, "pointerref_box");
754756
im1 = ctx.builder.CreateMul(im1, ConstantInt::get(ctx.types().T_size,
755757
LLT_ALIGN(size, jl_datatype_align(ety))));
@@ -905,7 +907,7 @@ static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
905907

906908
if (!deserves_stack(ety)) {
907909
assert(jl_is_datatype(ety));
908-
Value *strct = emit_allocobj(ctx, (jl_datatype_t*)ety);
910+
Value *strct = emit_allocobj(ctx, (jl_datatype_t*)ety, true);
909911
setName(ctx.emission_context, strct, "atomic_pointerref_box");
910912
Value *thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
911913
Type *loadT = Type::getIntNTy(ctx.builder.getContext(), nb * 8);

src/llvm-alloc-helpers.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ JL_USED_FUNC void AllocUseInfo::dump(llvm::raw_ostream &OS)
125125
OS << "hastypeof: " << hastypeof << '\n';
126126
OS << "refload: " << refload << '\n';
127127
OS << "refstore: " << refstore << '\n';
128+
OS << "allockind:";
129+
if ((allockind & AllocFnKind::Uninitialized) != AllocFnKind::Unknown)
130+
OS << " uninitialized";
131+
if ((allockind & AllocFnKind::Zeroed) != AllocFnKind::Unknown)
132+
OS << " zeroed";
133+
OS << '\n';
128134
OS << "Uses: " << uses.size() << '\n';
129135
for (auto inst: uses)
130136
inst->print(OS);
@@ -164,8 +170,11 @@ JL_USED_FUNC void AllocUseInfo::dump()
164170
#define REMARK(remark)
165171
#endif
166172

167-
void jl_alloc::runEscapeAnalysis(llvm::Instruction *I, EscapeAnalysisRequiredArgs required, EscapeAnalysisOptionalArgs options) {
173+
void jl_alloc::runEscapeAnalysis(llvm::CallInst *I, EscapeAnalysisRequiredArgs required, EscapeAnalysisOptionalArgs options) {
168174
required.use_info.reset();
175+
Attribute allockind = I->getFnAttr(Attribute::AllocKind);
176+
if (allockind.isValid())
177+
required.use_info.allockind = allockind.getAllocKind();
169178
if (I->use_empty())
170179
return;
171180
CheckInst::Frame cur{I, 0, I->use_begin(), I->use_end()};

src/llvm-alloc-helpers.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ namespace jl_alloc {
8787
bool returned:1;
8888
// The object is used in an error function
8989
bool haserror:1;
90+
// For checking attributes of "uninitialized" or "zeroed" or unknown
91+
llvm::AllocFnKind allockind;
9092

9193
// The alloc has a Julia object reference not in an explicit field.
9294
bool has_unknown_objref:1;
@@ -105,6 +107,7 @@ namespace jl_alloc {
105107
hasunknownmem = false;
106108
returned = false;
107109
haserror = false;
110+
allockind = llvm::AllocFnKind::Unknown;
108111
has_unknown_objref = false;
109112
has_unknown_objrefaggr = false;
110113
uses.clear();
@@ -153,7 +156,7 @@ namespace jl_alloc {
153156
}
154157
};
155158

156-
void runEscapeAnalysis(llvm::Instruction *I, EscapeAnalysisRequiredArgs required, EscapeAnalysisOptionalArgs options=EscapeAnalysisOptionalArgs());
159+
void runEscapeAnalysis(llvm::CallInst *I, EscapeAnalysisRequiredArgs required, EscapeAnalysisOptionalArgs options=EscapeAnalysisOptionalArgs());
157160
}
158161

159162

src/llvm-alloc-opt.cpp

+28-5
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,13 @@ struct Optimizer {
135135
// insert llvm.lifetime.* calls for `ptr` with size `sz` based on the use of `orig`.
136136
void insertLifetime(Value *ptr, Constant *sz, Instruction *orig);
137137

138-
void checkInst(Instruction *I);
138+
void checkInst(CallInst *I);
139139

140140
void replaceIntrinsicUseWith(IntrinsicInst *call, Intrinsic::ID ID,
141141
Instruction *orig_i, Instruction *new_i);
142142
void removeAlloc(CallInst *orig_inst);
143-
void moveToStack(CallInst *orig_inst, size_t sz, bool has_ref);
143+
void moveToStack(CallInst *orig_inst, size_t sz, bool has_ref, AllocFnKind allockind);
144+
void initializeAlloca(IRBuilder<> &prolog_builder, AllocaInst *buff, AllocFnKind allockind);
144145
void splitOnStack(CallInst *orig_inst);
145146
void optimizeTag(CallInst *orig_inst);
146147

@@ -288,7 +289,7 @@ void Optimizer::optimizeAll()
288289
<< "GC allocation moved to stack " << ore::NV("GC Allocation", orig);
289290
});
290291
// The object has no fields with mix reference access
291-
moveToStack(orig, sz, has_ref);
292+
moveToStack(orig, sz, has_ref, use_info.allockind);
292293
}
293294
}
294295

@@ -355,7 +356,7 @@ ssize_t Optimizer::getGCAllocSize(Instruction *I)
355356
return -1;
356357
}
357358

358-
void Optimizer::checkInst(Instruction *I)
359+
void Optimizer::checkInst(CallInst *I)
359360
{
360361
LLVM_DEBUG(dbgs() << "Running escape analysis on " << *I << "\n");
361362
jl_alloc::EscapeAnalysisRequiredArgs required{use_info, check_stack, pass, *pass.DL};
@@ -598,9 +599,25 @@ void Optimizer::replaceIntrinsicUseWith(IntrinsicInst *call, Intrinsic::ID ID,
598599
call->eraseFromParent();
599600
}
600601

602+
void Optimizer::initializeAlloca(IRBuilder<> &prolog_builder, AllocaInst *buff, AllocFnKind allockind)
603+
{
604+
if ((allockind & AllocFnKind::Uninitialized) != AllocFnKind::Unknown)
605+
return;
606+
assert(!buff->isArrayAllocation());
607+
Type *T = buff->getAllocatedType();
608+
Value *Init = UndefValue::get(T);
609+
if ((allockind & AllocFnKind::Zeroed) != AllocFnKind::Unknown)
610+
Init = Constant::getNullValue(T); // zero, as described
611+
else if (allockind == AllocFnKind::Unknown)
612+
Init = Constant::getNullValue(T); // assume zeroed since we didn't find the attribute
613+
else
614+
Init = prolog_builder.CreateFreeze(UndefValue::get(T)); // assume freeze, since LLVM does not natively support this case
615+
prolog_builder.CreateStore(Init, buff);
616+
}
617+
601618
// This function should not erase any safepoint so that the lifetime marker can find and cache
602619
// all the original safepoints.
603-
void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref)
620+
void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref, AllocFnKind allockind)
604621
{
605622
++RemovedAllocs;
606623
++StackAllocs;
@@ -643,6 +660,10 @@ void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref)
643660
ptr = cast<Instruction>(prolog_builder.CreateBitCast(buff, Type::getInt8PtrTy(prolog_builder.getContext(), buff->getType()->getPointerAddressSpace())));
644661
}
645662
insertLifetime(ptr, ConstantInt::get(Type::getInt64Ty(prolog_builder.getContext()), sz), orig_inst);
663+
if (sz != 0 && !has_ref) { // TODO: fix has_ref case too
664+
IRBuilder<> builder(orig_inst);
665+
initializeAlloca(builder, buff, allockind);
666+
}
646667
Instruction *new_inst = cast<Instruction>(prolog_builder.CreateBitCast(ptr, JuliaType::get_pjlvalue_ty(prolog_builder.getContext(), buff->getType()->getPointerAddressSpace())));
647668
new_inst->takeName(orig_inst);
648669

@@ -927,8 +948,10 @@ void Optimizer::splitOnStack(CallInst *orig_inst)
927948
allocty = ArrayType::get(Type::getInt8Ty(pass.getLLVMContext()), field.size);
928949
}
929950
slot.slot = prolog_builder.CreateAlloca(allocty);
951+
IRBuilder<> builder(orig_inst);
930952
insertLifetime(prolog_builder.CreateBitCast(slot.slot, Type::getInt8PtrTy(prolog_builder.getContext())),
931953
ConstantInt::get(Type::getInt64Ty(prolog_builder.getContext()), field.size), orig_inst);
954+
initializeAlloca(builder, slot.slot, use_info.allockind);
932955
slots.push_back(std::move(slot));
933956
}
934957
const auto nslots = slots.size();

src/llvm-pass-helpers.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ namespace jl_intrinsics {
130130
#if JL_LLVM_VERSION >= 160000
131131
FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref) | inaccessibleMemOnly(ModRefInfo::ModRef));
132132
#endif
133-
FnAttrs.addAllocKindAttr(AllocFnKind::Alloc | AllocFnKind::Uninitialized);
133+
FnAttrs.addAllocKindAttr(AllocFnKind::Alloc);
134134
FnAttrs.addAttribute(Attribute::WillReturn);
135135
FnAttrs.addAttribute(Attribute::NoUnwind);
136136
target->addFnAttrs(FnAttrs);

0 commit comments

Comments
 (0)