Skip to content

Commit e8a8f7d

Browse files
committed
Merge pull request #2564 from trentxintong/RLE
Fix a non-deterministic load forwarding in RLE
2 parents 0b16751 + 260f75d commit e8a8f7d

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,13 +1487,26 @@ bool RLEContext::run() {
14871487
// Finally, perform the redundant load replacements.
14881488
llvm::DenseSet<SILInstruction *> InstsToDelete;
14891489
bool SILChanged = false;
1490-
for (auto &X : BBToLocState) {
1491-
for (auto &F : X.second.getRL()) {
1492-
DEBUG(llvm::dbgs() << "Replacing " << SILValue(F.first) << "With "
1493-
<< F.second);
1490+
for (auto &B : *Fn) {
1491+
auto &State = BBToLocState[&B];
1492+
auto &Loads = State.getRL();
1493+
// Nothing to forward.
1494+
if (Loads.empty())
1495+
continue;
1496+
// We iterate the instructions in the basic block in a deterministic order
1497+
// and use this order to perform the load forwarding.
1498+
//
1499+
// NOTE: we could end up with different SIL depending on the ordering load
1500+
// forwarding is performed.
1501+
for (auto I = B.rbegin(), E = B.rend(); I != E; ++I) {
1502+
auto Iter = Loads.find(&*I);
1503+
if (Iter == Loads.end())
1504+
continue;
1505+
DEBUG(llvm::dbgs() << "Replacing " << SILValue(Iter->first) << "With "
1506+
<< Iter->second);
14941507
SILChanged = true;
1495-
F.first->replaceAllUsesWith(F.second);
1496-
InstsToDelete.insert(F.first);
1508+
Iter->first->replaceAllUsesWith(Iter->second);
1509+
InstsToDelete.insert(Iter->first);
14971510
++NumForwardedLoads;
14981511
}
14991512
}

test/SILOptimizer/redundant_load_elim.sil

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,3 +1128,21 @@ bb0(%0 : $AB):
11281128
%4 = tuple ()
11291129
return %4 : $()
11301130
}
1131+
1132+
// Make sure we have a deterministic forward ordering and also both loads are forwarded.
1133+
//
1134+
// CHECK-LABEL: sil @load_store_deterministic_forwarding
1135+
// CHECK: bb0
1136+
// CHECK-NEXT: [[VAL:%.*]] = integer_literal $Builtin.Int64, 0
1137+
// CHECK-NEXT: store
1138+
// CHECK-NEXT: store
1139+
// CHECK-NEXT: return [[VAL]] : $Builtin.Int64
1140+
sil @load_store_deterministic_forwarding : $@convention(thin) (@inout Builtin.Int64, @inout Builtin.Int64) -> (Builtin.Int64) {
1141+
bb0(%0 : $*Builtin.Int64, %1 : $*Builtin.Int64):
1142+
%2 = integer_literal $Builtin.Int64, 0
1143+
store %2 to %0 : $*Builtin.Int64
1144+
%3 = load %0 : $*Builtin.Int64
1145+
store %3 to %1: $*Builtin.Int64
1146+
%4 = load %1 : $*Builtin.Int64
1147+
return %4 : $Builtin.Int64
1148+
}

0 commit comments

Comments
 (0)