Skip to content

[5.7] Fix OwnershipLiveRange for @owned values getting transformed to none values via switch_enum #60110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2022

Conversation

meg-gupta
Copy link
Contributor

@meg-gupta meg-gupta commented Jul 18, 2022

Scope: Fixes possible verifier error while using switch on enums with dead ends on non-trivial paths

Main Branch PR: #60101

Resolves: rdar://95039799

Risk: Very low

Reviewed By: Andrew Trick, Michael Gottesman

Testing: Added a regression test-case to the suite.

…values via switch_enum

rdar://95039799

We are currently not computing OwnershipLiveRange correctly in the presence of switch_enum transforming the owned value to a none value.

We can end up with illegal SIL with LoadCopyToLoadBorrowOptimization, due to this.

Example:

sil [ossa] @switch_enum_test : $@convention(thin) (@inout StructWithEnum) -> () {
 bb0(%0 : $*StructWithEnum):
   %1 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
   %2 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
   %3 = load [copy] %2 : $*EnumA
   destroy_addr %1 : $*EnumA
   switch_enum %3 : $EnumA, case #EnumA.sometrivial!enumelt: bb1, case #EnumA.somenontrivial!enumelt:bb2, case #EnumA.none!enumelt: bb3

 bb1(%6 : $TrivialStruct):
   %f = function_ref @get_enum : $@convention(thin) () -> @owned EnumA
   %r = apply %f() : $@convention(thin) () -> @owned EnumA
   %ele = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
   store %r to [init] %ele :$*EnumA
   %9999 = tuple()
   return %9999 : $()

 bb2(%7 : @owned $NonTrivialStruct):
  unreachable

 bb3:
  unreachable
 }

can get transformed to:

sil [ossa] @switch_enum_test : $@convention(thin) (@inout StructWithEnum) -> () {

bb0(%0 : $*StructWithEnum):
  %1 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
  %2 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
  %3 = load_borrow %2 : $*EnumA
  destroy_addr %1 : $*EnumA
  switch_enum %3 : $EnumA, case #EnumA.sometrivial!enumelt: bb1, case #EnumA.somenontrivial!enumelt: bb2, case #EnumA.none!enumelt: bb3

bb1(%6 : $TrivialStruct):
  end_borrow %3 : $EnumA

  %8 = function_ref @get_enum : $@convention(thin) () -> @owned EnumA
  %9 = apply %8() : $@convention(thin) () -> @owned EnumA
  %10 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
  store %9 to [init] %10 : $*EnumA
  %12 = tuple ()
  return %12 : $()

bb2(%14 : @guaranteed $NonTrivialStruct):
  unreachable

bb3:
  unreachable
}

which is incorrect:
Write:   destroy_addr %1 : $*EnumA
SIL verification failed: Found load borrow that is invalidated by a local write?!: loadBorrowImmutabilityAnalysis.isImmutable(LBI)
Verifying instruction:
     %2 = struct_element_addr %0 : $*StructWithEnum, #StructWithEnum.val
->   %3 = load_borrow %2 : $*EnumA
     switch_enum %3 : $EnumA, case #EnumA.sometrivial!enumelt: bb1, case #EnumA.somenontrivial!enumelt: bb2, case #EnumA.none!enumelt: bb3
     end_borrow %3 : $EnumA
@meg-gupta meg-gupta requested a review from a team as a code owner July 18, 2022 20:56
@meg-gupta
Copy link
Contributor Author

@swift-ci test

@atrick atrick added the r5.7 label Jul 18, 2022
@atrick atrick self-assigned this Jul 18, 2022
Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed for CCC

@meg-gupta meg-gupta changed the title Fix OwnershipLiveRange for @owned values getting transformed to none values via switch_enum [5.7] Fix OwnershipLiveRange for @owned values getting transformed to none values via switch_enum Jul 18, 2022
@meg-gupta
Copy link
Contributor Author

@swift-ci please nominate

@meg-gupta meg-gupta merged commit bb547c2 into swiftlang:release/5.7 Jul 22, 2022
@meg-gupta meg-gupta deleted the cherrypickossafix57 branch December 14, 2022 22:31
@AnthonyLatsis AnthonyLatsis added 🍒 release cherry pick Flag: Release branch cherry picks swift 5.7 labels Jan 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍒 release cherry pick Flag: Release branch cherry picks swift 5.7
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants