From 3c755e36aa8a74bfe727a8536bebe580e6a94e4d Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Mon, 19 Sep 2016 10:15:14 -0700 Subject: [PATCH] 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 --- .../LoopTransforms/ArrayBoundsCheckOpts.cpp | 4 ++ test/SILOptimizer/abcopts.sil | 47 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp b/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp index 7cc5b052954..51b6e68dbfc 100644 --- a/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp +++ b/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp @@ -1010,6 +1010,10 @@ static bool hoistChecksInLoop(DominanceInfo *DT, DominanceInfoNode *DTNode, if (!ArrayIndex) continue; + // Make sure we know how-to hoist the array call. + if (!ArrayCall.canHoist(Preheader->getTerminator(), DT)) + continue; + // Invariant check. if (blockAlwaysExecutes && dominates(DT, ArrayIndex, Preheader)) { assert(ArrayCall.canHoist(Preheader->getTerminator(), DT) && diff --git a/test/SILOptimizer/abcopts.sil b/test/SILOptimizer/abcopts.sil index 144a18dc1e9..0b8d84be989 100644 --- a/test/SILOptimizer/abcopts.sil +++ b/test/SILOptimizer/abcopts.sil @@ -1176,3 +1176,50 @@ bb4: %28 = builtin "cmp_eq_Int64"(%23 : $Builtin.Int64, %0 : $Builtin.Int64) : $Builtin.Int1 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 +}