ABCOpts: Bail out if we don't know how-to hoist an array operation

Instead of assuming we see only certain forms IR.

rdar://28204253
This commit is contained in:
Arnold Schwaighofer
2016-09-19 10:15:14 -07:00
parent 6132819f59
commit 3c755e36aa
2 changed files with 51 additions and 0 deletions

View File

@@ -1010,6 +1010,10 @@ static bool hoistChecksInLoop(DominanceInfo *DT, DominanceInfoNode *DTNode,
if (!ArrayIndex) if (!ArrayIndex)
continue; continue;
// Make sure we know how-to hoist the array call.
if (!ArrayCall.canHoist(Preheader->getTerminator(), DT))
continue;
// Invariant check. // Invariant check.
if (blockAlwaysExecutes && dominates(DT, ArrayIndex, Preheader)) { if (blockAlwaysExecutes && dominates(DT, ArrayIndex, Preheader)) {
assert(ArrayCall.canHoist(Preheader->getTerminator(), DT) && assert(ArrayCall.canHoist(Preheader->getTerminator(), DT) &&

View File

@@ -1176,3 +1176,50 @@ bb4:
%28 = builtin "cmp_eq_Int64"(%23 : $Builtin.Int64, %0 : $Builtin.Int64) : $Builtin.Int1 %28 = builtin "cmp_eq_Int64"(%23 : $Builtin.Int64, %0 : $Builtin.Int64) : $Builtin.Int1
cond_br %28, bb2, bb3(%23 : $Builtin.Int64) cond_br %28, bb2, bb3(%23 : $Builtin.Int64)
} }
// Don't assert when we have an isNativeTypeChecked parameter that is not a
// constant or an array semantic call. It is valid for it to be a phi node.
sil @bb_arg_is_native2 : $@convention(thin) (Int32, @inout ArrayInt, Builtin.Int1) -> Int32 {
bb0(%0 : $Int32, %1 : $*ArrayInt, %2 : $Builtin.Int1):
cond_br %2, bb1, bb2
bb1:
%4 = integer_literal $Builtin.Int1, -1
%5 = struct $Bool (%4 : $Builtin.Int1)
br bb3(%5 : $Bool)
bb2:
%7 = integer_literal $Builtin.Int1, -1
%8 = struct $Bool (%7 : $Builtin.Int1)
br bb3(%8 : $Bool)
bb3(%10 : $Bool):
%11 = struct_extract %0 : $Int32, #Int32._value
%12 = integer_literal $Builtin.Int32, 0
%13 = builtin "cmp_eq_Int32"(%12 : $Builtin.Int32, %11 : $Builtin.Int32) : $Builtin.Int1
cond_br %13, bb6(%12 : $Builtin.Int32), bb4
bb4:
br bb5(%12 : $Builtin.Int32)
bb5(%16 : $Builtin.Int32):
%17 = struct $Int32 (%16 : $Builtin.Int32)
%18 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
%19 = load %1 : $*ArrayInt
%20 = struct_extract %19 : $ArrayInt, #ArrayInt.buffer
%21 = struct_extract %20 : $ArrayIntBuffer, #ArrayIntBuffer.storage
retain_value %21 : $Builtin.NativeObject
%23 = apply %18(%17, %10, %19) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
%24 = integer_literal $Builtin.Int32, 1
%25 = integer_literal $Builtin.Int1, -1
%26 = builtin "sadd_with_overflow_Int32"(%16 : $Builtin.Int32, %24 : $Builtin.Int32, %25 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
%27 = tuple_extract %26 : $(Builtin.Int32, Builtin.Int1), 0
%28 = tuple_extract %26 : $(Builtin.Int32, Builtin.Int1), 1
cond_fail %28 : $Builtin.Int1
%30 = builtin "cmp_eq_Int32"(%27 : $Builtin.Int32, %11 : $Builtin.Int32) : $Builtin.Int1
cond_br %30, bb6(%27 : $Builtin.Int32), bb5(%27 : $Builtin.Int32)
bb6(%32 : $Builtin.Int32):
%33 = struct $Int32 (%32 : $Builtin.Int32)
return %33 : $Int32
}