swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.66k stars 10.38k forks source link

[SR-6169] [sil-opt] Assertion " "no dealloc found for alloc stack" in stack promotion pass on valid SIL code #48721

Open 0acf245c-f0fa-406f-afb9-4746d10f0359 opened 7 years ago

0acf245c-f0fa-406f-afb9-4746d10f0359 commented 7 years ago
Previous ID SR-6169
Radar None
Original Reporter @dcci
Type Bug
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, SILParser | |Assignee | None | |Priority | Medium | md5: 79392f9bb1951d980d108a9b65b5afd1

Issue Description:

This is the first interesting bug, I tweaked my fuzzer/reduction script and now I'm filtering only interesting bugs. stack-promotion crashes on this valid SIL.

$ ./sil-opt -assume-parsing-unqualified-ownership-sil -stack-promotion red4.ll
sil-opt: /home/davide/work/swift/swift/lib/SILOptimizer/Utils/StackNesting.cpp:125: bool swift::StackNesting::solve(): Assertion `(Bits.test(BitNr) || (!BI.ExitReachable && !Bits.an
y())) && "no dealloc found for alloc stack"' failed.
import Builtin
import Swift
class B { }
enum BoolLike { case true_, false_ }
sil @fold_enum : $@convention(thin) (BoolLike) -> BoolLike {
bb0(%0 : $BoolLike):
  %2 = enum $BoolLike, #BoolLike.true_!enumelt
  br bb3(%2 : $BoolLike)
bb3(%3 : $BoolLike):
  return %3 : $BoolLike
}
sil @is_trivial_layout_constraint_class : $@convention(thin) <T where T: _Trivial> (@in T) -> Int8 {
bb0(%0 : $*T):
  %1 = metatype $@thick T.Type
  %3 = builtin "canBeClass"<T>(%1 : $@thick T.Type) : $Builtin.Int8
  %4 = struct $Int8 (%3 : $Builtin.Int8)
  return %4 : $Int8
}
sil @convert_function_simplification : $@convention(thin) (@inout B, B, Builtin.Int1) -> () {
bb0(%0 : $*B, %1 : $B, %2 : $Builtin.Int1):
  %6 = tuple()
  return %6 : $()
}
sil @delete_dead_alloc_stack : $(@inout B) -> () {
bb0(%0 : $*B):
  %1 = alloc_ref $B
  %2 = tuple()
  return %2 : $()
}
0acf245c-f0fa-406f-afb9-4746d10f0359 commented 7 years ago

Reduced testcase

import Builtin
import Swift
class B { }
sil @delete_dead_alloc_stack : $(@inout B) -> () {
bb0(%0 : $*B):
  %1 = alloc_ref $B
  %2 = tuple()
  return %2 : $()
}

The pass expects to find a dealloc for the alloc function, possibly invalid SIL?
@eeckstein/@gottesmm

eeckstein commented 7 years ago

Yes, that's invalid SIL, because the alloc_ref is never destroyed. This should be detected by the ownership verifier (which should run if you don't pass -assume-parsing-unqualified-ownership-sil to sil-opt)

0acf245c-f0fa-406f-afb9-4746d10f0359 commented 7 years ago

I'm afraid this still crashes if I don't pass the `-assume-unqualified-blah` bit.
I'll try enhancing the verifier to detect this case.

$ ./sil-opt x.sil
sil_stage raw

import Builtin
import Swift
import SwiftShims

class B {
  deinit
  init()
}

// delete_dead_alloc_stack
sil @delete_dead_alloc_stack : $@convention(thin) (@inout B) -> () {
bb0(%0 : $*B):
  %1 = alloc_ref $B
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function 'delete_dead_alloc_stack'
eeckstein commented 7 years ago

As I said, this should be detected by the ownership verifier. So no need to add the same check to the SILVerifier.

@gottesmm knows the details about this

0acf245c-f0fa-406f-afb9-4746d10f0359 commented 7 years ago

Michael asked me to try adding `-enable-sil-ownership` and I can claim it still fails.

gottesmm commented 7 years ago

Can you try it without running stack promotion through it?

0acf245c-f0fa-406f-afb9-4746d10f0359 commented 7 years ago

Or, FWIW, when I pass `-enable-sil-verify-all`, i.e.

$ ./sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-ownership -enable-sil-verify-all -stack-promotion red4.ll
sil-opt: /home/davide/work/swift/swift/lib/SILOptimizer/Utils/StackNesting.cpp:125: bool swift::StackNesting::solve(): Assertion `(Bits.test(BitNr) || (!BI.ExitReachable && !Bits.an
y())) && "no dealloc found for alloc stack"' failed.
0acf245c-f0fa-406f-afb9-4746d10f0359 commented 7 years ago

No error without `-stack-promotion`.

[davide@localhost bin]$ ./sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-ownership -enable-sil-verify-all red4.ll -o /dev/null
[davide@localhost bin]$
gottesmm commented 7 years ago

That isn't what I meant. I meant:

./sil-opt -enable-sil-ownership -enable-sil-verify-all red4.ll -o /dev/null
0acf245c-f0fa-406f-afb9-4746d10f0359 commented 7 years ago

Thanks.
That passes (and produces many errors). FWIW, I think this should stay open as the compiler still crashes with some combinations (and it shouldn't), but, your call.

gottesmm commented 7 years ago

@dcci my (personal) feeling is that once ownership gets into its final position (somewhere in the optimizer pipeline), we will introduce a new SIL stage. Then there will no longer be all of these options. The crashes here are just due to us being in an intermediate state of that transition.