Skip to content

Commit 4fe43e3

Browse files
author
Joe Shajrawi
authored
Merge pull request swiftlang#5622 from shajrawi/array_bouds_check_false
[SILOptimizer] add support for always false comparisons to ArrayBoundsCheckOpts
2 parents 8d8c258 + fee71ca commit 4fe43e3

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,38 @@ static bool isComparisonKnownTrue(BuiltinInst *Builtin, InductionInfo &IndVar) {
10971097
m_Specific(IndVar.End)));
10981098
}
10991099

1100+
/// Based on the induction variable information this comparison is known to be
1101+
/// false.
1102+
static bool isComparisonKnownFalse(BuiltinInst *Builtin,
1103+
InductionInfo &IndVar) {
1104+
if (!IndVar.IsOverflowCheckInserted ||
1105+
IndVar.Cmp != BuiltinValueKind::ICMP_EQ)
1106+
return false;
1107+
1108+
// Pattern match a false condition patterns that we can detect and optimize:
1109+
// Iteration count < 0 (start)
1110+
// Iteration count + 1 <= 0 (start)
1111+
// Iteration count + 1 < 0 (start)
1112+
// Iteration count + 1 == 0 (start)
1113+
auto MatchIndVarHeader = m_Specific(IndVar.HeaderVal);
1114+
auto MatchIncrementIndVar = m_TupleExtractInst(
1115+
m_ApplyInst(BuiltinValueKind::SAddOver, MatchIndVarHeader, m_One()), 0);
1116+
auto MatchIndVarStart = m_Specific(IndVar.Start);
1117+
1118+
if (match(Builtin,
1119+
m_ApplyInst(BuiltinValueKind::ICMP_SLT,
1120+
m_CombineOr(MatchIndVarHeader, MatchIncrementIndVar),
1121+
MatchIndVarStart)) ||
1122+
match(Builtin, m_ApplyInst(BuiltinValueKind::ICMP_EQ,
1123+
MatchIncrementIndVar, MatchIndVarStart)) ||
1124+
match(Builtin, m_ApplyInst(BuiltinValueKind::ICMP_SLE,
1125+
MatchIncrementIndVar, MatchIndVarStart))) {
1126+
return true;
1127+
}
1128+
1129+
return false;
1130+
}
1131+
11001132
/// Analyse the loop for arrays that are not modified and perform dominator tree
11011133
/// based redundant bounds check removal.
11021134
static bool hoistBoundsChecks(SILLoop *Loop, DominanceInfo *DT, SILLoopInfo *LI,
@@ -1200,6 +1232,15 @@ static bool hoistBoundsChecks(SILLoop *Loop, DominanceInfo *DT, SILLoopInfo *LI,
12001232
Changed = true;
12011233
continue;
12021234
}
1235+
if (isComparisonKnownFalse(Builtin, *IV)) {
1236+
if (!FalseVal) {
1237+
FalseVal = SILValue(B.createIntegerLiteral(
1238+
Builtin->getLoc(), Builtin->getType(), 0));
1239+
}
1240+
Builtin->replaceAllUsesWith(FalseVal);
1241+
Changed = true;
1242+
continue;
1243+
}
12031244
// Check whether a dominating check of the condition let's us
12041245
// replace
12051246
// the condition by false.

test/SILOptimizer/abcopts.sil

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,67 @@ bb3:
441441
return %23 : $Int32
442442
}
443443

444+
// HOIST-LABEL: sil @always_false_hoist
445+
// HOIST: bb4
446+
// HOIST: builtin "sadd_with_overflow_Int32"
447+
// HOIST: tuple_extract
448+
// HOIST-NOT: builtin "cmp_slt_Int32"
449+
// HOIST-NOT: builtin "cmp_sle_Int32"
450+
// HOIST-NOT: builtin "cmp_eq_Int32"
451+
// HOIST: cond_fail
452+
// HOIST: cond_fail
453+
// HOIST: cond_fail
454+
// HOIST: cond_fail
455+
// HOIST: builtin "cmp_eq_Int32"
456+
// HOIST: cond_br
457+
// HOIST: }
458+
sil @always_false_hoist : $@convention(thin) (@owned Array<Int>) -> () {
459+
bb0(%0 : $Array<Int>):
460+
%z0 = integer_literal $Builtin.Int32, 0
461+
%f1 = function_ref @getCount2 : $@convention(method) (@owned Array<Int>) -> Int32
462+
retain_value %0 : $Array<Int>
463+
%t1 = apply %f1(%0) : $@convention(method) (@owned Array<Int>) -> Int32
464+
%c1 = struct_extract %t1 : $Int32, #Int32._value
465+
%t2 = builtin "cmp_eq_Int32"(%z0 : $Builtin.Int32, %c1 : $Builtin.Int32) : $Builtin.Int1
466+
cond_br %t2, bb5, bb1
467+
468+
bb1:
469+
br bb2(%z0 : $Builtin.Int32)
470+
471+
bb2(%i0 : $Builtin.Int32):
472+
cond_br undef, bb3, bb4
473+
474+
bb3:
475+
%f2 = function_ref @checkbounds2 : $@convention(method) (Int32, Bool, @owned Array<Int>) -> _DependenceToken
476+
retain_value %0 : $Array<Int>
477+
%t3 = struct $Int32(%i0 : $Builtin.Int32)
478+
479+
br bb4
480+
481+
bb4:
482+
%t5 = integer_literal $Builtin.Int1, 0
483+
%i2 = integer_literal $Builtin.Int32, 1
484+
%t6 = builtin "sadd_with_overflow_Int32"(%i0 : $Builtin.Int32, %i2 : $Builtin.Int32, %t5 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
485+
%t7 = tuple_extract %t6 : $(Builtin.Int32, Builtin.Int1), 0
486+
%t8 = tuple_extract %t6 : $(Builtin.Int32, Builtin.Int1), 1
487+
cond_fail %t8 : $Builtin.Int1
488+
%af1 = builtin "cmp_slt_Int32"(%i0 : $Builtin.Int32, %z0 : $Builtin.Int32) : $Builtin.Int1
489+
cond_fail %af1 : $Builtin.Int1
490+
%af2 = builtin "cmp_slt_Int32"(%t7 : $Builtin.Int32, %z0 : $Builtin.Int32) : $Builtin.Int1
491+
cond_fail %af2 : $Builtin.Int1
492+
%af3 = builtin "cmp_sle_Int32"(%t7 : $Builtin.Int32, %z0 : $Builtin.Int32) : $Builtin.Int1
493+
cond_fail %af3 : $Builtin.Int1
494+
%af4 = builtin "cmp_eq_Int32"(%t7 : $Builtin.Int32, %z0 : $Builtin.Int32) : $Builtin.Int1
495+
cond_fail %af4 : $Builtin.Int1
496+
%8 = builtin "cmp_eq_Int32"(%t7 : $Builtin.Int32, %c1 : $Builtin.Int32) : $Builtin.Int1
497+
cond_br %8, bb5, bb2(%t7 : $Builtin.Int32)
498+
499+
bb5:
500+
%r1 = tuple ()
501+
return %r1 : $()
502+
}
503+
504+
444505
// HOIST-LABEL: sil @hoistinvariant
445506

446507
// Preheader.

0 commit comments

Comments
 (0)