ART: Fix wide stores in Optimizing
SsaBuilder::VisitStoreLocal did not take into account the following:
(a) when storing a wide value, the high vreg must be invalidated,
(b) when storing into the high vreg of a wide value, the low vreg
must be invalidated.
Both situations cause overestimation of liveness but only (b) has
implications on correctness. CodeGenerator::EmitEnvironment will skip
the high vreg, causing deoptimizing and try/catch to load a wrong
value for that vreg.
In order to fix this bug, several changes had to be made to the
SsaBuilder:
(1) phis need to be initialized with a type which matches its
inputs' size,
(2) eagerly created loop header phis may end up being undefined
because of their corresponding vregs being invalidated inside
the loop; these are marked dead during input setting,
(3) the entire SSA-building algorithm should never revive an
undefined loop header phi.
Bug: 25677992
Bug: https://code.google.com/p/android/issues/detail?id=194022
Change-Id: Id8a852e38c3f5ff1c2e608b1aafd6d5ac8311e32
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index a5ea154..9f979ed 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4313,9 +4313,13 @@
: HInstruction(SideEffects::None(), dex_pc),
inputs_(number_of_inputs, arena->Adapter(kArenaAllocPhiInputs)),
reg_number_(reg_number),
- type_(type),
- is_live_(false),
+ type_(ToPhiType(type)),
+ // Phis are constructed live and marked dead if conflicting or unused.
+ // Individual steps of SsaBuilder should assume that if a phi has been
+ // marked dead, it can be ignored and will be removed by SsaPhiElimination.
+ is_live_(true),
can_be_null_(true) {
+ DCHECK_NE(type_, Primitive::kPrimVoid);
}
// Returns a type equivalent to the given `type`, but that a `HPhi` can hold.