Does FullApplySite::getCalleeOrigin() work correctly?

I was debugging some code that produced SIL like this:

  %7 = partial_apply [callee_guaranteed] %5(%6) : $@convention(thin) (@guaranteed NS) -> @owned NS // user: %8
  %8 = move_value [lexical] [var_decl] %7         // users: %23, %10, %9
  debug_value %8, let, name "c"                   // id: %9
  %10 = begin_borrow %8                           // users: %18, %11
  %11 = copy_value %10                            // users: %17, %12
  %12 = begin_borrow %11                          // users: %14, %13
  %13 = apply %12() : $@callee_guaranteed () -> @owned NS // user: %16

I was using a FullApplySite of the apply at %13 = apply %12(), and when I called getCalleeOrigin() on it, I expected to get back to the the partial_apply. However, it seems that utility does not look through MoveValueInst and I ended up with the move_value being returned instead.

Is that the expected behavior, or should getCalleeOrigin() look through the move_value? Relatedly, are there any other instructions it should also look through (e.g. mark_dependence or any newer ownership/lifetime things?)?

getCalleeOrigin already looks through copies, so looking through moves shouldn't confuse anything. getCalleeOrigin should just loop over getSingleValueCopyOrCast without checking anything else.

The additional instructions handled by getSingleValueCopyOrCast are:

  • From its own switch CopyBlockInst, CopyBlockWithoutEscapingInst, BeginAccessInst, MarkDependenceInst, MoveValueInst
  • From ConversionOperation::isa
  •   - MarkUnresolvedNonCopyableValueInst
      - MarkUninitializedInst
      - ConvertFunctionInst
      - UpcastInst
      - AddressToPointerInst
      - UncheckedTrivialBitCastInst
      - UncheckedAddrCastInst
      - UncheckedBitwiseCastInst
      - RefToRawPointerInst
      - RawPointerToRefInst
      - ConvertEscapeToNoEscapeInst
      - RefToBridgeObjectInst
      - BridgeObjectToRefInst
      - BridgeObjectToWordInst
      - ThinToThickFunctionInst
      - ThickToObjCMetatypeInst
      - ObjCToThickMetatypeInst
      - ObjCMetatypeToObjectInst
      - ObjCExistentialMetatypeToObjectInst
      - UnconditionalCheckedCastInst
      - UncheckedRefCastInst
      - UncheckedValueCastInst
      - RefToUnmanagedInst
      - RefToUnownedInst
      - UnmanagedToRefInst
      - UnownedToRefInst
      - CopyableToMoveOnlyWrapperValueInst
      - MoveOnlyWrapperToCopyableValueInst
      - MoveOnlyWrapperToCopyableBoxInst
      - DropDeinitInst
    
2 Likes

Thank you!

Here is a proposed refactor based on this suggestion, for which I would appreciate any/all feedback: [SIL]: Refactor getCalleeOrigin to look through more instructions by jamieQ · Pull Request #90765 · swiftlang/swift · GitHub.

I should have pointed out that ConversionOperation can change the function type. It's possible we have code that expects the original callee to have the same type as the applied callee.