Skip to content

Commit 85437a2

Browse files
Merge pull request #71521 from nate-chandler/rdar122417297
[Mem2Reg] When materializing an empty type projected from a non-empty aggregate, populate the non-empty fields of the aggregate with undef.
2 parents a1d70b6 + b4e336e commit 85437a2

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -679,18 +679,18 @@ replaceLoad(SILInstruction *inst, SILValue newValue, AllocStackInst *asi,
679679
}
680680
}
681681

682-
/// Instantiate the specified empty type by recursively tupling and structing
683-
/// the empty types aggregated together at each level.
684-
static SILValue createValueForEmptyType(SILType ty,
685-
SILInstruction *insertionPoint,
686-
SILBuilderContext &ctx) {
682+
/// Instantiate the specified type by recursively tupling and structing the
683+
/// unique instances of the empty types and undef "instances" of the non-empty
684+
/// types aggregated together at each level.
685+
static SILValue createEmptyAndUndefValue(SILType ty,
686+
SILInstruction *insertionPoint,
687+
SILBuilderContext &ctx) {
687688
auto *function = insertionPoint->getFunction();
688-
assert(ty.isEmpty(*function));
689689
if (auto tupleTy = ty.getAs<TupleType>()) {
690690
SmallVector<SILValue, 4> elements;
691691
for (unsigned idx : range(tupleTy->getNumElements())) {
692692
SILType elementTy = ty.getTupleElementType(idx);
693-
auto element = createValueForEmptyType(elementTy, insertionPoint, ctx);
693+
auto element = createEmptyAndUndefValue(elementTy, insertionPoint, ctx);
694694
elements.push_back(element);
695695
}
696696
SILBuilderWithScope builder(insertionPoint, ctx);
@@ -707,15 +707,14 @@ static SILValue createValueForEmptyType(SILType ty,
707707
SmallVector<SILValue, 4> elements;
708708
for (auto *field : decl->getStoredProperties()) {
709709
auto elementTy = ty.getFieldType(field, module, tec);
710-
auto element = createValueForEmptyType(elementTy, insertionPoint, ctx);
710+
auto element = createEmptyAndUndefValue(elementTy, insertionPoint, ctx);
711711
elements.push_back(element);
712712
}
713713
SILBuilderWithScope builder(insertionPoint, ctx);
714714
return builder.createStruct(insertionPoint->getLoc(), ty, elements);
715+
} else {
716+
return SILUndef::get(ty, *insertionPoint->getFunction());
715717
}
716-
llvm::errs() << "Attempting to create value for illegal empty type:\n";
717-
ty.print(llvm::errs());
718-
llvm::report_fatal_error("illegal empty type: neither tuple nor struct.");
719718
}
720719

721720
/// Whether lexical lifetimes should be added for the values stored into the
@@ -1982,7 +1981,7 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
19821981
// empty--an aggregate of types without storage.
19831982
runningVals = {
19841983
LiveValues::toReplace(asi,
1985-
/*replacement=*/createValueForEmptyType(
1984+
/*replacement=*/createEmptyAndUndefValue(
19861985
asi->getElementType(), inst, ctx)),
19871986
/*isStorageValid=*/true};
19881987
}

test/SILOptimizer/mem2reg.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,3 +531,19 @@ sil @dont_canonicalize_undef : $@convention(thin) () -> () {
531531
%retval = tuple ()
532532
return %retval : $()
533533
}
534+
535+
// CHECK-LABEL: sil @undef_for_load_of_empty_type_from_nontrivial_aggregate : {{.*}} {
536+
// CHECK: [[EMPTY:%[^,]+]] = tuple ()
537+
// CHECK: [[AGGREGATE:%[^,]+]] = tuple (undef : $Builtin.BridgeObject, [[EMPTY]] : $())
538+
// CHECK: tuple_extract [[AGGREGATE]] : $(Builtin.BridgeObject, ()), 1
539+
// CHECK-LABEL: } // end sil function 'undef_for_load_of_empty_type_from_nontrivial_aggregate'
540+
sil @undef_for_load_of_empty_type_from_nontrivial_aggregate : $@convention(thin) () -> () {
541+
bb0:
542+
%11 = alloc_stack $(Builtin.BridgeObject, ())
543+
%12 = tuple_element_addr %11 : $*(Builtin.BridgeObject, ()), 1
544+
%13 = load %12 : $*()
545+
%empty = tuple ()
546+
%14 = tuple (%empty : $(), %13 : $())
547+
dealloc_stack %11 : $*(Builtin.BridgeObject, ())
548+
return undef : $()
549+
}

0 commit comments

Comments
 (0)