Skip to content

Commit c0eabf0

Browse files
committed
---
yaml --- r: 345955 b: refs/heads/master c: 796add2 h: refs/heads/master i: 345953: f414836 345951: 5c90132
1 parent d7ef115 commit c0eabf0

File tree

4 files changed

+79
-37
lines changed

4 files changed

+79
-37
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 3c82c7ea889cbc3c7f53c72baac16a362681286c
2+
refs/heads/master: 796add2b9fc12e5cf93618a6fec27f53d89c79ee
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/SIL/MemAccessUtils.h

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,31 @@ class AccessedStorage {
314314
bool operator==(const AccessedStorage &) const = delete;
315315
bool operator!=(const AccessedStorage &) const = delete;
316316
};
317+
318+
/// Return true if the given storage objects have identical storage locations.
319+
///
320+
/// This compares only the AccessedStorage base class bits, ignoring the
321+
/// subclass bits.
322+
inline bool accessingIdenticalLocations(AccessedStorage LHS,
323+
AccessedStorage RHS) {
324+
if (LHS.getKind() != RHS.getKind())
325+
return false;
326+
327+
switch (LHS.getKind()) {
328+
case swift::AccessedStorage::Box:
329+
case swift::AccessedStorage::Stack:
330+
case swift::AccessedStorage::Nested:
331+
case swift::AccessedStorage::Yield:
332+
case swift::AccessedStorage::Unidentified:
333+
return LHS.getValue() == RHS.getValue();
334+
case swift::AccessedStorage::Argument:
335+
return LHS.getParamIndex() == RHS.getParamIndex();
336+
case swift::AccessedStorage::Global:
337+
return LHS.getGlobal() == RHS.getGlobal();
338+
case swift::AccessedStorage::Class:
339+
return LHS.getObjectProjection() == RHS.getObjectProjection();
340+
}
341+
}
317342
} // end namespace swift
318343

319344
namespace llvm {
@@ -355,24 +380,7 @@ template <> struct DenseMapInfo<swift::AccessedStorage> {
355380
}
356381

357382
static bool isEqual(swift::AccessedStorage LHS, swift::AccessedStorage RHS) {
358-
if (LHS.getKind() != RHS.getKind())
359-
return false;
360-
361-
switch (LHS.getKind()) {
362-
case swift::AccessedStorage::Box:
363-
case swift::AccessedStorage::Stack:
364-
case swift::AccessedStorage::Nested:
365-
case swift::AccessedStorage::Yield:
366-
case swift::AccessedStorage::Unidentified:
367-
return LHS.getValue() == RHS.getValue();
368-
case swift::AccessedStorage::Argument:
369-
return LHS.getParamIndex() == RHS.getParamIndex();
370-
case swift::AccessedStorage::Global:
371-
return LHS.getGlobal() == RHS.getGlobal();
372-
case swift::AccessedStorage::Class:
373-
return LHS.getObjectProjection() == RHS.getObjectProjection();
374-
}
375-
llvm_unreachable("Unhandled AccessedStorageKind");
383+
return swift::accessingIdenticalLocations(LHS, RHS);
376384
}
377385
};
378386

trunk/lib/SIL/MemAccessUtils.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,10 @@ static bool isUnsafePointerExtraction(StructExtractInst *SEI) {
206206
|| decl == C.getUnsafePointerDecl();
207207
}
208208

209-
// Given an address base is a block argument, verify that it is actually a box
210-
// projected from a switch_enum. This is a valid pattern at any SIL stage
211-
// resulting in a block-type phi. In later SIL stages, the optimizer may form
212-
// address-type phis, causing this assert if called on those cases.
209+
// Given a block argument address base, check if it is actually a box projected
210+
// from a switch_enum. This is a valid pattern at any SIL stage resulting in a
211+
// block-type phi. In later SIL stages, the optimizer may form address-type
212+
// phis, causing this assert if called on those cases.
213213
static void checkSwitchEnumBlockArg(SILPhiArgument *arg) {
214214
assert(!arg->getType().isAddress());
215215
SILBasicBlock *Pred = arg->getParent()->getSinglePredecessorBlock();
@@ -289,22 +289,21 @@ AccessedStorage swift::findAccessedStorage(SILValue sourceAddr) {
289289

290290
case ValueKind::SILPhiArgument: {
291291
auto *phiArg = cast<SILPhiArgument>(address);
292-
bool allValsMatch = true;
293-
SmallVector<SILValue, 8> incomingPhis;
294-
phiArg->getIncomingPhiValues(incomingPhis);
295-
if (!incomingPhis.empty()) {
296-
auto firstVal = incomingPhis.front();
297-
for (auto val : incomingPhis) {
298-
if (val != firstVal) {
299-
allValsMatch = false;
300-
break;
301-
}
302-
}
303-
if (allValsMatch) {
304-
return findAccessedStorage(firstVal);
292+
if (phiArg->isPhiArgument()) {
293+
SmallVector<SILValue, 8> incomingValues;
294+
phiArg->getIncomingPhiValues(incomingValues);
295+
if (incomingValues.empty())
296+
return AccessedStorage();
297+
298+
auto storage = findAccessedStorage(incomingValues.pop_back_val());
299+
for (auto val : incomingValues) {
300+
auto otherStorage = findAccessedStorage(val);
301+
if (!accessingIdenticalLocations(storage, otherStorage))
302+
return AccessedStorage();
305303
}
304+
return storage;
306305
}
307-
// A block argument may be a box value projected out of
306+
// A non-phi block argument may be a box value projected out of
308307
// switch_enum. Address-type block arguments are not allowed.
309308
if (address->getType().isAddress())
310309
return AccessedStorage();

trunk/test/SILOptimizer/accessed_storage_analysis.sil

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,3 +626,38 @@ bb2(%7 : ${ var Int }):
626626
bb3(%result : $Int):
627627
return %result : $Int
628628
}
629+
630+
// Make sure findAccessedStorage returns a valid storage object for an address-phi
631+
// that feeds ref_element_addr instructions. The ref_element_addr's need to have the
632+
// same base object and same field id.
633+
// <rdar://problem/46114512> SIL verification failed: Unknown formal access pattern: storage
634+
class BaseClass {
635+
var f: Float = 0.0
636+
}
637+
638+
class SubClass : BaseClass {}
639+
640+
// CHECK-LABEL: @testElementAddressPhiAccess
641+
// CHECK: [read] [no_nested_conflict] Class %{{.*}} = upcast %0 : $SubClass to $BaseClass
642+
// CHECK: Field: @_hasInitialValue var f: Float
643+
sil @testElementAddressPhiAccess : $@convention(thin) (@guaranteed SubClass) -> () {
644+
bb0(%0 : $SubClass):
645+
%base = upcast %0 : $SubClass to $BaseClass
646+
cond_br undef, bb1, bb2
647+
648+
bb1:
649+
%ref1 = ref_element_addr %base : $BaseClass, #BaseClass.f
650+
br bb3(%ref1 : $*Float)
651+
652+
bb2:
653+
%ref2 = ref_element_addr %base : $BaseClass, #BaseClass.f
654+
br bb3(%ref2 : $*Float)
655+
656+
bb3(%phi : $*Float):
657+
%access = begin_access [read] [dynamic] [no_nested_conflict] %phi : $*Float
658+
%addr = struct_element_addr %access : $*Float, #Float._value
659+
%val = load %addr : $*Builtin.FPIEEE32
660+
end_access %access : $*Float
661+
%v = tuple ()
662+
return %v : $()
663+
}

0 commit comments

Comments
 (0)