From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 8BC283858D28 for ; Sun, 31 Jul 2022 18:12:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8BC283858D28 Received: from mail-oo1-f69.google.com (mail-oo1-f69.google.com [209.85.161.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-472-rDVBR1SvMjGg6SL4zCamYQ-1; Sun, 31 Jul 2022 14:12:06 -0400 X-MC-Unique: rDVBR1SvMjGg6SL4zCamYQ-1 Received: by mail-oo1-f69.google.com with SMTP id b3-20020a4a8783000000b0043895cf5c9cso2875320ooi.9 for ; Sun, 31 Jul 2022 11:12:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc; bh=+ljk5MULzDatM5S3N0mwFZX279GbwmF1oFmAyEl4qSw=; b=LBFjSH0c87Iz78ed+VOS3awLW31pm/ywmaowxkp6t6k3+aMzfcUb92jWPAnToavxTJ wblZd/ptWMopHvDJBY2f8yguejBfh9Pkimlwmm1MQBokHOs4Z9j8c57LoKPDDUXOkXhO tmhLtDOaFClpV7FuIeP5cYfwH4gkaufmO77gt5zMnw9FOpVYrbNe+mjy3u61JBJnAjOl ddVPYkhwqofeMmAExcS7aeHyO1xYigPh8aYuMbgCd7S0ejczryXWZPM+Pz8skvAepfF6 zz8TQ9W6E8CSE6oyGdeSFij0uL1OU2PJKfKl7S1XN3w/dhMZ50NuLPDTLsWwveRFVzsB KVhg== X-Gm-Message-State: AJIora+VZUZ8mbaXluIiz7/ENvpnqISaDorr4msT0fv+KG7U4FQHx/GL otIYIvlLxCti/CXLacMz4xfBQi17IitJ7UWFq2c0dzhyHxcK6T3m1VV2Fn7tvVmx8YEbHGr8Ue2 9KSnRsuMkU6cklio+W3RTjMV5ZICxwCVYVg== X-Received: by 2002:a05:6870:210b:b0:10b:ed11:4e2d with SMTP id f11-20020a056870210b00b0010bed114e2dmr6095699oae.265.1659291125677; Sun, 31 Jul 2022 11:12:05 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tHUQK+SjpBCtX6m4myfTWEm1D8zYdoMcJkUZ4iFax5qcscVxZ/GeNR2j1KDa1BcBcaTQBJL+yJqri4lLUQU/w= X-Received: by 2002:a05:6870:210b:b0:10b:ed11:4e2d with SMTP id f11-20020a056870210b00b0010bed114e2dmr6095686oae.265.1659291125258; Sun, 31 Jul 2022 11:12:05 -0700 (PDT) MIME-Version: 1.0 References: <20220725184951.2202379-1-aldyh@redhat.com> In-Reply-To: <20220725184951.2202379-1-aldyh@redhat.com> From: Aldy Hernandez Date: Sun, 31 Jul 2022 20:11:53 +0200 Message-ID: Subject: Re: [RFA] Implement basic range operators to enable floating point VRP. To: GCC patches , "MacLeod, Andrew" Cc: Jeff Law , Richard Biener , Jakub Jelinek , Roger Sayle X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="0000000000001a0d6605e51dd24e" X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Jul 2022 18:12:14 -0000 --0000000000001a0d6605e51dd24e Content-Type: text/plain; charset="UTF-8" PING Andrew, anyone, would you mind giving this a once over? I realize reviewing ranger's range-op code is not on anyone's list of priorities, but I could use a sanity check. The patch is sufficiently self-contained to easily catch anything caused by it, and I'd like to commit earlier in the week to have enough time to field any possible fallout before I take a few days off next week. Updated patch attached. Thanks. Aldy On Mon, Jul 25, 2022 at 8:50 PM Aldy Hernandez wrote: > > Without further ado, here is the implementation for floating point > range operators, plus the switch to enable all ranger clients to > handle floats. > > These are bare bone implementations good enough for relation operators > to work, while keeping the NAN bits up to date in the frange. There > is also minimal support for keeping track of +-INF when it is obvious. > > I have included some basic tests to help get a feel of what is > ultimately handled. > > Since range-ops is the domain specific core of ranger, I think its > best if a global maintainer or an FP expert could review this. > > OK for trunk? > > Tested on x86-64 Linux. > > p.s. I haven't done extensive testing in DOM, but with this we're mighty > close for the forward threader there to be replaceable with the backward > threader, thus removing the last use of the forward threader. > > gcc/ChangeLog: > > * range-op-float.cc (finite_operands_p): New. > (frelop_early_resolve): New. > (default_frelop_fold_range): New. > (class foperator_equal): New. > (class foperator_not_equal): New. > (class foperator_lt): New. > (class foperator_le): New. > (class foperator_gt): New. > (class foperator_ge): New. > (class foperator_unordered): New. > (class foperator_ordered): New. > (class foperator_relop_unknown): New. > (floating_op_table::floating_op_table): Add above classes to > floating op table. > * value-range.h (frange::supports_p): Enable. > > gcc/testsuite/ChangeLog: > > * g++.dg/opt/pr94589-2.C: Add notes. > * gcc.dg/tree-ssa/vrp-float-1.c: New test. > * gcc.dg/tree-ssa/vrp-float-11.c: New test. > * gcc.dg/tree-ssa/vrp-float-3.c: New test. > * gcc.dg/tree-ssa/vrp-float-4.c: New test. > * gcc.dg/tree-ssa/vrp-float-6.c: New test. > * gcc.dg/tree-ssa/vrp-float-7.c: New test. > * gcc.dg/tree-ssa/vrp-float-8.c: New test. > --- > gcc/range-op-float.cc | 564 +++++++++++++++++++ > gcc/testsuite/g++.dg/opt/pr94589-2.C | 25 + > gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c | 19 + > gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c | 26 + > gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c | 18 + > gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c | 16 + > gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c | 20 + > gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c | 14 + > gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c | 26 + > gcc/value-range.h | 3 +- > 10 files changed, 729 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c > > diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc > index 8e9d83e3827..d94ff6f915a 100644 > --- a/gcc/range-op-float.cc > +++ b/gcc/range-op-float.cc > @@ -150,6 +150,50 @@ range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) cons > return VREL_VARYING; > } > > +// Return TRUE if OP1 and OP2 are known to be free of NANs. > + > +static inline bool > +finite_operands_p (const frange &op1, const frange &op2) > +{ > + return (flag_finite_math_only > + || (op1.get_nan ().no_p () > + && op2.get_nan ().no_p ())); > +} > + > +// Floating version of relop_early_resolve that takes into account NAN > +// and -ffinite-math-only. > + > +inline bool > +frelop_early_resolve (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel, relation_kind my_rel) > +{ > + // If either operand is undefined, return VARYING. > + if (empty_range_varying (r, type, op1, op2)) > + return true; > + > + // We can fold relations from the oracle when we know both operands > + // are free of NANs, or when -ffinite-math-only. > + return (finite_operands_p (op1, op2) > + && relop_early_resolve (r, type, op1, op2, rel, my_rel)); > +} > + > +// Default implementation of fold_range for relational operators. > +// This amounts to passing on any known relations from the oracle, iff > +// we know the operands are not NAN or -ffinite-math-only holds. > + > +static inline bool > +default_frelop_fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel, relation_kind my_rel) > +{ > + if (frelop_early_resolve (r, type, op1, op2, rel, my_rel)) > + return true; > + > + r.set_varying (type); > + return true; > +} > + > class foperator_identity : public range_operator_float > { > using range_operator_float::fold_range; > @@ -172,6 +216,509 @@ class foperator_identity : public range_operator_float > public: > } fop_identity; > > +class foperator_equal : public range_operator_float > +{ > + using range_operator_float::fold_range; > + using range_operator_float::op1_range; > + using range_operator_float::op2_range; > + > + bool fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel) const final override > + { > + return default_frelop_fold_range (r, type, op1, op2, rel, VREL_EQ); > + } > + relation_kind op1_op2_relation (const irange &lhs) const final override > + { > + return equal_op1_op2_relation (lhs); > + } > + bool op1_range (frange &r, tree type, > + const irange &lhs, const frange &op2, > + relation_kind rel) const final override; > + bool op2_range (frange &r, tree type, > + const irange &lhs, const frange &op1, > + relation_kind rel) const final override > + { > + return op1_range (r, type, lhs, op1, rel); > + } > +} fop_equal; > + > +bool > +foperator_equal::op1_range (frange &r, tree type, > + const irange &lhs, > + const frange &op2 ATTRIBUTE_UNUSED, > + relation_kind rel) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // The TRUE side of op1 == op2 implies op1 is !NAN. > + r.set_nan (fp_prop::NO); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + // The FALSE side of op1 ORDERED op1 implies op1 is a NAN. > + if (rel == VREL_EQ) > + r.set_nan (fp_prop::YES); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +class foperator_not_equal : public range_operator_float > +{ > + using range_operator_float::fold_range; > + using range_operator_float::op1_range; > + > + bool fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel) const final override > + { > + return default_frelop_fold_range (r, type, op1, op2, rel, VREL_NE); > + } > + relation_kind op1_op2_relation (const irange &lhs) const final override > + { > + return not_equal_op1_op2_relation (lhs); > + } > + bool op1_range (frange &r, tree type, > + const irange &lhs, const frange &op2, > + relation_kind rel) const final override; > +} fop_not_equal; > + > +bool > +foperator_not_equal::op1_range (frange &r, tree type, > + const irange &lhs, > + const frange &op2 ATTRIBUTE_UNUSED, > + relation_kind) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + // The FALSE side of op1 != op2 implies op1 is !NAN. > + r.set_nan (fp_prop::NO); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +class foperator_lt : public range_operator_float > +{ > + using range_operator_float::fold_range; > + using range_operator_float::op1_range; > + using range_operator_float::op2_range; > + > + bool fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel) const final override > + { > + return default_frelop_fold_range (r, type, op1, op2, rel, VREL_LT); > + } > + relation_kind op1_op2_relation (const irange &lhs) const final override > + { > + return lt_op1_op2_relation (lhs); > + } > + bool op1_range (frange &r, tree type, > + const irange &lhs, const frange &op2, > + relation_kind rel) const final override; > + bool op2_range (frange &r, tree type, > + const irange &lhs, const frange &op1, > + relation_kind rel) const final override; > +} fop_lt; > + > +bool > +foperator_lt::op1_range (frange &r, > + tree type, > + const irange &lhs, > + const frange &op2 ATTRIBUTE_UNUSED, > + relation_kind) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // The TRUE side of op1 < op2 implies op1 is !NAN and !INF. > + r.set_nan (fp_prop::NO); > + r.set_inf (fp_prop::NO); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +bool > +foperator_lt::op2_range (frange &r, > + tree type, > + const irange &lhs, > + const frange &op1 ATTRIBUTE_UNUSED, > + relation_kind) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // The TRUE side of op1 < op2 implies op2 is !NAN and !NINF. > + r.set_nan (fp_prop::NO); > + r.set_ninf (fp_prop::NO); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +class foperator_le : public range_operator_float > +{ > + using range_operator_float::fold_range; > + using range_operator_float::op1_range; > + using range_operator_float::op2_range; > + > + bool fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel) const final override > + { > + return default_frelop_fold_range (r, type, op1, op2, rel, VREL_LE); > + } > + relation_kind op1_op2_relation (const irange &lhs) const final override > + { > + return le_op1_op2_relation (lhs); > + } > + bool op1_range (frange &r, tree type, > + const irange &lhs, const frange &op2, > + relation_kind rel) const final override; > + bool op2_range (frange &r, tree type, > + const irange &lhs, const frange &op1, > + relation_kind rel) const final override > + { > + return op1_range (r, type, lhs, op1, rel); > + } > +} fop_le; > + > +bool > +foperator_le::op1_range (frange &r, > + tree type, > + const irange &lhs, > + const frange &op2 ATTRIBUTE_UNUSED, > + relation_kind) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // The TRUE side of op1 <= op2 implies op1 is !NAN. > + r.set_nan (fp_prop::NO); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +class foperator_gt : public range_operator_float > +{ > + using range_operator_float::fold_range; > + using range_operator_float::op1_range; > + using range_operator_float::op2_range; > + > + bool fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel) const final override > + { > + return default_frelop_fold_range (r, type, op1, op2, rel, VREL_GT); > + } > + relation_kind op1_op2_relation (const irange &lhs) const final override > + { > + return gt_op1_op2_relation (lhs); > + } > + bool op1_range (frange &r, tree type, > + const irange &lhs, const frange &op2, > + relation_kind rel) const final override; > + bool op2_range (frange &r, tree type, > + const irange &lhs, const frange &op1, > + relation_kind rel) const final override; > +} fop_gt; > + > +bool > +foperator_gt::op1_range (frange &r, > + tree type, > + const irange &lhs, > + const frange &op2 ATTRIBUTE_UNUSED, > + relation_kind) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // The TRUE side of op1 > op2 implies op1 is !NAN and !NINF. > + r.set_nan (fp_prop::NO); > + r.set_ninf (fp_prop::NO); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +bool > +foperator_gt::op2_range (frange &r, > + tree type, > + const irange &lhs, > + const frange &op1 ATTRIBUTE_UNUSED, > + relation_kind) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // The TRUE side of op1 > op2 implies op2 is !NAN and !INF. > + r.set_nan (fp_prop::NO); > + r.set_inf (fp_prop::NO); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +class foperator_ge : public range_operator_float > +{ > + using range_operator_float::fold_range; > + using range_operator_float::op1_range; > + using range_operator_float::op2_range; > + > + bool fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel) const final override > + { > + return default_frelop_fold_range (r, type, op1, op2, rel, VREL_GE); > + } > + relation_kind op1_op2_relation (const irange &lhs) const final override > + { > + return ge_op1_op2_relation (lhs); > + } > + bool op1_range (frange &r, tree type, > + const irange &lhs, const frange &op2, > + relation_kind rel) const final override; > + bool op2_range (frange &r, tree type, > + const irange &lhs, const frange &op1, > + relation_kind rel) const final override > + { > + return op1_range (r, type, lhs, op1, rel); > + } > +} fop_ge; > + > +bool > +foperator_ge::op1_range (frange &r, > + tree type, > + const irange &lhs, > + const frange &op2 ATTRIBUTE_UNUSED, > + relation_kind) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // The TRUE side of op1 >= op2 implies op1 is !NAN. > + r.set_nan (fp_prop::NO); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +// UNORDERED_EXPR comparison. > + > +class foperator_unordered : public range_operator_float > +{ > + using range_operator_float::fold_range; > + using range_operator_float::op1_range; > + using range_operator_float::op2_range; > + > +public: > + bool fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel) const final override; > + bool op1_range (frange &r, tree type, > + const irange &lhs, const frange &op2, > + relation_kind rel) const final override; > + bool op2_range (frange &r, tree type, > + const irange &lhs, const frange &op1, > + relation_kind rel) const final override > + { > + return op1_range (r, type, lhs, op1, rel); > + } > +} fop_unordered; > + > +bool > +foperator_unordered::fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind) const > +{ > + // UNORDERED is TRUE if either operand is a NAN. > + if (op1.get_nan ().yes_p () || op2.get_nan ().yes_p ()) > + r = range_true (type); > + // UNORDERED is FALSE if neither operand is a NAN. > + else if (op1.get_nan ().no_p () && op2.get_nan ().no_p ()) > + r = range_false (type); > + else > + r = range_true_and_false (type); > + return true; > +} > + > +bool > +foperator_unordered::op1_range (frange &r, tree type, > + const irange &lhs, > + const frange &op2 ATTRIBUTE_UNUSED, > + relation_kind) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // Since at least one operand must be NAN, if one of them is > + // not, the other must be. > + if (op2.get_nan ().no_p ()) > + r.set_nan (fp_prop::YES); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + // A false UNORDERED means both operands are !NAN. > + r.set_nan (fp_prop::NO); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +// ORDERED_EXPR comparison. > + > +class foperator_ordered : public range_operator_float > +{ > + using range_operator_float::fold_range; > + using range_operator_float::op1_range; > + using range_operator_float::op2_range; > + > +public: > + bool fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind rel) const final override; > + bool op1_range (frange &r, tree type, > + const irange &lhs, const frange &op2, > + relation_kind rel) const final override; > + bool op2_range (frange &r, tree type, > + const irange &lhs, const frange &op1, > + relation_kind rel) const final override > + { > + return op1_range (r, type, lhs, op1, rel); > + } > +} fop_ordered; > + > +bool > +foperator_ordered::fold_range (irange &r, tree type, > + const frange &op1, const frange &op2, > + relation_kind) const > +{ > + // ORDERED is TRUE if neither operand is a NAN. > + if (op1.get_nan ().no_p () && op2.get_nan ().no_p ()) > + r = range_true (type); > + // ORDERED is FALSE if either operand is a NAN. > + else if (op1.get_nan ().yes_p () || op2.get_nan ().yes_p ()) > + r = range_false (type); > + else > + r = range_true_and_false (type); > + return true; > +} > + > +bool > +foperator_ordered::op1_range (frange &r, tree type, > + const irange &lhs, > + const frange &op2 ATTRIBUTE_UNUSED, > + relation_kind rel) const > +{ > + switch (get_bool_state (r, lhs, type)) > + { > + case BRS_TRUE: > + r.set_varying (type); > + // The TRUE side of op1 UNORDERED op2 implies op1 is !NAN. > + r.set_nan (fp_prop::NO); > + break; > + > + case BRS_FALSE: > + r.set_varying (type); > + // The FALSE side of op1 UNORDERED op1 implies op1 is !NAN. > + if (rel == VREL_EQ) > + r.set_nan (fp_prop::NO); > + break; > + > + default: > + break; > + } > + return true; > +} > + > +// Placeholder for unimplemented relational operators. > + > +class foperator_relop_unknown : public range_operator_float > +{ > + using range_operator_float::fold_range; > + > +public: > + bool fold_range (irange &r, tree type, > + const frange &, const frange &, > + relation_kind) const final override > + { > + r.set_varying (type); > + return true; > + } > +} fop_relop_unknown; > + > > // Instantiate a range_op_table for floating point operations. > static floating_op_table global_floating_table; > @@ -185,6 +732,23 @@ floating_op_table::floating_op_table () > set (PAREN_EXPR, fop_identity); > set (OBJ_TYPE_REF, fop_identity); > set (REAL_CST, fop_identity); > + > + // All the relational operators are expected to work, because the > + // calculation of ranges on outgoing edges expect the handlers to be > + // present. > + set (EQ_EXPR, fop_equal); > + set (NE_EXPR, fop_not_equal); > + set (LT_EXPR, fop_lt); > + set (LE_EXPR, fop_le); > + set (GT_EXPR, fop_gt); > + set (GE_EXPR, fop_ge); > + set (UNLE_EXPR, fop_relop_unknown); > + set (UNLT_EXPR, fop_relop_unknown); > + set (UNGE_EXPR, fop_relop_unknown); > + set (UNGT_EXPR, fop_relop_unknown); > + set (UNEQ_EXPR, fop_relop_unknown); > + set (ORDERED_EXPR, fop_ordered); > + set (UNORDERED_EXPR, fop_unordered); > } > > // Return a pointer to the range_operator_float instance, if there is > diff --git a/gcc/testsuite/g++.dg/opt/pr94589-2.C b/gcc/testsuite/g++.dg/opt/pr94589-2.C > index e9ef84b1912..1caa725061e 100644 > --- a/gcc/testsuite/g++.dg/opt/pr94589-2.C > +++ b/gcc/testsuite/g++.dg/opt/pr94589-2.C > @@ -4,6 +4,31 @@ > // { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 12 "optimized" } } > // { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 5\\.0" 12 "optimized" } } > > +/* This is failing on f5() because the spaceship operator is no longer > + folded. What happens is that evrp folds away the final condition > + here as always true. > + > + : > + if (i_2(D) != j_4(D)) > + goto ; [INV] > + else > + goto ; [INV] > + > + : > + if (i_2(D) >= j_4(D)) > + goto ; [INV] > + else > + goto ; [INV] > + > + : > + if (i_2(D) > j_4(D)) <<== ALWAYS TRUE > + goto ; [INV] > + else > + goto ; [INV] > + > + This causes phiopt to no longer be able to fold the total sequence > + into i_2 >= j_4. */ > + > #include > > #define A __attribute__((noipa)) > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c > new file mode 100644 > index 00000000000..88faf72ac42 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c > @@ -0,0 +1,19 @@ > +// { dg-do compile } > +// { dg-options "-O2 -fdisable-tree-ethread -fdisable-tree-fre1 -fdump-tree-evrp" } > + > +void bar (); > +void george (); > + > +float > +foo (float x, float y) > +{ > + if (x == x) > + { > + if (x > y) > + bar(); > + if (x == x) > + george(); > + } > +} > + > +// { dg-final { scan-tree-dump-times "Folding predicate x_*to 1" "evrp" 1 } } > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c > new file mode 100644 > index 00000000000..2f4dc8757a3 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c > @@ -0,0 +1,26 @@ > +// { dg-do compile } > +// { dg-options "-O2 -fno-thread-jumps -fdump-tree-evrp" } > + > +extern void link_error (); > + > +void fast_sqrt (float); > + > +float test (float x) > +{ > + float y = x*x; > + if (y >= 0.f) > + { > + if (__builtin_isnan (y)) > + link_error (); > + else > + fast_sqrt (y); > + > + if (!__builtin_isnan (y)) > + fast_sqrt (y); > + else > + link_error (); > + } > +} > + > +// { dg-final { scan-tree-dump-times "fast_sqrt" 2 "evrp" } } > +// { dg-final { scan-tree-dump-not "link_error" "evrp" } } > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c > new file mode 100644 > index 00000000000..c659abb6cc0 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c > @@ -0,0 +1,18 @@ > +// { dg-do compile } > +// { dg-options "-O2 -fdisable-tree-ethread -fdump-tree-evrp" } > + > +void link_error (); > + > +void > +foo (double x, double y) > +{ > + if (x == y) > + { > + if (__builtin_isnan (x)) > + link_error (); > + if (__builtin_isnan (y)) > + link_error (); > + } > +} > + > +// { dg-final { scan-tree-dump-not "link_error" "evrp" } } > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c > new file mode 100644 > index 00000000000..86436742e0a > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c > @@ -0,0 +1,16 @@ > +// { dg-do compile } > +// { dg-options "-O2 -fdisable-tree-ethread -fdump-tree-evrp" } > + > +void link_error (); > + > +void > +foo (double x, double y) > +{ > + if (x > y) > + { > + if (__builtin_isnan (x) || __builtin_isnan (y)) > + link_error (); > + } > +} > + > +// { dg-final { scan-tree-dump-not "link_error" "evrp" } } > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c > new file mode 100644 > index 00000000000..145d1861804 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c > @@ -0,0 +1,20 @@ > +// { dg-do compile } > +// { dg-options "-O2 -fdisable-tree-ethread -fdump-tree-evrp" } > + > +void bar (); > + > +void > +foo (double x, double y) > +{ > + if (x > y) > + ; > + else if (!__builtin_isnan (x) && !__builtin_isnan (y)) > + { > + // If x and y are not NAN, the x <= y relationship holds, and the > + // following conditional can be folded away. > + if (x <= y) > + bar (); > + } > +} > + > +// { dg-final { scan-tree-dump-times "Folding predicate x_.* <= y_.* to 1" 1 "evrp" } } > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c > new file mode 100644 > index 00000000000..92af87091a8 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c > @@ -0,0 +1,14 @@ > +// { dg-do compile } > +// { dg-options "-O2 -fno-tree-forwprop -fno-tree-ccp -fno-tree-fre -fdump-tree-evrp" } > + > +extern void link_error (); > + > +void > +foo () > +{ > + float z = 0.0; > + if (__builtin_isnan (z)) > + link_error (); > +} > + > +// { dg-final { scan-tree-dump-not "link_error" "evrp" } } > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c > new file mode 100644 > index 00000000000..9170150d453 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c > @@ -0,0 +1,26 @@ > +// { dg-do compile } > +// { dg-options "-O2 -fno-thread-jumps -fdump-tree-evrp" } > + > +extern void link_error (); > + > +void fast_sqrt (float); > + > +float test (float x) > +{ > + float y = x*x; > + if (y >= 0.f) > + { > + if (__builtin_isnan (y)) > + link_error (); > + else > + fast_sqrt (y); > + > + if (!__builtin_isnan (y)) > + fast_sqrt (y); > + else > + link_error (); > + } > +} > + > +// { dg-final { scan-tree-dump-times "fast_sqrt" 2 "evrp" } } > +// { dg-final { scan-tree-dump-not "link_error" "evrp" } } > diff --git a/gcc/value-range.h b/gcc/value-range.h > index e43fbe30f27..478f165e02b 100644 > --- a/gcc/value-range.h > +++ b/gcc/value-range.h > @@ -338,8 +338,7 @@ public: > frange (const frange &); > static bool supports_p (tree type) > { > - // Disabled until floating point range-ops come live. > - return 0 && SCALAR_FLOAT_TYPE_P (type); > + return SCALAR_FLOAT_TYPE_P (type); > } > virtual tree type () const override; > virtual void set (tree, tree, value_range_kind = VR_RANGE) override; > -- > 2.36.1 > --0000000000001a0d6605e51dd24e Content-Type: text/x-patch; charset="US-ASCII"; name="0004-Implement-basic-range-operators-to-enable-floating-p.patch" Content-Disposition: attachment; filename="0004-Implement-basic-range-operators-to-enable-floating-p.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_l69myk1s0 RnJvbSBmOThhZjc5OGQzZDY2ZDA2OTU2NWVhNTk2NmEyODc2ZWFkMGQ1Mzg2IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBBbGR5IEhlcm5hbmRleiA8YWxkeWhAcmVkaGF0LmNvbT4KRGF0 ZTogTW9uLCAyNSBKdWwgMjAyMiAxNjo0Nzo0OCArMDIwMApTdWJqZWN0OiBbUEFUQ0hdIEltcGxl bWVudCBiYXNpYyByYW5nZSBvcGVyYXRvcnMgdG8gZW5hYmxlIGZsb2F0aW5nIHBvaW50IFZSUC4K CldpdGhvdXQgZnVydGhlciBhZG8sIGhlcmUgaXMgdGhlIGltcGxlbWVudGF0aW9uIGZvciBmbG9h dGluZyBwb2ludApyYW5nZSBvcGVyYXRvcnMsIHBsdXMgdGhlIHN3aXRjaCB0byBlbmFibGUgYWxs IHJhbmdlciBjbGllbnRzIHRvCmhhbmRsZSBmbG9hdHMuCgpUaGVzZSBhcmUgYmFyZSBib25lIGlt cGxlbWVudGF0aW9ucyBnb29kIGVub3VnaCBmb3IgcmVsYXRpb24gb3BlcmF0b3JzCnRvIHdvcmss IHdoaWxlIGtlZXBpbmcgdGhlIE5BTiBiaXRzIHVwIHRvIGRhdGUgaW4gdGhlIGZyYW5nZS4gIFRo ZXJlCmlzIGFsc28gbWluaW1hbCBzdXBwb3J0IGZvciBrZWVwaW5nIHRyYWNrIG9mICstSU5GIHdo ZW4gaXQgaXMgb2J2aW91cy4KClRlc3RlZCBvbiB4ODYtNjQgTGludXguCgpnY2MvQ2hhbmdlTG9n OgoKCSogcmFuZ2Utb3AtZmxvYXQuY2MgKGZpbml0ZV9vcGVyYW5kc19wKTogTmV3LgoJKGZyZWxv cF9lYXJseV9yZXNvbHZlKTogTmV3LgoJKGRlZmF1bHRfZnJlbG9wX2ZvbGRfcmFuZ2UpOiBOZXcu CgkoY2xhc3MgZm9wZXJhdG9yX2VxdWFsKTogTmV3LgoJKGNsYXNzIGZvcGVyYXRvcl9ub3RfZXF1 YWwpOiBOZXcuCgkoY2xhc3MgZm9wZXJhdG9yX2x0KTogTmV3LgoJKGNsYXNzIGZvcGVyYXRvcl9s ZSk6IE5ldy4KCShjbGFzcyBmb3BlcmF0b3JfZ3QpOiBOZXcuCgkoY2xhc3MgZm9wZXJhdG9yX2dl KTogTmV3LgoJKGNsYXNzIGZvcGVyYXRvcl91bm9yZGVyZWQpOiBOZXcuCgkoY2xhc3MgZm9wZXJh dG9yX29yZGVyZWQpOiBOZXcuCgkoY2xhc3MgZm9wZXJhdG9yX3JlbG9wX3Vua25vd24pOiBOZXcu CgkoZmxvYXRpbmdfb3BfdGFibGU6OmZsb2F0aW5nX29wX3RhYmxlKTogQWRkIGFib3ZlIGNsYXNz ZXMgdG8KCWZsb2F0aW5nIG9wIHRhYmxlLgoJKiB2YWx1ZS1yYW5nZS5oIChmcmFuZ2U6OnN1cHBv cnRzX3ApOiBFbmFibGUuCgpnY2MvdGVzdHN1aXRlL0NoYW5nZUxvZzoKCgkqIGcrKy5kZy9vcHQv cHI5NDU4OS0yLkM6IFhGQUlMLgoJKiBnY2MuZGcvdHJlZS1zc2EvdnJwLWZsb2F0LTEuYzogTmV3 IHRlc3QuCgkqIGdjYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtMTEuYzogTmV3IHRlc3QuCgkqIGdj Yy5kZy90cmVlLXNzYS92cnAtZmxvYXQtMy5jOiBOZXcgdGVzdC4KCSogZ2NjLmRnL3RyZWUtc3Nh L3ZycC1mbG9hdC00LmM6IE5ldyB0ZXN0LgoJKiBnY2MuZGcvdHJlZS1zc2EvdnJwLWZsb2F0LTYu YzogTmV3IHRlc3QuCgkqIGdjYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtNy5jOiBOZXcgdGVzdC4K CSogZ2NjLmRnL3RyZWUtc3NhL3ZycC1mbG9hdC04LmM6IE5ldyB0ZXN0LgotLS0KIGdjYy9yYW5n ZS1vcC1mbG9hdC5jYyAgICAgICAgICAgICAgICAgICAgICAgIHwgNTY0ICsrKysrKysrKysrKysr KysrKysKIGdjYy90ZXN0c3VpdGUvZysrLmRnL29wdC9wcjk0NTg5LTIuQyAgICAgICAgIHwgICAy ICstCiBnY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtMS5jICB8ICAxOSAr CiBnY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtMTEuYyB8ICAyNiArCiBn Y2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtMy5jICB8ICAxOCArCiBnY2Mv dGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtNC5jICB8ICAxNiArCiBnY2MvdGVz dHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtNi5jICB8ICAyMCArCiBnY2MvdGVzdHN1 aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtNy5jICB8ICAxNCArCiBnY2MvdGVzdHN1aXRl L2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtOC5jICB8ICAyNiArCiBnY2MvdmFsdWUtcmFuZ2Uu aCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgMyArLQogMTAgZmlsZXMgY2hhbmdlZCwg NzA1IGluc2VydGlvbnMoKyksIDMgZGVsZXRpb25zKC0pCiBjcmVhdGUgbW9kZSAxMDA2NDQgZ2Nj L3Rlc3RzdWl0ZS9nY2MuZGcvdHJlZS1zc2EvdnJwLWZsb2F0LTEuYwogY3JlYXRlIG1vZGUgMTAw NjQ0IGdjYy90ZXN0c3VpdGUvZ2NjLmRnL3RyZWUtc3NhL3ZycC1mbG9hdC0xMS5jCiBjcmVhdGUg bW9kZSAxMDA2NDQgZ2NjL3Rlc3RzdWl0ZS9nY2MuZGcvdHJlZS1zc2EvdnJwLWZsb2F0LTMuYwog Y3JlYXRlIG1vZGUgMTAwNjQ0IGdjYy90ZXN0c3VpdGUvZ2NjLmRnL3RyZWUtc3NhL3ZycC1mbG9h dC00LmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBnY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92 cnAtZmxvYXQtNi5jCiBjcmVhdGUgbW9kZSAxMDA2NDQgZ2NjL3Rlc3RzdWl0ZS9nY2MuZGcvdHJl ZS1zc2EvdnJwLWZsb2F0LTcuYwogY3JlYXRlIG1vZGUgMTAwNjQ0IGdjYy90ZXN0c3VpdGUvZ2Nj LmRnL3RyZWUtc3NhL3ZycC1mbG9hdC04LmMKCmRpZmYgLS1naXQgYS9nY2MvcmFuZ2Utb3AtZmxv YXQuY2MgYi9nY2MvcmFuZ2Utb3AtZmxvYXQuY2MKaW5kZXggOGU5ZDgzZTM4MjcuLjRmYmQ5NmE3 NDc5IDEwMDY0NAotLS0gYS9nY2MvcmFuZ2Utb3AtZmxvYXQuY2MKKysrIGIvZ2NjL3JhbmdlLW9w LWZsb2F0LmNjCkBAIC0xNTAsNiArMTUwLDUwIEBAIHJhbmdlX29wZXJhdG9yX2Zsb2F0OjpvcDFf b3AyX3JlbGF0aW9uIChjb25zdCBpcmFuZ2UgJmxocyBBVFRSSUJVVEVfVU5VU0VEKSBjb25zCiAg IHJldHVybiBWUkVMX1ZBUllJTkc7CiB9CiAKKy8vIFJldHVybiBUUlVFIGlmIE9QMSBhbmQgT1Ay IGFyZSBrbm93biB0byBiZSBmcmVlIG9mIE5BTnMuCisKK3N0YXRpYyBpbmxpbmUgYm9vbAorZmlu aXRlX29wZXJhbmRzX3AgKGNvbnN0IGZyYW5nZSAmb3AxLCBjb25zdCBmcmFuZ2UgJm9wMikKK3sK KyAgcmV0dXJuIChmbGFnX2Zpbml0ZV9tYXRoX29ubHkKKwkgIHx8IChvcDEuZ2V0X25hbiAoKS5u b19wICgpCisJICAgICAgJiYgb3AyLmdldF9uYW4gKCkubm9fcCAoKSkpOworfQorCisvLyBGbG9h dGluZyB2ZXJzaW9uIG9mIHJlbG9wX2Vhcmx5X3Jlc29sdmUgdGhhdCB0YWtlcyBpbnRvIGFjY291 bnQgTkFOCisvLyBhbmQgLWZmaW5pdGUtbWF0aC1vbmx5LgorCitpbmxpbmUgYm9vbAorZnJlbG9w X2Vhcmx5X3Jlc29sdmUgKGlyYW5nZSAmciwgdHJlZSB0eXBlLAorCQkgICAgICBjb25zdCBmcmFu Z2UgJm9wMSwgY29uc3QgZnJhbmdlICZvcDIsCisJCSAgICAgIHJlbGF0aW9uX2tpbmQgcmVsLCBy ZWxhdGlvbl9raW5kIG15X3JlbCkKK3sKKyAgLy8gSWYgZWl0aGVyIG9wZXJhbmQgaXMgdW5kZWZp bmVkLCByZXR1cm4gVkFSWUlORy4KKyAgaWYgKGVtcHR5X3JhbmdlX3ZhcnlpbmcgKHIsIHR5cGUs IG9wMSwgb3AyKSkKKyAgICByZXR1cm4gdHJ1ZTsKKworICAvLyBXZSBjYW4gZm9sZCByZWxhdGlv bnMgZnJvbSB0aGUgb3JhY2xlIHdoZW4gd2Uga25vdyBib3RoIG9wZXJhbmRzCisgIC8vIGFyZSBm cmVlIG9mIE5BTnMsIG9yIHdoZW4gLWZmaW5pdGUtbWF0aC1vbmx5LgorICByZXR1cm4gKGZpbml0 ZV9vcGVyYW5kc19wIChvcDEsIG9wMikKKwkgICYmIHJlbG9wX2Vhcmx5X3Jlc29sdmUgKHIsIHR5 cGUsIG9wMSwgb3AyLCByZWwsIG15X3JlbCkpOworfQorCisvLyBEZWZhdWx0IGltcGxlbWVudGF0 aW9uIG9mIGZvbGRfcmFuZ2UgZm9yIHJlbGF0aW9uYWwgb3BlcmF0b3JzLgorLy8gVGhpcyBhbW91 bnRzIHRvIHBhc3Npbmcgb24gYW55IGtub3duIHJlbGF0aW9ucyBmcm9tIHRoZSBvcmFjbGUsIGlm ZgorLy8gd2Uga25vdyB0aGUgb3BlcmFuZHMgYXJlIG5vdCBOQU4gb3IgLWZmaW5pdGUtbWF0aC1v bmx5IGhvbGRzLgorCitzdGF0aWMgaW5saW5lIGJvb2wKK2RlZmF1bHRfZnJlbG9wX2ZvbGRfcmFu Z2UgKGlyYW5nZSAmciwgdHJlZSB0eXBlLAorCQkJICBjb25zdCBmcmFuZ2UgJm9wMSwgY29uc3Qg ZnJhbmdlICZvcDIsCisJCQkgIHJlbGF0aW9uX2tpbmQgcmVsLCByZWxhdGlvbl9raW5kIG15X3Jl bCkKK3sKKyAgaWYgKGZyZWxvcF9lYXJseV9yZXNvbHZlIChyLCB0eXBlLCBvcDEsIG9wMiwgcmVs LCBteV9yZWwpKQorICAgIHJldHVybiB0cnVlOworCisgIHIuc2V0X3ZhcnlpbmcgKHR5cGUpOwor ICByZXR1cm4gdHJ1ZTsKK30KKwogY2xhc3MgZm9wZXJhdG9yX2lkZW50aXR5IDogcHVibGljIHJh bmdlX29wZXJhdG9yX2Zsb2F0CiB7CiAgIHVzaW5nIHJhbmdlX29wZXJhdG9yX2Zsb2F0Ojpmb2xk X3JhbmdlOwpAQCAtMTcyLDYgKzIxNiw1MDkgQEAgY2xhc3MgZm9wZXJhdG9yX2lkZW50aXR5IDog cHVibGljIHJhbmdlX29wZXJhdG9yX2Zsb2F0CiBwdWJsaWM6CiB9IGZvcF9pZGVudGl0eTsKIAor Y2xhc3MgZm9wZXJhdG9yX2VxdWFsIDogcHVibGljIHJhbmdlX29wZXJhdG9yX2Zsb2F0Cit7Cisg IHVzaW5nIHJhbmdlX29wZXJhdG9yX2Zsb2F0Ojpmb2xkX3JhbmdlOworICB1c2luZyByYW5nZV9v cGVyYXRvcl9mbG9hdDo6b3AxX3JhbmdlOworICB1c2luZyByYW5nZV9vcGVyYXRvcl9mbG9hdDo6 b3AyX3JhbmdlOworCisgIGJvb2wgZm9sZF9yYW5nZSAoaXJhbmdlICZyLCB0cmVlIHR5cGUsCisJ CSAgIGNvbnN0IGZyYW5nZSAmb3AxLCBjb25zdCBmcmFuZ2UgJm9wMiwKKwkJICAgcmVsYXRpb25f a2luZCByZWwpIGNvbnN0IGZpbmFsIG92ZXJyaWRlCisgIHsKKyAgICByZXR1cm4gZGVmYXVsdF9m cmVsb3BfZm9sZF9yYW5nZSAociwgdHlwZSwgb3AxLCBvcDIsIHJlbCwgVlJFTF9FUSk7CisgIH0K KyAgcmVsYXRpb25fa2luZCBvcDFfb3AyX3JlbGF0aW9uIChjb25zdCBpcmFuZ2UgJmxocykgY29u c3QgZmluYWwgb3ZlcnJpZGUKKyAgeworICAgIHJldHVybiBlcXVhbF9vcDFfb3AyX3JlbGF0aW9u IChsaHMpOworICB9CisgIGJvb2wgb3AxX3JhbmdlIChmcmFuZ2UgJnIsIHRyZWUgdHlwZSwKKwkJ ICBjb25zdCBpcmFuZ2UgJmxocywgY29uc3QgZnJhbmdlICZvcDIsCisJCSAgcmVsYXRpb25fa2lu ZCByZWwpIGNvbnN0IGZpbmFsIG92ZXJyaWRlOworICBib29sIG9wMl9yYW5nZSAoZnJhbmdlICZy LCB0cmVlIHR5cGUsCisJCSAgY29uc3QgaXJhbmdlICZsaHMsIGNvbnN0IGZyYW5nZSAmb3AxLAor CQkgIHJlbGF0aW9uX2tpbmQgcmVsKSBjb25zdCBmaW5hbCBvdmVycmlkZQorICB7CisgICAgcmV0 dXJuIG9wMV9yYW5nZSAociwgdHlwZSwgbGhzLCBvcDEsIHJlbCk7CisgIH0KK30gZm9wX2VxdWFs OworCitib29sCitmb3BlcmF0b3JfZXF1YWw6Om9wMV9yYW5nZSAoZnJhbmdlICZyLCB0cmVlIHR5 cGUsCisJCQkgICAgY29uc3QgaXJhbmdlICZsaHMsCisJCQkgICAgY29uc3QgZnJhbmdlICZvcDIg QVRUUklCVVRFX1VOVVNFRCwKKwkJCSAgICByZWxhdGlvbl9raW5kIHJlbCkgY29uc3QKK3sKKyAg c3dpdGNoIChnZXRfYm9vbF9zdGF0ZSAociwgbGhzLCB0eXBlKSkKKyAgICB7CisgICAgY2FzZSBC UlNfVFJVRToKKyAgICAgIHIuc2V0X3ZhcnlpbmcgKHR5cGUpOworICAgICAgLy8gVGhlIFRSVUUg c2lkZSBvZiBvcDEgPT0gb3AyIGltcGxpZXMgb3AxIGlzICFOQU4uCisgICAgICByLnNldF9uYW4g KGZwX3Byb3A6Ok5PKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBCUlNfRkFMU0U6CisgICAg ICByLnNldF92YXJ5aW5nICh0eXBlKTsKKyAgICAgIC8vIFRoZSBGQUxTRSBzaWRlIG9mIG9wMSA9 PSBvcDEgaW1wbGllcyBvcDEgaXMgYSBOQU4uCisgICAgICBpZiAocmVsID09IFZSRUxfRVEpCisJ ci5zZXRfbmFuIChmcF9wcm9wOjpZRVMpOworICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0Ogor ICAgICAgYnJlYWs7CisgICAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworY2xhc3MgZm9wZXJhdG9y X25vdF9lcXVhbCA6IHB1YmxpYyByYW5nZV9vcGVyYXRvcl9mbG9hdAoreworICB1c2luZyByYW5n ZV9vcGVyYXRvcl9mbG9hdDo6Zm9sZF9yYW5nZTsKKyAgdXNpbmcgcmFuZ2Vfb3BlcmF0b3JfZmxv YXQ6Om9wMV9yYW5nZTsKKworICBib29sIGZvbGRfcmFuZ2UgKGlyYW5nZSAmciwgdHJlZSB0eXBl LAorCQkgICBjb25zdCBmcmFuZ2UgJm9wMSwgY29uc3QgZnJhbmdlICZvcDIsCisJCSAgIHJlbGF0 aW9uX2tpbmQgcmVsKSBjb25zdCBmaW5hbCBvdmVycmlkZQorICB7CisgICAgcmV0dXJuIGRlZmF1 bHRfZnJlbG9wX2ZvbGRfcmFuZ2UgKHIsIHR5cGUsIG9wMSwgb3AyLCByZWwsIFZSRUxfTkUpOwor ICB9CisgIHJlbGF0aW9uX2tpbmQgb3AxX29wMl9yZWxhdGlvbiAoY29uc3QgaXJhbmdlICZsaHMp IGNvbnN0IGZpbmFsIG92ZXJyaWRlCisgIHsKKyAgICByZXR1cm4gbm90X2VxdWFsX29wMV9vcDJf cmVsYXRpb24gKGxocyk7CisgIH0KKyAgYm9vbCBvcDFfcmFuZ2UgKGZyYW5nZSAmciwgdHJlZSB0 eXBlLAorCQkgIGNvbnN0IGlyYW5nZSAmbGhzLCBjb25zdCBmcmFuZ2UgJm9wMiwKKwkJICByZWxh dGlvbl9raW5kIHJlbCkgY29uc3QgZmluYWwgb3ZlcnJpZGU7Cit9IGZvcF9ub3RfZXF1YWw7CisK K2Jvb2wKK2ZvcGVyYXRvcl9ub3RfZXF1YWw6Om9wMV9yYW5nZSAoZnJhbmdlICZyLCB0cmVlIHR5 cGUsCisJCQkJY29uc3QgaXJhbmdlICZsaHMsCisJCQkJY29uc3QgZnJhbmdlICZvcDIgQVRUUklC VVRFX1VOVVNFRCwKKwkJCQlyZWxhdGlvbl9raW5kKSBjb25zdAoreworICBzd2l0Y2ggKGdldF9i b29sX3N0YXRlIChyLCBsaHMsIHR5cGUpKQorICAgIHsKKyAgICBjYXNlIEJSU19UUlVFOgorICAg ICAgci5zZXRfdmFyeWluZyAodHlwZSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgQlJTX0ZB TFNFOgorICAgICAgci5zZXRfdmFyeWluZyAodHlwZSk7CisgICAgICAvLyBUaGUgRkFMU0Ugc2lk ZSBvZiBvcDEgIT0gb3AyIGltcGxpZXMgb3AxIGlzICFOQU4uCisgICAgICByLnNldF9uYW4gKGZw X3Byb3A6Ok5PKTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOwor ICAgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2NsYXNzIGZvcGVyYXRvcl9sdCA6IHB1YmxpYyBy YW5nZV9vcGVyYXRvcl9mbG9hdAoreworICB1c2luZyByYW5nZV9vcGVyYXRvcl9mbG9hdDo6Zm9s ZF9yYW5nZTsKKyAgdXNpbmcgcmFuZ2Vfb3BlcmF0b3JfZmxvYXQ6Om9wMV9yYW5nZTsKKyAgdXNp bmcgcmFuZ2Vfb3BlcmF0b3JfZmxvYXQ6Om9wMl9yYW5nZTsKKworICBib29sIGZvbGRfcmFuZ2Ug KGlyYW5nZSAmciwgdHJlZSB0eXBlLAorCQkgICBjb25zdCBmcmFuZ2UgJm9wMSwgY29uc3QgZnJh bmdlICZvcDIsCisJCSAgIHJlbGF0aW9uX2tpbmQgcmVsKSBjb25zdCBmaW5hbCBvdmVycmlkZQor ICB7CisgICAgcmV0dXJuIGRlZmF1bHRfZnJlbG9wX2ZvbGRfcmFuZ2UgKHIsIHR5cGUsIG9wMSwg b3AyLCByZWwsIFZSRUxfTFQpOworICB9CisgIHJlbGF0aW9uX2tpbmQgb3AxX29wMl9yZWxhdGlv biAoY29uc3QgaXJhbmdlICZsaHMpIGNvbnN0IGZpbmFsIG92ZXJyaWRlCisgIHsKKyAgICByZXR1 cm4gbHRfb3AxX29wMl9yZWxhdGlvbiAobGhzKTsKKyAgfQorICBib29sIG9wMV9yYW5nZSAoZnJh bmdlICZyLCB0cmVlIHR5cGUsCisJCSAgY29uc3QgaXJhbmdlICZsaHMsIGNvbnN0IGZyYW5nZSAm b3AyLAorCQkgIHJlbGF0aW9uX2tpbmQgcmVsKSBjb25zdCBmaW5hbCBvdmVycmlkZTsKKyAgYm9v bCBvcDJfcmFuZ2UgKGZyYW5nZSAmciwgdHJlZSB0eXBlLAorCQkgIGNvbnN0IGlyYW5nZSAmbGhz LCBjb25zdCBmcmFuZ2UgJm9wMSwKKwkJICByZWxhdGlvbl9raW5kIHJlbCkgY29uc3QgZmluYWwg b3ZlcnJpZGU7Cit9IGZvcF9sdDsKKworYm9vbAorZm9wZXJhdG9yX2x0OjpvcDFfcmFuZ2UgKGZy YW5nZSAmciwKKwkJCSB0cmVlIHR5cGUsCisJCQkgY29uc3QgaXJhbmdlICZsaHMsCisJCQkgY29u c3QgZnJhbmdlICZvcDIgQVRUUklCVVRFX1VOVVNFRCwKKwkJCSByZWxhdGlvbl9raW5kKSBjb25z dAoreworICBzd2l0Y2ggKGdldF9ib29sX3N0YXRlIChyLCBsaHMsIHR5cGUpKQorICAgIHsKKyAg ICBjYXNlIEJSU19UUlVFOgorICAgICAgci5zZXRfdmFyeWluZyAodHlwZSk7CisgICAgICAvLyBU aGUgVFJVRSBzaWRlIG9mIG9wMSA8IG9wMiBpbXBsaWVzIG9wMSBpcyAhTkFOIGFuZCAhSU5GLgor ICAgICAgci5zZXRfbmFuIChmcF9wcm9wOjpOTyk7CisgICAgICByLnNldF9pbmYgKGZwX3Byb3A6 Ok5PKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBCUlNfRkFMU0U6CisgICAgICByLnNldF92 YXJ5aW5nICh0eXBlKTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFr OworICAgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wKK2ZvcGVyYXRvcl9sdDo6b3AyX3Jh bmdlIChmcmFuZ2UgJnIsCisJCQkgdHJlZSB0eXBlLAorCQkJIGNvbnN0IGlyYW5nZSAmbGhzLAor CQkJIGNvbnN0IGZyYW5nZSAmb3AxIEFUVFJJQlVURV9VTlVTRUQsCisJCQkgcmVsYXRpb25fa2lu ZCkgY29uc3QKK3sKKyAgc3dpdGNoIChnZXRfYm9vbF9zdGF0ZSAociwgbGhzLCB0eXBlKSkKKyAg ICB7CisgICAgY2FzZSBCUlNfVFJVRToKKyAgICAgIHIuc2V0X3ZhcnlpbmcgKHR5cGUpOworICAg ICAgLy8gVGhlIFRSVUUgc2lkZSBvZiBvcDEgPCBvcDIgaW1wbGllcyBvcDIgaXMgIU5BTiBhbmQg IU5JTkYuCisgICAgICByLnNldF9uYW4gKGZwX3Byb3A6Ok5PKTsKKyAgICAgIHIuc2V0X25pbmYg KGZwX3Byb3A6Ok5PKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBCUlNfRkFMU0U6CisgICAg ICByLnNldF92YXJ5aW5nICh0eXBlKTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAg ICAgIGJyZWFrOworICAgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2NsYXNzIGZvcGVyYXRvcl9s ZSA6IHB1YmxpYyByYW5nZV9vcGVyYXRvcl9mbG9hdAoreworICB1c2luZyByYW5nZV9vcGVyYXRv cl9mbG9hdDo6Zm9sZF9yYW5nZTsKKyAgdXNpbmcgcmFuZ2Vfb3BlcmF0b3JfZmxvYXQ6Om9wMV9y YW5nZTsKKyAgdXNpbmcgcmFuZ2Vfb3BlcmF0b3JfZmxvYXQ6Om9wMl9yYW5nZTsKKworICBib29s IGZvbGRfcmFuZ2UgKGlyYW5nZSAmciwgdHJlZSB0eXBlLAorCQkgICBjb25zdCBmcmFuZ2UgJm9w MSwgY29uc3QgZnJhbmdlICZvcDIsCisJCSAgIHJlbGF0aW9uX2tpbmQgcmVsKSBjb25zdCBmaW5h bCBvdmVycmlkZQorICB7CisgICAgcmV0dXJuIGRlZmF1bHRfZnJlbG9wX2ZvbGRfcmFuZ2UgKHIs IHR5cGUsIG9wMSwgb3AyLCByZWwsIFZSRUxfTEUpOworICB9CisgIHJlbGF0aW9uX2tpbmQgb3Ax X29wMl9yZWxhdGlvbiAoY29uc3QgaXJhbmdlICZsaHMpIGNvbnN0IGZpbmFsIG92ZXJyaWRlCisg IHsKKyAgICByZXR1cm4gbGVfb3AxX29wMl9yZWxhdGlvbiAobGhzKTsKKyAgfQorICBib29sIG9w MV9yYW5nZSAoZnJhbmdlICZyLCB0cmVlIHR5cGUsCisJCSAgY29uc3QgaXJhbmdlICZsaHMsIGNv bnN0IGZyYW5nZSAmb3AyLAorCQkgIHJlbGF0aW9uX2tpbmQgcmVsKSBjb25zdCBmaW5hbCBvdmVy cmlkZTsKKyAgYm9vbCBvcDJfcmFuZ2UgKGZyYW5nZSAmciwgdHJlZSB0eXBlLAorCQkgIGNvbnN0 IGlyYW5nZSAmbGhzLCBjb25zdCBmcmFuZ2UgJm9wMSwKKwkJICByZWxhdGlvbl9raW5kIHJlbCkg Y29uc3QgZmluYWwgb3ZlcnJpZGUKKyAgeworICAgIHJldHVybiBvcDFfcmFuZ2UgKHIsIHR5cGUs IGxocywgb3AxLCByZWwpOworICB9Cit9IGZvcF9sZTsKKworYm9vbAorZm9wZXJhdG9yX2xlOjpv cDFfcmFuZ2UgKGZyYW5nZSAmciwKKwkJCSB0cmVlIHR5cGUsCisJCQkgY29uc3QgaXJhbmdlICZs aHMsCisJCQkgY29uc3QgZnJhbmdlICZvcDIgQVRUUklCVVRFX1VOVVNFRCwKKwkJCSByZWxhdGlv bl9raW5kKSBjb25zdAoreworICBzd2l0Y2ggKGdldF9ib29sX3N0YXRlIChyLCBsaHMsIHR5cGUp KQorICAgIHsKKyAgICBjYXNlIEJSU19UUlVFOgorICAgICAgci5zZXRfdmFyeWluZyAodHlwZSk7 CisgICAgICAvLyBUaGUgVFJVRSBzaWRlIG9mIG9wMSA8PSBvcDIgaW1wbGllcyBvcDEgaXMgIU5B Ti4KKyAgICAgIHIuc2V0X25hbiAoZnBfcHJvcDo6Tk8pOworICAgICAgYnJlYWs7CisKKyAgICBj YXNlIEJSU19GQUxTRToKKyAgICAgIHIuc2V0X3ZhcnlpbmcgKHR5cGUpOworICAgICAgYnJlYWs7 CisKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgICAgfQorICByZXR1cm4gdHJ1ZTsKK30K KworY2xhc3MgZm9wZXJhdG9yX2d0IDogcHVibGljIHJhbmdlX29wZXJhdG9yX2Zsb2F0Cit7Cisg IHVzaW5nIHJhbmdlX29wZXJhdG9yX2Zsb2F0Ojpmb2xkX3JhbmdlOworICB1c2luZyByYW5nZV9v cGVyYXRvcl9mbG9hdDo6b3AxX3JhbmdlOworICB1c2luZyByYW5nZV9vcGVyYXRvcl9mbG9hdDo6 b3AyX3JhbmdlOworCisgIGJvb2wgZm9sZF9yYW5nZSAoaXJhbmdlICZyLCB0cmVlIHR5cGUsCisJ CSAgIGNvbnN0IGZyYW5nZSAmb3AxLCBjb25zdCBmcmFuZ2UgJm9wMiwKKwkJICAgcmVsYXRpb25f a2luZCByZWwpIGNvbnN0IGZpbmFsIG92ZXJyaWRlCisgIHsKKyAgICByZXR1cm4gZGVmYXVsdF9m cmVsb3BfZm9sZF9yYW5nZSAociwgdHlwZSwgb3AxLCBvcDIsIHJlbCwgVlJFTF9HVCk7CisgIH0K KyAgcmVsYXRpb25fa2luZCBvcDFfb3AyX3JlbGF0aW9uIChjb25zdCBpcmFuZ2UgJmxocykgY29u c3QgZmluYWwgb3ZlcnJpZGUKKyAgeworICAgIHJldHVybiBndF9vcDFfb3AyX3JlbGF0aW9uIChs aHMpOworICB9CisgIGJvb2wgb3AxX3JhbmdlIChmcmFuZ2UgJnIsIHRyZWUgdHlwZSwKKwkJICBj b25zdCBpcmFuZ2UgJmxocywgY29uc3QgZnJhbmdlICZvcDIsCisJCSAgcmVsYXRpb25fa2luZCBy ZWwpIGNvbnN0IGZpbmFsIG92ZXJyaWRlOworICBib29sIG9wMl9yYW5nZSAoZnJhbmdlICZyLCB0 cmVlIHR5cGUsCisJCSAgY29uc3QgaXJhbmdlICZsaHMsIGNvbnN0IGZyYW5nZSAmb3AxLAorCQkg IHJlbGF0aW9uX2tpbmQgcmVsKSBjb25zdCBmaW5hbCBvdmVycmlkZTsKK30gZm9wX2d0OworCiti b29sCitmb3BlcmF0b3JfZ3Q6Om9wMV9yYW5nZSAoZnJhbmdlICZyLAorCQkJIHRyZWUgdHlwZSwK KwkJCSBjb25zdCBpcmFuZ2UgJmxocywKKwkJCSBjb25zdCBmcmFuZ2UgJm9wMiBBVFRSSUJVVEVf VU5VU0VELAorCQkJIHJlbGF0aW9uX2tpbmQpIGNvbnN0Cit7CisgIHN3aXRjaCAoZ2V0X2Jvb2xf c3RhdGUgKHIsIGxocywgdHlwZSkpCisgICAgeworICAgIGNhc2UgQlJTX1RSVUU6CisgICAgICBy LnNldF92YXJ5aW5nICh0eXBlKTsKKyAgICAgIC8vIFRoZSBUUlVFIHNpZGUgb2Ygb3AxID4gb3Ay IGltcGxpZXMgb3AxIGlzICFOQU4gYW5kICFOSU5GLgorICAgICAgci5zZXRfbmFuIChmcF9wcm9w OjpOTyk7CisgICAgICByLnNldF9uaW5mIChmcF9wcm9wOjpOTyk7CisgICAgICBicmVhazsKKwor ICAgIGNhc2UgQlJTX0ZBTFNFOgorICAgICAgci5zZXRfdmFyeWluZyAodHlwZSk7CisgICAgICBi cmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICBicmVhazsKKyAgICB9CisgIHJldHVybiB0cnVl OworfQorCitib29sCitmb3BlcmF0b3JfZ3Q6Om9wMl9yYW5nZSAoZnJhbmdlICZyLAorCQkJIHRy ZWUgdHlwZSwKKwkJCSBjb25zdCBpcmFuZ2UgJmxocywKKwkJCSBjb25zdCBmcmFuZ2UgJm9wMSBB VFRSSUJVVEVfVU5VU0VELAorCQkJIHJlbGF0aW9uX2tpbmQpIGNvbnN0Cit7CisgIHN3aXRjaCAo Z2V0X2Jvb2xfc3RhdGUgKHIsIGxocywgdHlwZSkpCisgICAgeworICAgIGNhc2UgQlJTX1RSVUU6 CisgICAgICByLnNldF92YXJ5aW5nICh0eXBlKTsKKyAgICAgIC8vIFRoZSBUUlVFIHNpZGUgb2Yg b3AxID4gb3AyIGltcGxpZXMgb3AyIGlzICFOQU4gYW5kICFJTkYuCisgICAgICByLnNldF9uYW4g KGZwX3Byb3A6Ok5PKTsKKyAgICAgIHIuc2V0X2luZiAoZnBfcHJvcDo6Tk8pOworICAgICAgYnJl YWs7CisKKyAgICBjYXNlIEJSU19GQUxTRToKKyAgICAgIHIuc2V0X3ZhcnlpbmcgKHR5cGUpOwor ICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgICAgfQorICByZXR1 cm4gdHJ1ZTsKK30KKworY2xhc3MgZm9wZXJhdG9yX2dlIDogcHVibGljIHJhbmdlX29wZXJhdG9y X2Zsb2F0Cit7CisgIHVzaW5nIHJhbmdlX29wZXJhdG9yX2Zsb2F0Ojpmb2xkX3JhbmdlOworICB1 c2luZyByYW5nZV9vcGVyYXRvcl9mbG9hdDo6b3AxX3JhbmdlOworICB1c2luZyByYW5nZV9vcGVy YXRvcl9mbG9hdDo6b3AyX3JhbmdlOworCisgIGJvb2wgZm9sZF9yYW5nZSAoaXJhbmdlICZyLCB0 cmVlIHR5cGUsCisJCSAgIGNvbnN0IGZyYW5nZSAmb3AxLCBjb25zdCBmcmFuZ2UgJm9wMiwKKwkJ ICAgcmVsYXRpb25fa2luZCByZWwpIGNvbnN0IGZpbmFsIG92ZXJyaWRlCisgIHsKKyAgICByZXR1 cm4gZGVmYXVsdF9mcmVsb3BfZm9sZF9yYW5nZSAociwgdHlwZSwgb3AxLCBvcDIsIHJlbCwgVlJF TF9HRSk7CisgIH0KKyAgcmVsYXRpb25fa2luZCBvcDFfb3AyX3JlbGF0aW9uIChjb25zdCBpcmFu Z2UgJmxocykgY29uc3QgZmluYWwgb3ZlcnJpZGUKKyAgeworICAgIHJldHVybiBnZV9vcDFfb3Ay X3JlbGF0aW9uIChsaHMpOworICB9CisgIGJvb2wgb3AxX3JhbmdlIChmcmFuZ2UgJnIsIHRyZWUg dHlwZSwKKwkJICBjb25zdCBpcmFuZ2UgJmxocywgY29uc3QgZnJhbmdlICZvcDIsCisJCSAgcmVs YXRpb25fa2luZCByZWwpIGNvbnN0IGZpbmFsIG92ZXJyaWRlOworICBib29sIG9wMl9yYW5nZSAo ZnJhbmdlICZyLCB0cmVlIHR5cGUsCisJCSAgY29uc3QgaXJhbmdlICZsaHMsIGNvbnN0IGZyYW5n ZSAmb3AxLAorCQkgIHJlbGF0aW9uX2tpbmQgcmVsKSBjb25zdCBmaW5hbCBvdmVycmlkZQorICB7 CisgICAgcmV0dXJuIG9wMV9yYW5nZSAociwgdHlwZSwgbGhzLCBvcDEsIHJlbCk7CisgIH0KK30g Zm9wX2dlOworCitib29sCitmb3BlcmF0b3JfZ2U6Om9wMV9yYW5nZSAoZnJhbmdlICZyLAorCQkJ IHRyZWUgdHlwZSwKKwkJCSBjb25zdCBpcmFuZ2UgJmxocywKKwkJCSBjb25zdCBmcmFuZ2UgJm9w MiBBVFRSSUJVVEVfVU5VU0VELAorCQkJIHJlbGF0aW9uX2tpbmQpIGNvbnN0Cit7CisgIHN3aXRj aCAoZ2V0X2Jvb2xfc3RhdGUgKHIsIGxocywgdHlwZSkpCisgICAgeworICAgIGNhc2UgQlJTX1RS VUU6CisgICAgICByLnNldF92YXJ5aW5nICh0eXBlKTsKKyAgICAgIC8vIFRoZSBUUlVFIHNpZGUg b2Ygb3AxID49IG9wMiBpbXBsaWVzIG9wMSBpcyAhTkFOLgorICAgICAgci5zZXRfbmFuIChmcF9w cm9wOjpOTyk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgQlJTX0ZBTFNFOgorICAgICAgci5z ZXRfdmFyeWluZyAodHlwZSk7CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICBi cmVhazsKKyAgICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBVTk9SREVSRURfRVhQUiBjb21w YXJpc29uLgorCitjbGFzcyBmb3BlcmF0b3JfdW5vcmRlcmVkIDogcHVibGljIHJhbmdlX29wZXJh dG9yX2Zsb2F0Cit7CisgIHVzaW5nIHJhbmdlX29wZXJhdG9yX2Zsb2F0Ojpmb2xkX3JhbmdlOwor ICB1c2luZyByYW5nZV9vcGVyYXRvcl9mbG9hdDo6b3AxX3JhbmdlOworICB1c2luZyByYW5nZV9v cGVyYXRvcl9mbG9hdDo6b3AyX3JhbmdlOworCitwdWJsaWM6CisgIGJvb2wgZm9sZF9yYW5nZSAo aXJhbmdlICZyLCB0cmVlIHR5cGUsCisJCSAgIGNvbnN0IGZyYW5nZSAmb3AxLCBjb25zdCBmcmFu Z2UgJm9wMiwKKwkJICAgcmVsYXRpb25fa2luZCByZWwpIGNvbnN0IGZpbmFsIG92ZXJyaWRlOwor ICBib29sIG9wMV9yYW5nZSAoZnJhbmdlICZyLCB0cmVlIHR5cGUsCisJCSAgY29uc3QgaXJhbmdl ICZsaHMsIGNvbnN0IGZyYW5nZSAmb3AyLAorCQkgIHJlbGF0aW9uX2tpbmQgcmVsKSBjb25zdCBm aW5hbCBvdmVycmlkZTsKKyAgYm9vbCBvcDJfcmFuZ2UgKGZyYW5nZSAmciwgdHJlZSB0eXBlLAor CQkgIGNvbnN0IGlyYW5nZSAmbGhzLCBjb25zdCBmcmFuZ2UgJm9wMSwKKwkJICByZWxhdGlvbl9r aW5kIHJlbCkgY29uc3QgZmluYWwgb3ZlcnJpZGUKKyAgeworICAgIHJldHVybiBvcDFfcmFuZ2Ug KHIsIHR5cGUsIGxocywgb3AxLCByZWwpOworICB9Cit9IGZvcF91bm9yZGVyZWQ7CisKK2Jvb2wK K2ZvcGVyYXRvcl91bm9yZGVyZWQ6OmZvbGRfcmFuZ2UgKGlyYW5nZSAmciwgdHJlZSB0eXBlLAor CQkJCSBjb25zdCBmcmFuZ2UgJm9wMSwgY29uc3QgZnJhbmdlICZvcDIsCisJCQkJIHJlbGF0aW9u X2tpbmQpIGNvbnN0Cit7CisgIC8vIFVOT1JERVJFRCBpcyBUUlVFIGlmIGVpdGhlciBvcGVyYW5k IGlzIGEgTkFOLgorICBpZiAob3AxLmdldF9uYW4gKCkueWVzX3AgKCkgfHwgb3AyLmdldF9uYW4g KCkueWVzX3AgKCkpCisgICAgciA9IHJhbmdlX3RydWUgKHR5cGUpOworICAvLyBVTk9SREVSRUQg aXMgRkFMU0UgaWYgbmVpdGhlciBvcGVyYW5kIGlzIGEgTkFOLgorICBlbHNlIGlmIChvcDEuZ2V0 X25hbiAoKS5ub19wICgpICYmIG9wMi5nZXRfbmFuICgpLm5vX3AgKCkpCisgICAgciA9IHJhbmdl X2ZhbHNlICh0eXBlKTsKKyAgZWxzZQorICAgIHIgPSByYW5nZV90cnVlX2FuZF9mYWxzZSAodHlw ZSk7CisgIHJldHVybiB0cnVlOworfQorCitib29sCitmb3BlcmF0b3JfdW5vcmRlcmVkOjpvcDFf cmFuZ2UgKGZyYW5nZSAmciwgdHJlZSB0eXBlLAorCQkJCWNvbnN0IGlyYW5nZSAmbGhzLAorCQkJ CWNvbnN0IGZyYW5nZSAmb3AyIEFUVFJJQlVURV9VTlVTRUQsCisJCQkJcmVsYXRpb25fa2luZCkg Y29uc3QKK3sKKyAgc3dpdGNoIChnZXRfYm9vbF9zdGF0ZSAociwgbGhzLCB0eXBlKSkKKyAgICB7 CisgICAgY2FzZSBCUlNfVFJVRToKKyAgICAgIHIuc2V0X3ZhcnlpbmcgKHR5cGUpOworICAgICAg Ly8gU2luY2UgYXQgbGVhc3Qgb25lIG9wZXJhbmQgbXVzdCBiZSBOQU4sIGlmIG9uZSBvZiB0aGVt IGlzCisgICAgICAvLyBub3QsIHRoZSBvdGhlciBtdXN0IGJlLgorICAgICAgaWYgKG9wMi5nZXRf bmFuICgpLm5vX3AgKCkpCisJci5zZXRfbmFuIChmcF9wcm9wOjpZRVMpOworICAgICAgYnJlYWs7 CisKKyAgICBjYXNlIEJSU19GQUxTRToKKyAgICAgIHIuc2V0X3ZhcnlpbmcgKHR5cGUpOworICAg ICAgLy8gQSBmYWxzZSBVTk9SREVSRUQgbWVhbnMgYm90aCBvcGVyYW5kcyBhcmUgIU5BTi4KKyAg ICAgIHIuc2V0X25hbiAoZnBfcHJvcDo6Tk8pOworICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0 OgorICAgICAgYnJlYWs7CisgICAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworLy8gT1JERVJFRF9F WFBSIGNvbXBhcmlzb24uCisKK2NsYXNzIGZvcGVyYXRvcl9vcmRlcmVkIDogcHVibGljIHJhbmdl X29wZXJhdG9yX2Zsb2F0Cit7CisgIHVzaW5nIHJhbmdlX29wZXJhdG9yX2Zsb2F0Ojpmb2xkX3Jh bmdlOworICB1c2luZyByYW5nZV9vcGVyYXRvcl9mbG9hdDo6b3AxX3JhbmdlOworICB1c2luZyBy YW5nZV9vcGVyYXRvcl9mbG9hdDo6b3AyX3JhbmdlOworCitwdWJsaWM6CisgIGJvb2wgZm9sZF9y YW5nZSAoaXJhbmdlICZyLCB0cmVlIHR5cGUsCisJCSAgIGNvbnN0IGZyYW5nZSAmb3AxLCBjb25z dCBmcmFuZ2UgJm9wMiwKKwkJICAgcmVsYXRpb25fa2luZCByZWwpIGNvbnN0IGZpbmFsIG92ZXJy aWRlOworICBib29sIG9wMV9yYW5nZSAoZnJhbmdlICZyLCB0cmVlIHR5cGUsCisJCSAgY29uc3Qg aXJhbmdlICZsaHMsIGNvbnN0IGZyYW5nZSAmb3AyLAorCQkgIHJlbGF0aW9uX2tpbmQgcmVsKSBj b25zdCBmaW5hbCBvdmVycmlkZTsKKyAgYm9vbCBvcDJfcmFuZ2UgKGZyYW5nZSAmciwgdHJlZSB0 eXBlLAorCQkgIGNvbnN0IGlyYW5nZSAmbGhzLCBjb25zdCBmcmFuZ2UgJm9wMSwKKwkJICByZWxh dGlvbl9raW5kIHJlbCkgY29uc3QgZmluYWwgb3ZlcnJpZGUKKyAgeworICAgIHJldHVybiBvcDFf cmFuZ2UgKHIsIHR5cGUsIGxocywgb3AxLCByZWwpOworICB9Cit9IGZvcF9vcmRlcmVkOworCiti b29sCitmb3BlcmF0b3Jfb3JkZXJlZDo6Zm9sZF9yYW5nZSAoaXJhbmdlICZyLCB0cmVlIHR5cGUs CisJCQkgICAgICAgY29uc3QgZnJhbmdlICZvcDEsIGNvbnN0IGZyYW5nZSAmb3AyLAorCQkJICAg ICAgIHJlbGF0aW9uX2tpbmQpIGNvbnN0Cit7CisgIC8vIE9SREVSRUQgaXMgVFJVRSBpZiBuZWl0 aGVyIG9wZXJhbmQgaXMgYSBOQU4uCisgIGlmIChvcDEuZ2V0X25hbiAoKS5ub19wICgpICYmIG9w Mi5nZXRfbmFuICgpLm5vX3AgKCkpCisgICAgciA9IHJhbmdlX3RydWUgKHR5cGUpOworICAvLyBP UkRFUkVEIGlzIEZBTFNFIGlmIGVpdGhlciBvcGVyYW5kIGlzIGEgTkFOLgorICBlbHNlIGlmIChv cDEuZ2V0X25hbiAoKS55ZXNfcCAoKSB8fCBvcDIuZ2V0X25hbiAoKS55ZXNfcCAoKSkKKyAgICBy ID0gcmFuZ2VfZmFsc2UgKHR5cGUpOworICBlbHNlCisgICAgciA9IHJhbmdlX3RydWVfYW5kX2Zh bHNlICh0eXBlKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wKK2ZvcGVyYXRvcl9vcmRlcmVk OjpvcDFfcmFuZ2UgKGZyYW5nZSAmciwgdHJlZSB0eXBlLAorCQkJICAgICAgY29uc3QgaXJhbmdl ICZsaHMsCisJCQkgICAgICBjb25zdCBmcmFuZ2UgJm9wMiBBVFRSSUJVVEVfVU5VU0VELAorCQkJ ICAgICAgcmVsYXRpb25fa2luZCByZWwpIGNvbnN0Cit7CisgIHN3aXRjaCAoZ2V0X2Jvb2xfc3Rh dGUgKHIsIGxocywgdHlwZSkpCisgICAgeworICAgIGNhc2UgQlJTX1RSVUU6CisgICAgICByLnNl dF92YXJ5aW5nICh0eXBlKTsKKyAgICAgIC8vIFRoZSBUUlVFIHNpZGUgb2Ygb3AxIE9SREVSRUQg b3AyIGltcGxpZXMgb3AxIGlzICFOQU4uCisgICAgICByLnNldF9uYW4gKGZwX3Byb3A6Ok5PKTsK KyAgICAgIGJyZWFrOworCisgICAgY2FzZSBCUlNfRkFMU0U6CisgICAgICByLnNldF92YXJ5aW5n ICh0eXBlKTsKKyAgICAgIC8vIFRoZSBGQUxTRSBzaWRlIG9mIG9wMSBPUkRFUkVEIG9wMSBpbXBs aWVzIG9wMSBpcyAhTkFOLgorICAgICAgaWYgKHJlbCA9PSBWUkVMX0VRKQorCXIuc2V0X25hbiAo ZnBfcHJvcDo6Tk8pOworICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7 CisgICAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworLy8gUGxhY2Vob2xkZXIgZm9yIHVuaW1wbGVt ZW50ZWQgcmVsYXRpb25hbCBvcGVyYXRvcnMuCisKK2NsYXNzIGZvcGVyYXRvcl9yZWxvcF91bmtu b3duIDogcHVibGljIHJhbmdlX29wZXJhdG9yX2Zsb2F0Cit7CisgIHVzaW5nIHJhbmdlX29wZXJh dG9yX2Zsb2F0Ojpmb2xkX3JhbmdlOworCitwdWJsaWM6CisgIGJvb2wgZm9sZF9yYW5nZSAoaXJh bmdlICZyLCB0cmVlIHR5cGUsCisJCSAgIGNvbnN0IGZyYW5nZSAmLCBjb25zdCBmcmFuZ2UgJiwK KwkJICAgcmVsYXRpb25fa2luZCkgY29uc3QgZmluYWwgb3ZlcnJpZGUKKyAgeworICAgIHIuc2V0 X3ZhcnlpbmcgKHR5cGUpOworICAgIHJldHVybiB0cnVlOworICB9Cit9IGZvcF9yZWxvcF91bmtu b3duOworCiAKIC8vIEluc3RhbnRpYXRlIGEgcmFuZ2Vfb3BfdGFibGUgZm9yIGZsb2F0aW5nIHBv aW50IG9wZXJhdGlvbnMuCiBzdGF0aWMgZmxvYXRpbmdfb3BfdGFibGUgZ2xvYmFsX2Zsb2F0aW5n X3RhYmxlOwpAQCAtMTg1LDYgKzczMiwyMyBAQCBmbG9hdGluZ19vcF90YWJsZTo6ZmxvYXRpbmdf b3BfdGFibGUgKCkKICAgc2V0IChQQVJFTl9FWFBSLCBmb3BfaWRlbnRpdHkpOwogICBzZXQgKE9C Sl9UWVBFX1JFRiwgZm9wX2lkZW50aXR5KTsKICAgc2V0IChSRUFMX0NTVCwgZm9wX2lkZW50aXR5 KTsKKworICAvLyBBbGwgdGhlIHJlbGF0aW9uYWwgb3BlcmF0b3JzIGFyZSBleHBlY3RlZCB0byB3 b3JrLCBiZWNhdXNlIHRoZQorICAvLyBjYWxjdWxhdGlvbiBvZiByYW5nZXMgb24gb3V0Z29pbmcg ZWRnZXMgZXhwZWN0IHRoZSBoYW5kbGVycyB0byBiZQorICAvLyBwcmVzZW50LgorICBzZXQgKEVR X0VYUFIsIGZvcF9lcXVhbCk7CisgIHNldCAoTkVfRVhQUiwgZm9wX25vdF9lcXVhbCk7CisgIHNl dCAoTFRfRVhQUiwgZm9wX2x0KTsKKyAgc2V0IChMRV9FWFBSLCBmb3BfbGUpOworICBzZXQgKEdU X0VYUFIsIGZvcF9ndCk7CisgIHNldCAoR0VfRVhQUiwgZm9wX2dlKTsKKyAgc2V0IChVTkxFX0VY UFIsIGZvcF9yZWxvcF91bmtub3duKTsKKyAgc2V0IChVTkxUX0VYUFIsIGZvcF9yZWxvcF91bmtu b3duKTsKKyAgc2V0IChVTkdFX0VYUFIsIGZvcF9yZWxvcF91bmtub3duKTsKKyAgc2V0IChVTkdU X0VYUFIsIGZvcF9yZWxvcF91bmtub3duKTsKKyAgc2V0IChVTkVRX0VYUFIsIGZvcF9yZWxvcF91 bmtub3duKTsKKyAgc2V0IChPUkRFUkVEX0VYUFIsIGZvcF9vcmRlcmVkKTsKKyAgc2V0IChVTk9S REVSRURfRVhQUiwgZm9wX3Vub3JkZXJlZCk7CiB9CiAKIC8vIFJldHVybiBhIHBvaW50ZXIgdG8g dGhlIHJhbmdlX29wZXJhdG9yX2Zsb2F0IGluc3RhbmNlLCBpZiB0aGVyZSBpcwpkaWZmIC0tZ2l0 IGEvZ2NjL3Rlc3RzdWl0ZS9nKysuZGcvb3B0L3ByOTQ1ODktMi5DIGIvZ2NjL3Rlc3RzdWl0ZS9n KysuZGcvb3B0L3ByOTQ1ODktMi5DCmluZGV4IGU5ZWY4NGIxOTEyLi4zNzBkZWVhOTIxOCAxMDA2 NDQKLS0tIGEvZ2NjL3Rlc3RzdWl0ZS9nKysuZGcvb3B0L3ByOTQ1ODktMi5DCisrKyBiL2djYy90 ZXN0c3VpdGUvZysrLmRnL29wdC9wcjk0NTg5LTIuQwpAQCAtMSw3ICsxLDcgQEAKIC8vIFBSIHRy ZWUtb3B0aW1pemF0aW9uLzk0NTg5CiAvLyB7IGRnLWRvIGNvbXBpbGUgeyB0YXJnZXQgYysrMjAg fSB9CiAvLyB7IGRnLW9wdGlvbnMgIi1PMiAtZzAgLWZmYXN0LW1hdGggLWZkdW1wLXRyZWUtb3B0 aW1pemVkIiB9Ci0vLyB7IGRnLWZpbmFsIHsgc2Nhbi10cmVlLWR1bXAtdGltZXMgIlxbaWpdX1xb MC05XStcXChEXFwpICg/Ojx8PD18PT18IT18Pnw+PSkgXFtpal1fXFswLTldK1xcKERcXCkiIDEy ICJvcHRpbWl6ZWQiIH0gfQorLy8geyBkZy1maW5hbCB7IHNjYW4tdHJlZS1kdW1wLXRpbWVzICJc W2lqXV9cWzAtOV0rXFwoRFxcKSAoPzo8fDw9fD09fCE9fD58Pj0pIFxbaWpdX1xbMC05XStcXChE XFwpIiAxMiAib3B0aW1pemVkIiB7IHhmYWlsICotKi0qIH0gfSB9CiAvLyB7IGRnLWZpbmFsIHsg c2Nhbi10cmVlLWR1bXAtdGltZXMgImlfXFswLTldK1xcKERcXCkgKD86PHw8PXw9PXwhPXw+fD49 KSA1XFwuMCIgMTIgIm9wdGltaXplZCIgfSB9CiAKICNpbmNsdWRlIDxjb21wYXJlPgpkaWZmIC0t Z2l0IGEvZ2NjL3Rlc3RzdWl0ZS9nY2MuZGcvdHJlZS1zc2EvdnJwLWZsb2F0LTEuYyBiL2djYy90 ZXN0c3VpdGUvZ2NjLmRnL3RyZWUtc3NhL3ZycC1mbG9hdC0xLmMKbmV3IGZpbGUgbW9kZSAxMDA2 NDQKaW5kZXggMDAwMDAwMDAwMDAuLjg4ZmFmNzJhYzQyCi0tLSAvZGV2L251bGwKKysrIGIvZ2Nj L3Rlc3RzdWl0ZS9nY2MuZGcvdHJlZS1zc2EvdnJwLWZsb2F0LTEuYwpAQCAtMCwwICsxLDE5IEBA CisvLyB7IGRnLWRvIGNvbXBpbGUgfQorLy8geyBkZy1vcHRpb25zICItTzIgLWZkaXNhYmxlLXRy ZWUtZXRocmVhZCAtZmRpc2FibGUtdHJlZS1mcmUxIC1mZHVtcC10cmVlLWV2cnAiIH0KKwordm9p ZCBiYXIgKCk7Cit2b2lkIGdlb3JnZSAoKTsKKworZmxvYXQKK2ZvbyAoZmxvYXQgeCwgZmxvYXQg eSkKK3sKKyAgaWYgKHggPT0geCkKKyAgICB7CisgICAgICBpZiAoeCA+IHkpCisgICAgICAgIGJh cigpOworICAgICAgaWYgKHggPT0geCkKKyAgICAgICAgZ2VvcmdlKCk7CisgICAgfQorfQorCisv LyB7IGRnLWZpbmFsIHsgc2Nhbi10cmVlLWR1bXAtdGltZXMgIkZvbGRpbmcgcHJlZGljYXRlIHhf KnRvIDEiICJldnJwIiAxIH0gfQpkaWZmIC0tZ2l0IGEvZ2NjL3Rlc3RzdWl0ZS9nY2MuZGcvdHJl ZS1zc2EvdnJwLWZsb2F0LTExLmMgYi9nY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAt ZmxvYXQtMTEuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMC4uMmY0ZGM4 NzU3YTMKLS0tIC9kZXYvbnVsbAorKysgYi9nY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92 cnAtZmxvYXQtMTEuYwpAQCAtMCwwICsxLDI2IEBACisvLyB7IGRnLWRvIGNvbXBpbGUgfQorLy8g eyBkZy1vcHRpb25zICItTzIgLWZuby10aHJlYWQtanVtcHMgLWZkdW1wLXRyZWUtZXZycCIgfQor CitleHRlcm4gdm9pZCBsaW5rX2Vycm9yICgpOworCit2b2lkIGZhc3Rfc3FydCAoZmxvYXQpOwor CitmbG9hdCB0ZXN0IChmbG9hdCB4KQoreworICBmbG9hdCB5ID0geCp4OworICBpZiAoeSA+PSAw LmYpCisgICAgeyAKKyAgICAgIGlmIChfX2J1aWx0aW5faXNuYW4gKHkpKQorCWxpbmtfZXJyb3Ig KCk7CisgICAgICBlbHNlCisJZmFzdF9zcXJ0ICh5KTsKKworICAgICAgaWYgKCFfX2J1aWx0aW5f aXNuYW4gKHkpKQorCWZhc3Rfc3FydCAoeSk7CisgICAgICBlbHNlCisJbGlua19lcnJvciAoKTsK KyAgICB9Cit9CisKKy8vIHsgZGctZmluYWwgeyBzY2FuLXRyZWUtZHVtcC10aW1lcyAiZmFzdF9z cXJ0IiAyICJldnJwIiB9IH0KKy8vIHsgZGctZmluYWwgeyBzY2FuLXRyZWUtZHVtcC1ub3QgImxp bmtfZXJyb3IiICJldnJwIiB9IH0KZGlmZiAtLWdpdCBhL2djYy90ZXN0c3VpdGUvZ2NjLmRnL3Ry ZWUtc3NhL3ZycC1mbG9hdC0zLmMgYi9nY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAt ZmxvYXQtMy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwLi5jNjU5YWJi NmNjMAotLS0gL2Rldi9udWxsCisrKyBiL2djYy90ZXN0c3VpdGUvZ2NjLmRnL3RyZWUtc3NhL3Zy cC1mbG9hdC0zLmMKQEAgLTAsMCArMSwxOCBAQAorLy8geyBkZy1kbyBjb21waWxlIH0KKy8vIHsg ZGctb3B0aW9ucyAiLU8yIC1mZGlzYWJsZS10cmVlLWV0aHJlYWQgLWZkdW1wLXRyZWUtZXZycCIg fQorCit2b2lkIGxpbmtfZXJyb3IgKCk7CisKK3ZvaWQKK2ZvbyAoZG91YmxlIHgsIGRvdWJsZSB5 KQoreworICBpZiAoeCA9PSB5KQorICAgIHsKKyAgICAgIGlmIChfX2J1aWx0aW5faXNuYW4gKHgp KQorICAgICAgICBsaW5rX2Vycm9yICgpOworICAgICAgaWYgKF9fYnVpbHRpbl9pc25hbiAoeSkp CisgICAgICAgIGxpbmtfZXJyb3IgKCk7CisgICAgfQorfQorCisvLyB7IGRnLWZpbmFsIHsgc2Nh bi10cmVlLWR1bXAtbm90ICJsaW5rX2Vycm9yIiAiZXZycCIgfSB9CmRpZmYgLS1naXQgYS9nY2Mv dGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtNC5jIGIvZ2NjL3Rlc3RzdWl0ZS9n Y2MuZGcvdHJlZS1zc2EvdnJwLWZsb2F0LTQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAw MDAwMDAwMDAwMC4uODY0MzY3NDJlMGEKLS0tIC9kZXYvbnVsbAorKysgYi9nY2MvdGVzdHN1aXRl L2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtNC5jCkBAIC0wLDAgKzEsMTYgQEAKKy8vIHsgZGct ZG8gY29tcGlsZSB9CisvLyB7IGRnLW9wdGlvbnMgIi1PMiAtZmRpc2FibGUtdHJlZS1ldGhyZWFk IC1mZHVtcC10cmVlLWV2cnAiIH0KKwordm9pZCBsaW5rX2Vycm9yICgpOworCit2b2lkCitmb28g KGRvdWJsZSB4LCBkb3VibGUgeSkKK3sKKyAgaWYgKHggPiB5KQorICAgIHsKKyAgICAgIGlmIChf X2J1aWx0aW5faXNuYW4gKHgpIHx8IF9fYnVpbHRpbl9pc25hbiAoeSkpCisgICAgICAgIGxpbmtf ZXJyb3IgKCk7CisgICAgfQorfQorCisvLyB7IGRnLWZpbmFsIHsgc2Nhbi10cmVlLWR1bXAtbm90 ICJsaW5rX2Vycm9yIiAiZXZycCIgfSB9CmRpZmYgLS1naXQgYS9nY2MvdGVzdHN1aXRlL2djYy5k Zy90cmVlLXNzYS92cnAtZmxvYXQtNi5jIGIvZ2NjL3Rlc3RzdWl0ZS9nY2MuZGcvdHJlZS1zc2Ev dnJwLWZsb2F0LTYuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMC4uMTQ1 ZDE4NjE4MDQKLS0tIC9kZXYvbnVsbAorKysgYi9nY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNz YS92cnAtZmxvYXQtNi5jCkBAIC0wLDAgKzEsMjAgQEAKKy8vIHsgZGctZG8gY29tcGlsZSB9Cisv LyB7IGRnLW9wdGlvbnMgIi1PMiAtZmRpc2FibGUtdHJlZS1ldGhyZWFkIC1mZHVtcC10cmVlLWV2 cnAiIH0KKwordm9pZCBiYXIgKCk7CisKK3ZvaWQKK2ZvbyAoZG91YmxlIHgsIGRvdWJsZSB5KQor eworICAgICAgaWYgKHggPiB5KQorCTsKKyAgICAgIGVsc2UgaWYgKCFfX2J1aWx0aW5faXNuYW4g KHgpICYmICFfX2J1aWx0aW5faXNuYW4gKHkpKQorCXsKKwkgIC8vIElmIHggYW5kIHkgYXJlIG5v dCBOQU4sIHRoZSB4IDw9IHkgcmVsYXRpb25zaGlwIGhvbGRzLCBhbmQgdGhlCisJICAvLyBmb2xs b3dpbmcgY29uZGl0aW9uYWwgY2FuIGJlIGZvbGRlZCBhd2F5LgorCSAgaWYgKHggPD0geSkKKwkg ICAgYmFyICgpOworCX0KK30KKworLy8geyBkZy1maW5hbCB7IHNjYW4tdHJlZS1kdW1wLXRpbWVz ICJGb2xkaW5nIHByZWRpY2F0ZSB4Xy4qIDw9IHlfLiogdG8gMSIgMSAiZXZycCIgfSB9CmRpZmYg LS1naXQgYS9nY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtNy5jIGIvZ2Nj L3Rlc3RzdWl0ZS9nY2MuZGcvdHJlZS1zc2EvdnJwLWZsb2F0LTcuYwpuZXcgZmlsZSBtb2RlIDEw MDY0NAppbmRleCAwMDAwMDAwMDAwMC4uOTJhZjg3MDkxYTgKLS0tIC9kZXYvbnVsbAorKysgYi9n Y2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtNy5jCkBAIC0wLDAgKzEsMTQg QEAKKy8vIHsgZGctZG8gY29tcGlsZSB9CisvLyB7IGRnLW9wdGlvbnMgIi1PMiAtZm5vLXRyZWUt Zm9yd3Byb3AgLWZuby10cmVlLWNjcCAtZm5vLXRyZWUtZnJlIC1mZHVtcC10cmVlLWV2cnAiIH0K KworZXh0ZXJuIHZvaWQgbGlua19lcnJvciAoKTsKKwordm9pZAorZm9vICgpCit7CisgIGZsb2F0 IHogPSAwLjA7CisgIGlmIChfX2J1aWx0aW5faXNuYW4gKHopKQorICAgIGxpbmtfZXJyb3IgKCk7 Cit9CisKKy8vIHsgZGctZmluYWwgeyBzY2FuLXRyZWUtZHVtcC1ub3QgImxpbmtfZXJyb3IiICJl dnJwIiB9IH0KZGlmZiAtLWdpdCBhL2djYy90ZXN0c3VpdGUvZ2NjLmRnL3RyZWUtc3NhL3ZycC1m bG9hdC04LmMgYi9nY2MvdGVzdHN1aXRlL2djYy5kZy90cmVlLXNzYS92cnAtZmxvYXQtOC5jCm5l dyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwLi45MTcwMTUwZDQ1MwotLS0gL2Rl di9udWxsCisrKyBiL2djYy90ZXN0c3VpdGUvZ2NjLmRnL3RyZWUtc3NhL3ZycC1mbG9hdC04LmMK QEAgLTAsMCArMSwyNiBAQAorLy8geyBkZy1kbyBjb21waWxlIH0KKy8vIHsgZGctb3B0aW9ucyAi LU8yIC1mbm8tdGhyZWFkLWp1bXBzIC1mZHVtcC10cmVlLWV2cnAiIH0KKworZXh0ZXJuIHZvaWQg bGlua19lcnJvciAoKTsKKwordm9pZCBmYXN0X3NxcnQgKGZsb2F0KTsKKworZmxvYXQgdGVzdCAo ZmxvYXQgeCkKK3sKKyAgICBmbG9hdCB5ID0geCp4OworICAgIGlmICh5ID49IDAuZikKKyAgICAg IHsgCisgICAgICAgIGlmIChfX2J1aWx0aW5faXNuYW4gKHkpKQorICAgICAgICAgbGlua19lcnJv ciAoKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgIGZhc3Rfc3FydCAoeSk7CisKKyAgICAgICBp ZiAoIV9fYnVpbHRpbl9pc25hbiAoeSkpCisgICAgICAgICBmYXN0X3NxcnQgKHkpOworICAgICAg IGVsc2UKKyAgICAgICAgIGxpbmtfZXJyb3IgKCk7CisgICAgICB9Cit9CisKKy8vIHsgZGctZmlu YWwgeyBzY2FuLXRyZWUtZHVtcC10aW1lcyAiZmFzdF9zcXJ0IiAyICJldnJwIiB9IH0KKy8vIHsg ZGctZmluYWwgeyBzY2FuLXRyZWUtZHVtcC1ub3QgImxpbmtfZXJyb3IiICJldnJwIiB9IH0KZGlm ZiAtLWdpdCBhL2djYy92YWx1ZS1yYW5nZS5oIGIvZ2NjL3ZhbHVlLXJhbmdlLmgKaW5kZXggMzkw ZmNiOGZkOTkuLjMwNWUyY2FlN2U2IDEwMDY0NAotLS0gYS9nY2MvdmFsdWUtcmFuZ2UuaAorKysg Yi9nY2MvdmFsdWUtcmFuZ2UuaApAQCAtMzM4LDggKzMzOCw3IEBAIHB1YmxpYzoKICAgZnJhbmdl IChjb25zdCBmcmFuZ2UgJik7CiAgIHN0YXRpYyBib29sIHN1cHBvcnRzX3AgKGNvbnN0X3RyZWUg dHlwZSkKICAgewotICAgIC8vIERpc2FibGVkIHVudGlsIGZsb2F0aW5nIHBvaW50IHJhbmdlLW9w cyBjb21lIGxpdmUuCi0gICAgcmV0dXJuIDAgJiYgU0NBTEFSX0ZMT0FUX1RZUEVfUCAodHlwZSk7 CisgICAgcmV0dXJuIFNDQUxBUl9GTE9BVF9UWVBFX1AgKHR5cGUpOwogICB9CiAgIHZpcnR1YWwg dHJlZSB0eXBlICgpIGNvbnN0IG92ZXJyaWRlOwogICB2aXJ0dWFsIHZvaWQgc2V0ICh0cmVlLCB0 cmVlLCB2YWx1ZV9yYW5nZV9raW5kID0gVlJfUkFOR0UpIG92ZXJyaWRlOwotLSAKMi4zNy4xCgo= --0000000000001a0d6605e51dd24e--