Revision d9b2fe601b793741633d77606c4618e63612fbb2 authored by Chris Lattner on 10 January 2016, 04:17:56 UTC, committed by Chris Lattner on 10 January 2016, 04:17:56 UTC
1 parent 0fbbf59
Raw File
existentials.sil
// RUN: %target-swift-frontend %s -emit-ir -disable-objc-interop | FileCheck %s

// REQUIRES: CPU=x86_64

sil_stage canonical

import Swift

protocol CP: class {}

// CHECK-DAG: define { %swift.refcounted*, i8** } @class_existential_unowned(%swift.refcounted*, i8**) {{.*}} {
sil @class_existential_unowned : $@convention(thin) (@owned CP) -> @owned CP {
entry(%s : $CP):
  %u = ref_to_unowned %s : $CP to $@sil_unowned CP
  // CHECK: call void @swift_unownedRetain(%swift.refcounted* %0)
  unowned_retain %u : $@sil_unowned CP
  // CHECK: call void @swift_unownedRelease(%swift.refcounted* %0)
  unowned_release %u : $@sil_unowned CP

  // CHECK: call void @swift_unownedRetainStrong(%swift.refcounted* %0)
  strong_retain_unowned %u : $@sil_unowned CP
  %t = unowned_to_ref %u : $@sil_unowned CP to $CP
  // CHECK: call void @swift_release(%swift.refcounted* %0)
  strong_release %t : $CP

  %v = ref_to_unmanaged %s : $CP to $@sil_unmanaged CP
  %z = unmanaged_to_ref %v : $@sil_unmanaged CP to $CP

  // CHECK: [[RESULT_A:%.*]] = insertvalue { %swift.refcounted*, i8** } undef, %swift.refcounted* %0, 0
  // CHECK: [[RESULT_B:%.*]] = insertvalue { %swift.refcounted*, i8** } [[RESULT_A]], i8** %1, 1
  // CHECK: ret { %swift.refcounted*, i8** } [[RESULT_B]]

  return %z : $CP
}

// CHECK-DAG: define void @class_existential_weak({ %swift.weak, i8** }* noalias nocapture sret, i64, i64)
sil @class_existential_weak : $@convention(thin) (@out @sil_weak CP?, @owned CP?) -> () {
entry(%w : $*@sil_weak CP?, %a : $CP?):
  // CHECK: [[V:%.*]] = alloca { %swift.weak, i8** }
  %v = alloc_stack $@sil_weak CP?

  // CHECK: [[SRC_REF:%.*]] = inttoptr {{.*}} %swift.refcounted*
  // CHECK: [[SRC_WITNESS:%.*]] = inttoptr {{.*}} i8**
  // CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
  // CHECK: store i8** [[SRC_WITNESS]], i8*** [[DEST_WITNESS_ADDR]]
  // CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
  // CHECK: call void @swift_weakInit(%swift.weak* [[DEST_REF_ADDR]], %swift.refcounted* [[SRC_REF]])
  store_weak %a to [initialization] %w : $*@sil_weak CP?

  // CHECK: [[SRC_REF:%.*]] = inttoptr {{.*}} %swift.refcounted*
  // CHECK: [[SRC_WITNESS:%.*]] = inttoptr {{.*}} i8**
  // CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
  // CHECK: store i8** [[SRC_WITNESS]], i8*** [[DEST_WITNESS_ADDR]]
  // CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
  // CHECK: call void @swift_weakAssign(%swift.weak* [[DEST_REF_ADDR]], %swift.refcounted* [[SRC_REF]])
  store_weak %a to                  %w : $*@sil_weak CP?

  // CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
  // CHECK: [[DEST_REF:%.*]] = call %swift.refcounted* @swift_weakTakeStrong(%swift.weak* [[SRC_REF_ADDR]])
  // CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
  // CHECK: [[DEST_WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]]
  %b = load_weak [take] %w : $*@sil_weak CP?

  // CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
  // CHECK: [[DEST_REF:%.*]] = call %swift.refcounted* @swift_weakLoadStrong(%swift.weak* [[SRC_REF_ADDR]])
  // CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
  // CHECK: [[DEST_WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]]
  %c = load_weak        %w : $*@sil_weak CP?

  // CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
  // CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
  // CHECK: call void @swift_weakTakeInit(%swift.weak* [[DEST_REF_ADDR]], %swift.weak* [[SRC_REF_ADDR]])
  // CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
  // CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]], align 8
  // CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 1
  // CHECK: store i8** [[WITNESS]], i8*** [[DEST_WITNESS_ADDR]], align 8
  copy_addr [take] %w to [initialization] %v : $*@sil_weak CP?

  // CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
  // CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
  // CHECK: call void @swift_weakTakeAssign(%swift.weak* [[DEST_REF_ADDR]], %swift.weak* [[SRC_REF_ADDR]])
  // CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
  // CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]], align 8
  // CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 1
  // CHECK: store i8** [[WITNESS]], i8*** [[DEST_WITNESS_ADDR]], align 8
  copy_addr [take] %w to                  %v : $*@sil_weak CP?

  // CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
  // CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
  // CHECK: call void @swift_weakCopyInit(%swift.weak* [[DEST_REF_ADDR]], %swift.weak* [[SRC_REF_ADDR]])
  // CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
  // CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]], align 8
  // CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 1
  // CHECK: store i8** [[WITNESS]], i8*** [[DEST_WITNESS_ADDR]], align 8
  copy_addr        %w to [initialization] %v : $*@sil_weak CP?

  // CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
  // CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
  // CHECK: call void @swift_weakCopyAssign(%swift.weak* [[DEST_REF_ADDR]], %swift.weak* [[SRC_REF_ADDR]])
  // CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
  // CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]], align 8
  // CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 1
  // CHECK: store i8** [[WITNESS]], i8*** [[DEST_WITNESS_ADDR]], align 8
  copy_addr        %w to                  %v : $*@sil_weak CP?

  // CHECK: [[REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
  // CHECK: call void @swift_weakDestroy(%swift.weak* [[REF_ADDR]])
  destroy_addr %v : $*@sil_weak CP?

  dealloc_stack %v : $*@sil_weak CP?

  return undef : $()
}
back to top