Skip to content

Commit

Permalink
IRGen: Fix type of a global with tail allocated storage
Browse files Browse the repository at this point in the history
Cast the result to the expected type rather than a special
'..._tailelemsN' type.

rdar://44563038
  • Loading branch information
aschwaighofer committed Sep 19, 2018
1 parent 32fd274 commit 8ccc517
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
6 changes: 5 additions & 1 deletion lib/IRGen/GenDecl.cpp
Expand Up @@ -1739,6 +1739,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
ResilienceExpansion expansion = getResilienceExpansionForLayout(var);

llvm::Type *storageType;
llvm::Type *castStorageToType = nullptr;
Size fixedSize;
Alignment fixedAlignment;
bool inFixedBuffer = false;
Expand Down Expand Up @@ -1768,6 +1769,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
storageType = Layout->getType();
fixedSize = Layout->getSize();
fixedAlignment = Layout->getAlignment();
castStorageToType = cast<FixedTypeInfo>(ti).getStorageType();
assert(fixedAlignment >= TargetInfo.HeapObjectAlignment);
} else if (isREPLVar || ti.isFixedSize(expansion)) {
// Allocate static storage.
Expand Down Expand Up @@ -1863,7 +1865,9 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
// to a reference to it).
addr = llvm::ConstantExpr::getGetElementPtr(nullptr, gvar, Indices);
}
addr = llvm::ConstantExpr::getBitCast(addr, storageType->getPointerTo());
addr = llvm::ConstantExpr::getBitCast(
addr,
castStorageToType ? castStorageToType : storageType->getPointerTo());
return Address(addr, Alignment(gvar->getAlignment()));
}

Expand Down
26 changes: 23 additions & 3 deletions test/IRGen/static_initializer.sil
Expand Up @@ -152,11 +152,31 @@ bb0:
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$S18static_initializer16TestArrayStorageCMa"(i64 0)
// CHECK: [[MD:%[0-9]+]] = extractvalue %swift.metadata_response [[TMP]], 0
// CHECK: [[O:%[0-9a-z]+]] = call %swift.refcounted* @swift_initStaticObject(%swift.type* [[MD]], %swift.refcounted* getelementptr inbounds (%T18static_initializer16TestArrayStorageC_tailelems0c, %T18static_initializer16TestArrayStorageC_tailelems0c* @static_array, i32 0, i32 1, i32 0))
// CHECK: [[R:%[0-9]+]] = bitcast %swift.refcounted* [[O]] to %T18static_initializer16TestArrayStorageC_tailelems0*
// CHECK: [[R2:%[0-9]+]] = bitcast %T18static_initializer16TestArrayStorageC_tailelems0* [[R]] to %T18static_initializer16TestArrayStorageC*
// CHECK: ret %T18static_initializer16TestArrayStorageC* [[R2]]
// CHECK: [[R:%[0-9]+]] = bitcast %swift.refcounted* [[O]] to %T18static_initializer16TestArrayStorageC*
// CHECK: ret %T18static_initializer16TestArrayStorageC* [[R]]
%0 = global_value @static_array : $TestArrayStorage
%1 = struct $TestArray (%0 : $TestArrayStorage)
return %1 : $TestArray
}

// CHECK-LABEL: define swiftcc %T18static_initializer16TestArrayStorageC* @phi_nodes(i1, %T18static_initializer16TestArrayStorageC*)
// CHECK: [[T0:%.*]] = call %swift.refcounted* @swift_initStaticObject
// CHECK: [[T1:%.*]] = bitcast %swift.refcounted* [[T0]] to %T18static_initializer16TestArrayStorageC*
// CHECK: br
// CHECK: br
// CHECK: [[T3:%.*]] = phi %T18static_initializer16TestArrayStorageC* [ %1, {{.*}} ], [ [[T1]], {{.*}} ]
// CHECK: ret %T18static_initializer16TestArrayStorageC* [[T3]]
sil @phi_nodes : $@convention(thin) (Builtin.Int1, TestArrayStorage) -> TestArrayStorage {
bb0(%0 : $Builtin.Int1, %1 : $TestArrayStorage):
cond_br %0, bb1, bb2

bb1:
%2 = global_value @static_array : $TestArrayStorage
br bb3(%2 : $TestArrayStorage)

bb2:
br bb3(%1 : $TestArrayStorage)

bb3(%3 : $TestArrayStorage):
return %3 : $TestArrayStorage
}

0 comments on commit 8ccc517

Please sign in to comment.