Skip to content

Commit 3aa1ed1

Browse files
authored
Merge pull request #80433 from eeckstein/fix-alloc-stack-simplification
Simplification: fix a crash in alloc_stack simplification
2 parents a7ade95 + ee18f8c commit 3aa1ed1

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyAllocStack.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ private extension AllocStackInst {
277277
// The instruction which defines the existential archetype must dominate the alloc_stack, because
278278
// after the transformation the alloc_stack will use the existential archetype.
279279
for openArchetypeOp in initExistential.typeDependentOperands {
280-
if !openArchetypeOp.value.definingInstruction!.dominatesInSameBlock(self) {
280+
if !openArchetypeOp.value.triviallyDominates(self) {
281281
return nil
282282
}
283283
}

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

+18
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,24 @@ extension Value {
185185
}
186186
return true
187187
}
188+
189+
/// Performs a simple dominance check without using the dominator tree.
190+
/// Returns true if `instruction` is in the same block as this value, but "after" this value,
191+
/// or if this value is a function argument.
192+
func triviallyDominates(_ instruction: Instruction) -> Bool {
193+
switch self {
194+
case is FunctionArgument:
195+
return true
196+
case let arg as Argument:
197+
return arg.parentBlock == instruction.parentBlock
198+
case let svi as SingleValueInstruction:
199+
return svi.dominatesInSameBlock(instruction)
200+
case let mvi as MultipleValueInstructionResult:
201+
return mvi.parentInstruction.dominatesInSameBlock(instruction)
202+
default:
203+
return false
204+
}
205+
}
188206
}
189207

190208
extension FullApplySite {

test/SILOptimizer/simplify_alloc_stack.sil

+19
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ public struct S {}
1010
protocol P {
1111
}
1212

13+
public class C2: P {}
14+
1315
public struct T: P {
1416
let c: C
1517
let s: S
@@ -36,6 +38,7 @@ public enum X {
3638
sil [ossa] @take_s : $@convention(thin) (@in S) -> ()
3739
sil [ossa] @take_t : $@convention(thin) (@in T) -> ()
3840
sil [ossa] @use_mp : $@convention(thin) (@in_guaranteed MP) -> ()
41+
sil [ossa] @use_c2 : $@convention(thin) (@in_guaranteed C2) -> ()
3942

4043
// CHECK-LABEL: sil [ossa] @expand_alloc_stack_of_enum1 :
4144
// CHECK: [[A:%[0-9]+]] = alloc_stack $S
@@ -346,3 +349,19 @@ bb3:
346349
return %r
347350
}
348351

352+
// CHECK-LABEL: sil [ossa] @init_existential_with_dynamic_self :
353+
// CHECK: [[S:%.*]] = alloc_stack $C2
354+
// CHECK: store %0 to [init] [[S]]
355+
// CHECK: apply %{{[0-9]+}}([[S]])
356+
// CHECK: } // end sil function 'init_existential_with_dynamic_self'
357+
sil [ossa] @init_existential_with_dynamic_self : $@convention(method) (@owned C2) -> () {
358+
bb0(%0 : @owned $C2):
359+
%1 = alloc_stack $P
360+
%2 = init_existential_addr %1, $@dynamic_self C2
361+
store %0 to [init] %2
362+
%4 = function_ref @use_c2 : $@convention(thin) (@in_guaranteed C2) -> ()
363+
%5 = apply %4(%2) : $@convention(thin) (@in_guaranteed C2) -> ()
364+
destroy_addr %1
365+
dealloc_stack %1
366+
return %5
367+
}

0 commit comments

Comments
 (0)