Fixed bug in relying on precise FP in periodic sequence.

Rationale:
FP arithmetic is not always precise, so relying on FP
period sequences to "compute back" precisely is not
valid; when all values in the period are "fetches"
however, the rotation is precise.

Bug found by fuzz testing. With regression test.

Bug: 62196559
Test: test-art-host
Change-Id: Ie8f6b965b1921ff2762b90eebb8c20503c44c6bb
diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc
index 7c833cf..c0ec58f 100644
--- a/compiler/optimizing/induction_var_range.cc
+++ b/compiler/optimizing/induction_var_range.cc
@@ -1132,11 +1132,27 @@
                                                   /*out*/bool* needs_taken_test) const {
   DCHECK(info != nullptr);
   DCHECK_EQ(info->induction_class, HInductionVarAnalysis::kPeriodic);
-  // Count period.
+  // Count period and detect all-invariants.
   int64_t period = 1;
-  for (HInductionVarAnalysis::InductionInfo* p = info;
-       p->induction_class == HInductionVarAnalysis::kPeriodic;
-       p = p->op_b, ++period) {}
+  bool all_invariants = true;
+  HInductionVarAnalysis::InductionInfo* p = info;
+  for (; p->induction_class == HInductionVarAnalysis::kPeriodic; p = p->op_b, ++period) {
+    DCHECK_EQ(p->op_a->induction_class, HInductionVarAnalysis::kInvariant);
+    if (p->op_a->operation != HInductionVarAnalysis::kFetch) {
+      all_invariants = false;
+    }
+  }
+  DCHECK_EQ(p->induction_class, HInductionVarAnalysis::kInvariant);
+  if (p->operation != HInductionVarAnalysis::kFetch) {
+    all_invariants = false;
+  }
+  // Don't rely on FP arithmetic to be precise, unless the full period
+  // consist of pre-computed expressions only.
+  if (info->type == Primitive::kPrimFloat || info->type == Primitive::kPrimDouble) {
+    if (!all_invariants) {
+      return false;
+    }
+  }
   // Handle any periodic(x, periodic(.., y)) for known maximum index value m.
   int64_t m = 0;
   if (IsConstant(trip->op_a, kExact, &m) && m >= 1) {