From 82c93a5ea38f57fdc977b1d88c2b964fa84c7f7c Mon Sep 17 00:00:00 2001 From: Santiago Aboy Solanes Date: Wed, 25 Oct 2023 14:25:05 +0100 Subject: Make periodic loop optimization safe from overflow The trip number is calculated by doing: ((end - start) + (step - 1)) / step (Note that we add step - 1 as a way of doing ceiling). This way of calculating can overflow and produce the wrong result if e.g. end and start are in opposite sides of the spectrum. We can add checks to make sure that the calculation doesn't overflow. Bug: 256858062 Fixes: 256858062 Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing Change-Id: Ib2868406d2aa8f106dab06c0b44ef1b6208ef41a --- compiler/optimizing/induction_var_range.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'compiler/optimizing/induction_var_range.cc') diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc index b1f33abdf8..b54507a03c 100644 --- a/compiler/optimizing/induction_var_range.cc +++ b/compiler/optimizing/induction_var_range.cc @@ -1359,6 +1359,15 @@ bool InductionVarRange::GenerateLastValuePeriodic(const HBasicBlock* context, HInstruction* x = nullptr; HInstruction* y = nullptr; HInstruction* t = nullptr; + + // Overflows when the stride is equal to `1` are fine since the periodicity is + // `2` and the lowest bit is the same. Similar with `-1`. + auto allow_potential_overflow = [&]() { + int64_t stride_value = 0; + return IsConstant(context, loop, trip->op_a->op_b, kExact, &stride_value) && + (stride_value == 1 || stride_value == -1); + }; + if (period == 2 && GenerateCode(context, loop, @@ -1383,7 +1392,8 @@ bool InductionVarRange::GenerateLastValuePeriodic(const HBasicBlock* context, graph, block, /*is_min=*/ false, - graph ? &t : nullptr)) { + graph ? &t : nullptr, + allow_potential_overflow())) { // During actual code generation (graph != nullptr), generate is_even ? x : y. if (graph != nullptr) { DataType::Type type = trip->type; -- cgit v1.2.3-59-g8ed1b