Merge pull request #10107 from atrick/swift-4.0-branch

Guaranteed ARC Opts: Access instructions do not reduce refcounts.
diff --git a/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp b/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
index cdd4503..94d6cdf 100644
--- a/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
+++ b/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
@@ -76,7 +76,9 @@
       isa<RetainValueInst>(Inst) || isa<UnownedRetainInst>(Inst) ||
       isa<UnownedReleaseInst>(Inst) || isa<StrongRetainUnownedInst>(Inst) ||
       isa<StoreWeakInst>(Inst) || isa<StrongRetainInst>(Inst) ||
-      isa<AllocStackInst>(Inst) || isa<DeallocStackInst>(Inst))
+      isa<AllocStackInst>(Inst) || isa<DeallocStackInst>(Inst) ||
+      isa<BeginAccessInst>(Inst) || isa<EndAccessInst>(Inst) ||
+      isa<BeginUnpairedAccessInst>(Inst) || isa<EndUnpairedAccessInst>(Inst))
     return false;
 
   // Assign and copyaddr of trivial types cannot drop refcounts, and 'inits'
diff --git a/test/SILOptimizer/guaranteed_arc_opts_qualified.sil b/test/SILOptimizer/guaranteed_arc_opts_qualified.sil
index cda4fc2..d8e5d21 100644
--- a/test/SILOptimizer/guaranteed_arc_opts_qualified.sil
+++ b/test/SILOptimizer/guaranteed_arc_opts_qualified.sil
@@ -137,3 +137,24 @@
   %9999 = tuple()
   return %9999 : $()
 }
+
+class C {
+  var val: Builtin.Int32
+  init(i: Builtin.Int32)
+  deinit
+}
+
+// CHECK-LABEL: sil @access_test : $@convention(thin) (@owned C, Builtin.Int32) -> ()
+// CHECK-NOT: strong_retain
+// CHECK-NOT: strong_release
+sil @access_test : $@convention(thin) (@owned C, Builtin.Int32) -> () {
+bb0(%0 : $C, %1 : $Builtin.Int32):
+  strong_retain %0 : $C
+  %valadr = ref_element_addr %0 : $C, #C.val
+  %access = begin_access [modify] [dynamic] %valadr : $*Builtin.Int32
+  store %1 to %access : $*Builtin.Int32
+  end_access %access : $*Builtin.Int32
+  strong_release %0 : $C
+  %9999 = tuple()
+  return %9999 : $()
+}