Skip to content

Commit d3cf221

Browse files
committed
[IRGen] Lowered tuple_pack_element_addr.
1 parent 2ebff4d commit d3cf221

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

lib/IRGen/GenTuple.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -509,14 +509,12 @@ Address irgen::projectTupleElementAddressByDynamicIndex(IRGenFunction &IGF,
509509
SILType tupleType,
510510
llvm::Value *index,
511511
SILType elementType) {
512-
// TODO: retrieve type metadata (ForLayout) for the tuple type
513-
// and retrieve the field offset for the given index. Consider
514-
// special-casing constant indices if we can reason statically
515-
// about the prior elements. It's probably not necessary to try
516-
// to handle fixed-size tuples specially, because the optimizer
517-
// should ideally be lowering this operation to something static
518-
// in that case.
519-
llvm_unreachable("unimplemented");
512+
auto *metadata = IGF.emitTypeMetadataRefForLayout(tupleType);
513+
514+
llvm::Value *offset = loadTupleOffsetFromMetadata(IGF, metadata, index);
515+
auto *gep =
516+
IGF.emitByteOffsetGEP(tuple.getAddress(), offset, IGF.IGM.OpaqueTy);
517+
return Address(gep, IGF.IGM.OpaqueTy, IGF.IGM.getPointerAlignment());
520518
}
521519

522520
Optional<Size> irgen::getFixedTupleElementOffset(IRGenModule &IGM,

test/IRGen/variadic_generics.sil

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,31 @@ bb0(%pack : $*Pack{Int, repeat each T, Int}, %value : $Int):
106106
%ret = tuple ()
107107
return %ret : $()
108108
}
109+
110+
sil @blackhole : $<T> (@in T) -> () {
111+
entry(%addr : $*T):
112+
%ret = tuple ()
113+
return %ret : $()
114+
}
115+
116+
// CHECK-LABEL: define swiftcc void @test_tuple_pack_element_addr_1(
117+
// CHECK-SAME: {{.*}}* nocapture [[TUPLE_ADDR:%[^,]+]], i{{(64|32)}} [[INDEX:%[^,]+]]
118+
// CHECK: [[RESPONSE:%[^,]+]] = call swiftcc %swift.metadata_response @swift_getTupleTypeMetadata
119+
// CHECK: [[UNCAST_METADATA:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
120+
// CHECK: [[METADATA:%[^,]+]] = bitcast %swift.type* [[UNCAST_METADATA]] to %swift.tuple_type*
121+
// CHECK: [[OFFSET_PTR:%[^,]+]] = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* [[METADATA]], i{{(64|32)}} 0, i32 3, i{{(64|32)}} [[INDEX]]
122+
// CHECK: [[OFFSET:%[^,]+]] = load i32, i32* [[OFFSET_PTR]], align 8
123+
// CHECK: [[CAST_TUPLE_ADDR:%[^,]+]] = bitcast <{ %TSS }>* [[TUPLE_ADDR]] to i8*
124+
// CHECK: [[UNCAST_ELEMENT_ADDR:%[^,]+]] = getelementptr inbounds i8, i8* [[CAST_TUPLE_ADDR]], i32 [[OFFSET]]
125+
// CHECK: [[ELEMENT_ADDR:%[^,]+]] = bitcast i8* [[UNCAST_ELEMENT_ADDR]] to %swift.opaque*
126+
// CHECK: call swiftcc void @blackhole(%swift.opaque* noalias nocapture [[ELEMENT_ADDR]], %swift.type* %"\CF\84_1_0")
127+
sil @test_tuple_pack_element_addr_1 : $<T, U> (@inout (String, T, U, Int), Builtin.Word) -> () {
128+
bb0(%tuple : $*(String, T, U, Int), %i : $Builtin.Word):
129+
%index = dynamic_pack_index %i of $Pack{Float, T, U, Float}
130+
%0 = open_pack_element %index of <U_1...> at <Pack{String, T, U, Int}>, shape $U_1, uuid "01234567-89AB-CDEF-0123-000000000004"
131+
%elt = tuple_pack_element_addr %index of %tuple : $*(String, T, U, Int) as $*@pack_element("01234567-89AB-CDEF-0123-000000000004") U_1
132+
%blackhole = function_ref @blackhole : $@convention(thin) <T> (@in T) -> ()
133+
apply %blackhole<(@pack_element("01234567-89AB-CDEF-0123-000000000004") U_1)>(%elt) : $@convention(thin) <T> (@in T) -> ()
134+
%ret = tuple ()
135+
return %ret : $()
136+
}

0 commit comments

Comments
 (0)