From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id 3AAFC3858D28 for ; Fri, 3 Nov 2023 22:02:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3AAFC3858D28 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3AAFC3858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::62d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699048928; cv=none; b=thL/Ss12PrZBDud8nsIyugCsm5A9EXSbNNPsUR6u2wUmaBMLfxam8GWcsVkKhbp/cTtRaT18pcTaW274WqBjXunvODht8dU+d6wdlB4/kAhczE0nKjoyD+YNRhztskt5ap+ywtdUiTY5LDDLuWedn2Rw37/BtI+RwMkmrAX6oXI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699048928; c=relaxed/simple; bh=rYezcuUfzS29Rwhj1GtvmTHnxCC+uqM+wpbN5yjhFKg=; h=DKIM-Signature:Message-ID:Date:MIME-Version:From:Subject:To; b=x8wh+VB+Bb5WcM2XIRBwHR9jneNMScQzINWBxczM6O+SMDZ3+WMhOGxEMU3oDVx9LslxXHcMQGxbmsaYwuX/S+WeoLnlZnMhBMroXRUuW6UjJcYinCNfIsZsCaNVqG9Tmg6g5YzTuXS55nS1d9wKOz8wxXICD8a/p9S5nNLY12c= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ej1-x62d.google.com with SMTP id a640c23a62f3a-9d10f94f70bso372567766b.3 for ; Fri, 03 Nov 2023 15:02:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699048925; x=1699653725; darn=gcc.gnu.org; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id:from:to :cc:subject:date:message-id:reply-to; bh=fMFdewqpMSfY/Emr+jO+S7d2T0Ro7B/EWPUfAH0hkxw=; b=EIo9VrTEnOhHD6WBUPauP44zW9k8sjTJRyCz8+oLowv0UyU7zWUT9hpCG8PLv3Tofz R8mjKQ0RD4ubyGflyNvr35tK6rwr2xrE3IC30IegjCzx70qSD5a50Q+8X/YM2kuTkSFI 299Db5e5IlZHdtuGDAfjTHoHVwmeEsYUN2Vwc7Jg1W1SuVXgovLVn22nj6j6E5iDAli1 hRht0dqKhp4aprgG2zK7R2kDAVjA+D+A9as4c1+P1ed2duqze6jLmHL4iTBPJhVlQ7RW 86f/Z3oRUP1hzTrIJJ7CpYVGvxNie87F4pD4NAqRGMcSAe5BLdgdI7S5foR+juhkODTs th7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699048925; x=1699653725; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fMFdewqpMSfY/Emr+jO+S7d2T0Ro7B/EWPUfAH0hkxw=; b=UvyL+uFnt9OsLOTsUFrwwsJ9LIcKYlJQ+gietYHKHyjkgujnSbwtGPerhuQTOJ/k9r slWvHXZA4LPe/OCChd4hnOKA8OJ9EWBRK/xriU0fHCXkCkVore7swdDFabWYtqCCVugW rrvdnQojrTgTtz9ex2r5u4fDF5tUUjidFY8LvdRUoUcn5QnfAXMlbbgTwSThyXNyobtr V3deHqPIg6kqVMFGijKVXTShAm8ncdGIO+DLcn2NcP9+sOs1zBatxX+2gu1XuAQMy411 DU02Tp/3rmDe5Z5HZ5DTx1diVbo2Tr/UTTOz6f2pI7nj0GFr/BrxPfah4cTBj/IbpzhE 1dcg== X-Gm-Message-State: AOJu0YxpyFuoHyCsOz9mUbUnNsfRhPMNDa49jGMO28M704RMALUC6KIU YSB9C17ysfdOMkJXkH0luKM= X-Google-Smtp-Source: AGHT+IE5V18p4+TqeU+TfQ8KDtTmZyBgMM2ONXtHVK8JyKfvodiPcJ7k0hhvjXHFPAd6wB5SI01o9g== X-Received: by 2002:a17:907:c50e:b0:9da:3378:536e with SMTP id tq14-20020a170907c50e00b009da3378536emr6979872ejc.39.1699048924540; Fri, 03 Nov 2023 15:02:04 -0700 (PDT) Received: from [192.168.1.24] (ip-046-223-203-173.um13.pools.vodafone-ip.de. [46.223.203.173]) by smtp.gmail.com with ESMTPSA id e6-20020a1709061e8600b0099bccb03eadsm1311727ejj.205.2023.11.03.15.02.03 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 03 Nov 2023 15:02:04 -0700 (PDT) Message-ID: <44c57964-1cb7-43d6-af88-35be341ee5cd@gmail.com> Date: Fri, 3 Nov 2023 23:02:03 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Robin Dapp Subject: Re: [PATCH] internal-fn: Add VCOND_MASK_LEN. To: Richard Biener , gcc-patches , "juzhe.zhong@rivai.ai" , richard.sandiford@arm.com Cc: rdapp.gcc@gmail.com References: <818fe7b8-cb55-49d1-94fa-f929b8cbc5d8@gmail.com> <430d3b7e-acc3-43bb-9d3e-7897aa7d2e83@gmail.com> <4e5d9e2f-2ae2-493b-9ff9-6af4a895d893@gmail.com> Content-Language: en-US In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-8.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: > Ah, OK. IMO it's better to keep the optab operands the same as the IFN > operands, even if that makes things inconsistent with vcond_mask. > vcond_mask isn't really a good example to follow, since the operand > order is not only inconsistent with the IFN, it's also inconsistent > with the natural if_then_else order. v4 attached with that changed, match.pd patterns interleaved as well as scratch-handling added and VLS modes removed. Lehua has since pushed another patch that extends gimple_match_op to 6/7 operands already so that could be removed as well making the patch even smaller now. Testsuite on riscv looks good (apart from the mentioned cond_widen...), still running on aarch64 and x86. OK if those pass? Regards Robin Subject: [PATCH v4] internal-fn: Add VCOND_MASK_LEN. In order to prevent simplification of a COND_OP with degenerate mask (CONSTM1_RTX) into just an OP in the presence of length masking this patch introduces a length-masked analog to VEC_COND_EXPR: IFN_VCOND_MASK_LEN. It also adds new match patterns that allow the combination of unconditional unary, binary and ternay operations with the VCOND_MASK_LEN into a conditional operation if the target supports it. gcc/ChangeLog: PR tree-optimization/111760 * config/riscv/autovec.md (vcond_mask_len_): Add expander. * config/riscv/riscv-protos.h (enum insn_type): Add. * config/riscv/riscv-v.cc (needs_fp_rounding): Add !pred_mov. * doc/md.texi: Add vcond_mask_len. * gimple-match-exports.cc (maybe_resimplify_conditional_op): Create VCOND_MASK_LEN when length masking. * gimple-match.h (gimple_match_op::gimple_match_op): Always initialize len and bias. * internal-fn.cc (vec_cond_mask_len_direct): Add. (direct_vec_cond_mask_len_optab_supported_p): Add. (internal_fn_len_index): Add VCOND_MASK_LEN. (internal_fn_mask_index): Ditto. * internal-fn.def (VCOND_MASK_LEN): New internal function. * match.pd: Combine unconditional unary, binary and ternary operations into the respective COND_LEN operations. * optabs.def (OPTAB_D): Add vcond_mask_len optab. gcc/testsuite/ChangeLog: * gcc.dg/vect/vect-cond-arith-2.c: No vect cost model for riscv_v. --- gcc/config/riscv/autovec.md | 26 ++++++++++ gcc/config/riscv/riscv-protos.h | 3 ++ gcc/config/riscv/riscv-v.cc | 3 +- gcc/doc/md.texi | 9 ++++ gcc/gimple-match-exports.cc | 13 +++-- gcc/gimple-match.h | 6 ++- gcc/internal-fn.cc | 5 ++ gcc/internal-fn.def | 2 + gcc/match.pd | 51 +++++++++++++++++++ gcc/optabs.def | 1 + gcc/testsuite/gcc.dg/vect/vect-cond-arith-2.c | 1 + 11 files changed, 114 insertions(+), 6 deletions(-) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index cc4c9596bbf..0a5e4ccb54e 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -565,6 +565,32 @@ (define_insn_and_split "vcond_mask_" [(set_attr "type" "vector")] ) +(define_expand "vcond_mask_len_" + [(match_operand:V 0 "register_operand") + (match_operand: 1 "nonmemory_operand") + (match_operand:V 2 "nonmemory_operand") + (match_operand:V 3 "autovec_else_operand") + (match_operand 4 "autovec_length_operand") + (match_operand 5 "const_0_operand")] + "TARGET_VECTOR" + { + if (satisfies_constraint_Wc1 (operands[1])) + riscv_vector::expand_cond_len_unop (code_for_pred_mov (mode), + operands); + else + { + /* The order of then and else is opposite to pred_merge. */ + rtx ops[] = {operands[0], operands[3], operands[3], operands[2], + operands[1]}; + riscv_vector::emit_nonvlmax_insn (code_for_pred_merge (mode), + riscv_vector::MERGE_OP_TU, + ops, operands[4]); + } + DONE; + } + [(set_attr "type" "vector")] +) + ;; ------------------------------------------------------------------------- ;; ---- [BOOL] Select based on masks ;; ------------------------------------------------------------------------- diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index a1be731c28e..0d0ee5effea 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -359,6 +359,9 @@ enum insn_type : unsigned int /* For vmerge, no mask operand, no mask policy operand. */ MERGE_OP = __NORMAL_OP_TA2 | TERNARY_OP_P, + /* For vmerge with TU policy. */ + MERGE_OP_TU = HAS_DEST_P | HAS_MERGE_P | TERNARY_OP_P | TU_POLICY_P, + /* For vm, no tail policy operand. */ COMPARE_OP = __NORMAL_OP_MA | TERNARY_OP_P, COMPARE_OP_MU = __MASK_OP_MU | TERNARY_OP_P, diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index b489ce08775..d2dde1897c4 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -3214,7 +3214,8 @@ needs_fp_rounding (unsigned icode, machine_mode mode) && icode != maybe_code_for_pred_widen (FLOAT, mode) && icode != maybe_code_for_pred_widen (UNSIGNED_FLOAT, mode) /* vfsgnj */ - && icode != maybe_code_for_pred (UNSPEC_VCOPYSIGN, mode); + && icode != maybe_code_for_pred (UNSPEC_VCOPYSIGN, mode) + && icode != maybe_code_for_pred_mov (mode); } /* Subroutine to expand COND_LEN_* patterns. */ diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index fab2513105a..10f971749bc 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5306,6 +5306,15 @@ no need to define this instruction pattern if the others are supported. Similar to @code{vcond@var{m}@var{n}} but operand 3 holds a pre-computed result of vector comparison. +@cindex @code{vcond_mask_len_@var{m}@var{n}} instruction pattern +@item @samp{vcond_mask_@var{m}@var{n}} +Similar to @code{vcond_mask@var{m}@var{n}} but operand 4 holds a variable +or constant length and operand 5 holds a bias. If the +element index < operand 4 + operand 5 the respective element of the result is +computed as in @code{vcond_mask_@var{m}@var{n}}. For element indices >= +operand 4 + operand 5 the computation is performed as if the respective mask +element were zero. + @cindex @code{maskload@var{m}@var{n}} instruction pattern @item @samp{maskload@var{m}@var{n}} Perform a masked load of vector from memory operand 1 of mode @var{m} diff --git a/gcc/gimple-match-exports.cc b/gcc/gimple-match-exports.cc index b36027b0bad..d6dac08cc2b 100644 --- a/gcc/gimple-match-exports.cc +++ b/gcc/gimple-match-exports.cc @@ -307,9 +307,16 @@ maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op, && VECTOR_TYPE_P (res_op->type) && gimple_simplified_result_is_gimple_val (res_op)) { - new_op.set_op (VEC_COND_EXPR, res_op->type, - res_op->cond.cond, res_op->ops[0], - res_op->cond.else_value); + tree len = res_op->cond.len; + if (!len) + new_op.set_op (VEC_COND_EXPR, res_op->type, + res_op->cond.cond, res_op->ops[0], + res_op->cond.else_value); + else + new_op.set_op (IFN_VCOND_MASK_LEN, res_op->type, + res_op->cond.cond, res_op->ops[0], + res_op->cond.else_value, + res_op->cond.len, res_op->cond.bias); *res_op = new_op; return gimple_resimplify3 (seq, res_op, valueize); } diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h index 9892c142285..63a9f029589 100644 --- a/gcc/gimple-match.h +++ b/gcc/gimple-match.h @@ -32,7 +32,8 @@ public: enum uncond { UNCOND }; /* Build an unconditional op. */ - gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE) {} + gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE), len + (NULL_TREE), bias (NULL_TREE) {} gimple_match_cond (tree, tree); gimple_match_cond (tree, tree, tree, tree); @@ -56,7 +57,8 @@ public: inline gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in) - : cond (cond_in), else_value (else_value_in) + : cond (cond_in), else_value (else_value_in), len (NULL_TREE), + bias (NULL_TREE) { } diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index c7d3564faef..5a998e794ad 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -170,6 +170,7 @@ init_internal_fns () #define store_lanes_direct { 0, 0, false } #define mask_store_lanes_direct { 0, 0, false } #define vec_cond_mask_direct { 1, 0, false } +#define vec_cond_mask_len_direct { 1, 1, false } #define vec_cond_direct { 2, 0, false } #define scatter_store_direct { 3, 1, false } #define len_store_direct { 3, 3, false } @@ -4690,6 +4691,7 @@ internal_fn_len_index (internal_fn fn) case IFN_MASK_LEN_STORE: case IFN_MASK_LEN_LOAD_LANES: case IFN_MASK_LEN_STORE_LANES: + case IFN_VCOND_MASK_LEN: return 3; default: @@ -4782,6 +4784,9 @@ internal_fn_mask_index (internal_fn fn) case IFN_MASK_LEN_SCATTER_STORE: return 4; + case IFN_VCOND_MASK_LEN: + return 0; + default: return (conditional_internal_fn_code (fn) != ERROR_MARK || get_unconditional_internal_fn (fn) != IFN_LAST ? 0 : -1); diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index a2023ab9c3d..7f0e3759615 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -221,6 +221,8 @@ DEF_INTERNAL_OPTAB_FN (VCONDU, ECF_CONST | ECF_NOTHROW, vcondu, vec_cond) DEF_INTERNAL_OPTAB_FN (VCONDEQ, ECF_CONST | ECF_NOTHROW, vcondeq, vec_cond) DEF_INTERNAL_OPTAB_FN (VCOND_MASK, ECF_CONST | ECF_NOTHROW, vcond_mask, vec_cond_mask) +DEF_INTERNAL_OPTAB_FN (VCOND_MASK_LEN, ECF_CONST | ECF_NOTHROW, + vcond_mask_len, cond_len_unary) DEF_INTERNAL_OPTAB_FN (VEC_SET, ECF_CONST | ECF_NOTHROW, vec_set, vec_set) DEF_INTERNAL_OPTAB_FN (VEC_EXTRACT, ECF_CONST | ECF_NOTHROW, diff --git a/gcc/match.pd b/gcc/match.pd index 424bbd02233..dbc811b2b38 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -87,6 +87,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) negate bit_not) (define_operator_list COND_UNARY IFN_COND_NEG IFN_COND_NOT) +(define_operator_list COND_LEN_UNARY + IFN_COND_LEN_NEG IFN_COND_LEN_NOT) /* Binary operations and their associated IFN_COND_* function. */ (define_operator_list UNCOND_BINARY @@ -8961,6 +8963,21 @@ and, && is_truth_type_for (op_type, TREE_TYPE (@0))) (cond_op (bit_not @0) @2 @1))))) +(for uncond_op (UNCOND_UNARY) + cond_op (COND_LEN_UNARY) + (simplify + (IFN_VCOND_MASK_LEN @0 (view_convert? (uncond_op@3 @1)) @2 @4 @5) + (with { tree op_type = TREE_TYPE (@3); } + (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type) + && is_truth_type_for (op_type, TREE_TYPE (@0))) + (cond_op @0 @1 @2 @4 @5)))) + (simplify + (IFN_VCOND_MASK_LEN @0 @1 (view_convert? (uncond_op@3 @2)) @4 @5) + (with { tree op_type = TREE_TYPE (@3); } + (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type) + && is_truth_type_for (op_type, TREE_TYPE (@0))) + (cond_op (bit_not @0) @2 @1 @4 @5))))) + /* `(a ? -1 : 0) ^ b` can be converted into a conditional not. */ (simplify (bit_xor:c (vec_cond @0 uniform_integer_cst_p@1 uniform_integer_cst_p@2) @3) @@ -9007,6 +9024,23 @@ and, && single_use (@4)) (view_convert (cond_op (bit_not @0) @2 @3 (view_convert:op_type @1))))))) +(for uncond_op (UNCOND_BINARY) + cond_op (COND_LEN_BINARY) + (simplify + (IFN_VCOND_MASK_LEN @0 (view_convert? (uncond_op@4 @1 @2)) @3 @5 @6) + (with { tree op_type = TREE_TYPE (@4); } + (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type) + && is_truth_type_for (op_type, TREE_TYPE (@0)) + && single_use (@4)) + (view_convert (cond_op @0 @1 @2 (view_convert:op_type @3) @5 @6))))) + (simplify + (IFN_VCOND_MASK_LEN @0 @1 (view_convert? (uncond_op@4 @2 @3)) @5 @6) + (with { tree op_type = TREE_TYPE (@4); } + (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type) + && is_truth_type_for (op_type, TREE_TYPE (@0)) + && single_use (@4)) + (view_convert (cond_op (bit_not @0) @2 @3 (view_convert:op_type @1) @5 @6)))))) + /* Same for ternary operations. */ (for uncond_op (UNCOND_TERNARY) cond_op (COND_TERNARY) @@ -9025,6 +9059,23 @@ and, && single_use (@5)) (view_convert (cond_op (bit_not @0) @2 @3 @4 (view_convert:op_type @1))))))) + +(for uncond_op (UNCOND_TERNARY) + cond_op (COND_LEN_TERNARY) + (simplify + (IFN_VCOND_MASK_LEN @0 (view_convert? (uncond_op@5 @1 @2 @3)) @4 @6 @7) + (with { tree op_type = TREE_TYPE (@5); } + (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type) + && is_truth_type_for (op_type, TREE_TYPE (@0)) + && single_use (@5)) + (view_convert (cond_op @0 @1 @2 @3 (view_convert:op_type @4) @6 @7))))) + (simplify + (IFN_VCOND_MASK_LEN @0 @1 (view_convert? (uncond_op@5 @2 @3 @4 @6 @7))) + (with { tree op_type = TREE_TYPE (@5); } + (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type) + && is_truth_type_for (op_type, TREE_TYPE (@0)) + && single_use (@5)) + (view_convert (cond_op (bit_not @0) @2 @3 @4 (view_convert:op_type @1) @6 @7)))))) #endif /* Detect cases in which a VEC_COND_EXPR effectively replaces the diff --git a/gcc/optabs.def b/gcc/optabs.def index 2ccbe4197b7..8d5ceeb8710 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -282,6 +282,7 @@ OPTAB_D (cond_len_fnma_optab, "cond_len_fnma$a") OPTAB_D (cond_len_fnms_optab, "cond_len_fnms$a") OPTAB_D (cond_len_neg_optab, "cond_len_neg$a") OPTAB_D (cond_len_one_cmpl_optab, "cond_len_one_cmpl$a") +OPTAB_D (vcond_mask_len_optab, "vcond_mask_len_$a") OPTAB_D (cmov_optab, "cmov$a6") OPTAB_D (cstore_optab, "cstore$a4") OPTAB_D (ctrap_optab, "ctrap$a4") diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-arith-2.c b/gcc/testsuite/gcc.dg/vect/vect-cond-arith-2.c index 7e165977e2b..7b3d73acb88 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-cond-arith-2.c +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-arith-2.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-additional-options "-fgimple -fdump-tree-optimized -ffast-math" } */ +/* { dg-additional-options "-fno-vect-cost-model" { target { riscv_v } } } */ double __GIMPLE (ssa, startwith("loop")) neg_xi (double *x) -- 2.41.0