// RUN: %target-sil-opt -sil-print-types -access-enforcement-dom %s -enable-sil-verify-all | %FileCheck %s // // Test AccessEnforcementDom in the presence of loops. // For loops with accessors, see also access_dom_call.sil. sil_stage canonical import Builtin import Swift import SwiftShims struct X { @_hasStorage var i: Int64 { get set } init(i: Int64) init() } var globalX: X sil_global hidden @globalX : $X // Insert one preheader check for the outer access only. // CHECK-LABEL: sil @testDomLoopRDMD : $@convention(thin) () -> () { // CHECK: [[A:%.*]] = begin_access [read] [dynamic] [no_nested_conflict] [[GA:%.*]] : $*X // CHECK: end_access [[A]] // CHECK: bb3: // CHECK: begin_access [read] [static] [no_nested_conflict] [[GA]] : $*X // CHECK: begin_access [modify] [dynamic] [no_nested_conflict] [[GA]] : $*X // CHECK-LABEL: } // end sil function 'testDomLoopRDMD' sil @testDomLoopRDMD : $@convention(thin) () -> () { bb0: %0 = global_addr @globalX: $*X br bb1 bb1: br bb2 bb2: br bb3 bb3: %4 = begin_access [read] [dynamic] [no_nested_conflict] %0 : $*X %6 = begin_access [modify] [dynamic] [no_nested_conflict] %0 : $*X end_access %6 : $*X end_access %4 : $*X %cond = integer_literal $Builtin.Int1, 1 cond_br %cond, bb2, bb4 bb4: %10 = tuple () return %10 : $() } // No, do cannot optimize a nested loop access. // CHECK-LABEL: sil @testDomLoopRSMD : $@convention(thin) () -> () { // CHECK-NOT: begin_access // CHECK: bb3: // CHECK: begin_access [read] [static] [no_nested_conflict] [[GA:%.*]] : $*X // CHECK: begin_access [modify] [dynamic] [no_nested_conflict] [[GA]] : $*X // CHECK-LABEL: } // end sil function 'testDomLoopRSMD' sil @testDomLoopRSMD : $@convention(thin) () -> () { bb0: %0 = global_addr @globalX: $*X br bb1 bb1: br bb2 bb2: br bb3 bb3: %4 = begin_access [read] [static] [no_nested_conflict] %0 : $*X %6 = begin_access [modify] [dynamic] [no_nested_conflict] %0 : $*X end_access %6 : $*X end_access %4 : $*X %cond = integer_literal $Builtin.Int1, 1 cond_br %cond, bb2, bb4 bb4: %10 = tuple () return %10 : $() } // Yes, insert a preheader check for unidentifiable access (address argument). // CHECK-LABEL: sil @testDomLoopUnidentified : $@convention(thin) (@inout Int64) -> () { // CHECK: [[A:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GA:%.*]] : $*Int64 // CHECK: end_access [[A]] // CHECK: bb3: // CHECK: begin_access [modify] [static] [no_nested_conflict] [[GA]] : $*Int64 // CHECK-LABEL: } // end sil function 'testDomLoopUnidentified' sil @testDomLoopUnidentified : $@convention(thin) (@inout Int64) -> () { bb0(%0 : $*Int64): br bb1 bb1: br bb2 bb2: br bb3 bb3: %6 = begin_access [modify] [dynamic] [no_nested_conflict] %0 : $*Int64 end_access %6 : $*Int64 %cond = integer_literal $Builtin.Int1, 1 cond_br %cond, bb2, bb4 bb4: %10 = tuple () return %10 : $() }