From patchwork Wed Feb 1 15:35:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul-Antoine Arras X-Patchwork-Id: 51423 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp346342wrn; Wed, 1 Feb 2023 07:35:52 -0800 (PST) X-Google-Smtp-Source: AK7set9sQ6BUxQvF5nnuIeJM/GbUSRCI29lC+Tzrx+YM4tH2A78RuG0Xr+M8GSWF/JFO3+7ivcMu X-Received: by 2002:a05:6402:448c:b0:4a0:e31a:434 with SMTP id er12-20020a056402448c00b004a0e31a0434mr2507858edb.27.1675265752287; Wed, 01 Feb 2023 07:35:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675265752; cv=none; d=google.com; s=arc-20160816; b=G9S7uM+8mtEs9Uu1BYyL5ME5/Uih+hdseyPlyiIf982M+lh9RqGzvp4+hIyJ/FwWoy rDSwQmQJUSFYgAilINgoQ3kj0s9qLzJTPDzxr13gMRB0cybCaAo4AhIVYbWZtKBRt+b2 F523rk/aIlecC8r3v1TX3i30OHbvaAlwu1E2QU9V/2G0BRVlERYu/rk/kqVcMahX5+ZH pXWilVFXvAeFFa6l9fYuIb4XzDSjCJLcHu8QYAFMjBIRM0XVNVb+2E3dSrA/r+mczfWL pGUlKLqsUToUcHZtm4c/0GQRlRur6xJygtPTAofr4fapbvCijxWfNqhfkCGudEPDLL3s 66eg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:from:to :content-language:user-agent:mime-version:date:message-id :ironport-sdr:dmarc-filter:delivered-to; bh=31gDsAV/n0NNS8DyCWBT+Mt9iDLjACLJyRSTM0ouKuM=; b=rqqs+J8OzPkJ55hzEyWDe3j7fiDHC/g540B+CIaubrvt0g9FBf43+EsZgHG34/MX1e QxomA8lu3LeT9RTJ8y0pEeBl08GWmmV/DaPUzXU4IPA6j9y3YmVw0OW4knmpiEC1dT+7 IjVyJu90xA61qP1YWykNnboTmEBIAp8OBECJWIkWfpD8+a5mY7FlId52NIxE0sN8JCzc kHcrkVq9qLLxGIgs4dABQL7o2kvi4tdgZleGNmKedUVz/9MeTvAwXAYbNdGsGhS/Z7Ih ThhueF5Zhmna/iZnF84O45HYfBFxK02IQ2W1BYMSulIT0adeRxb1mrg7ObpmqlvyOxAb kFcw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id u8-20020a50eac8000000b0048793b0993asi21826825edp.390.2023.02.01.07.35.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Feb 2023 07:35:52 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7A0213858020 for ; Wed, 1 Feb 2023 15:35:39 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa4.mentor.iphmx.com (esa4.mentor.iphmx.com [68.232.137.252]) by sourceware.org (Postfix) with ESMTPS id B1E563858D35 for ; Wed, 1 Feb 2023 15:35:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B1E563858D35 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com X-IronPort-AV: E=Sophos;i="5.97,263,1669104000"; d="scan'208,223";a="95461907" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa4.mentor.iphmx.com with ESMTP; 01 Feb 2023 07:35:09 -0800 IronPort-SDR: ErZ1W/3stIt7nUH0NN7/tiheY9pL6q3Z4/gl3tbeqQqLyOj2toHRS5TVpl5DoK9/3/j9i6mNmL oqWji8SszYevskxRgQlbRmHbA/B3omqBbICoHEi6fUNmE8JKTQpE7cKSN038trYqm3MvzIFLT3 e41XDdGh71iyFy7040BDRXs67aMDOmgjHvxH0XFgtroVNSV21POhrU8FyStKe8GL6avJ5guNQl eifHt63DX1GrPFi2wUmu7T36cGzyErkFPE9OK90tnSez/QD/DyZZrNZn4yDEc93+CW3sFJcCNC 8Pk= Message-ID: Date: Wed, 1 Feb 2023 16:35:03 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.6.0 Content-Language: en-GB, fr To: From: Paul-Antoine Arras Subject: [PATCH] amdgcn: Add instruction pattern for conditional shift operations X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-14.mgc.mentorg.com (139.181.222.14) To svr-ies-mbx-13.mgc.mentorg.com (139.181.222.13) X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_PASS, SPF_PASS, 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: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756643461397684318?= X-GMAIL-MSGID: =?utf-8?q?1756643461397684318?= This patch introduces an instruction pattern for conditional shift operations (cond_{ashl|ashr|lshr}) in the GCN machine description. Tested on GCN3 Fiji gfx803. OK to commit? From e9c974670e8d37f725098eea97e22be5e2e9fd21 Mon Sep 17 00:00:00 2001 From: Paul-Antoine Arras Date: Wed, 1 Feb 2023 16:13:23 +0100 Subject: [PATCH] amdgcn: Add instruction pattern for conditional shift operations gcc/ChangeLog: * config/gcn/gcn-valu.md (cond_): Add cond_{ashl|ashr|lshr} gcc/testsuite/ChangeLog: * gcc.target/gcn/cond_shift_3.c: New test. * gcc.target/gcn/cond_shift_3_run.c: New test. * gcc.target/gcn/cond_shift_4.c: New test. * gcc.target/gcn/cond_shift_4_run.c: New test. * gcc.target/gcn/cond_shift_8.c: New test. * gcc.target/gcn/cond_shift_8_run.c: New test. * gcc.target/gcn/cond_shift_9.c: New test. * gcc.target/gcn/cond_shift_9_run.c: New test. --- gcc/config/gcn/gcn-valu.md | 23 +++++++++++ gcc/testsuite/gcc.target/gcn/cond_shift_3.c | 37 ++++++++++++++++++ .../gcc.target/gcn/cond_shift_3_run.c | 27 +++++++++++++ gcc/testsuite/gcc.target/gcn/cond_shift_4.c | 38 +++++++++++++++++++ .../gcc.target/gcn/cond_shift_4_run.c | 27 +++++++++++++ gcc/testsuite/gcc.target/gcn/cond_shift_8.c | 35 +++++++++++++++++ .../gcc.target/gcn/cond_shift_8_run.c | 28 ++++++++++++++ gcc/testsuite/gcc.target/gcn/cond_shift_9.c | 36 ++++++++++++++++++ .../gcc.target/gcn/cond_shift_9_run.c | 28 ++++++++++++++ 9 files changed, 279 insertions(+) create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_3.c create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_3_run.c create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_4.c create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_4_run.c create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_8.c create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_8_run.c create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_9.c create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_9_run.c diff --git gcc/config/gcn/gcn-valu.md gcc/config/gcn/gcn-valu.md index 44b04c222f7..47d9d87d58a 100644 --- gcc/config/gcn/gcn-valu.md +++ gcc/config/gcn/gcn-valu.md @@ -3489,6 +3489,29 @@ (define_expand "cond_" DONE; }) +(define_code_iterator cond_shiftop [ashift lshiftrt ashiftrt]) + +(define_expand "cond_" + [(match_operand:V_INT_noHI 0 "register_operand") + (match_operand:DI 1 "register_operand") + (cond_shiftop:V_INT_noHI + (match_operand:V_INT_noHI 2 "gcn_alu_operand") + (match_operand:V_INT_noHI 3 "gcn_alu_operand")) + (match_operand:V_INT_noHI 4 "register_operand")] + "" + { + operands[1] = force_reg (DImode, operands[1]); + operands[2] = force_reg (mode, operands[2]); + + rtx shiftby = gen_reg_rtx (mode); + convert_move (shiftby, operands[3], 0); + + emit_insn (gen_v3_exec (operands[0], operands[2], + shiftby, operands[4], + operands[1])); + DONE; + }) + ;; }}} ;; {{{ Vector reductions diff --git gcc/testsuite/gcc.target/gcn/cond_shift_3.c gcc/testsuite/gcc.target/gcn/cond_shift_3.c new file mode 100644 index 00000000000..983386c1464 --- /dev/null +++ gcc/testsuite/gcc.target/gcn/cond_shift_3.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -dp" } */ + +#include + +#define DEF_LOOP(TYPE, NAME, OP) \ + void __attribute__ ((noipa)) \ + test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \ + TYPE *__restrict b, int n) \ + { \ + for (int i = 0; i < n; ++i) \ + r[i] = a[i] > 20 ? b[i] OP 3 : 72; \ + } + +#define TEST_TYPE(T, TYPE) \ + T (TYPE, shl, <<) \ + T (TYPE, shr, >>) + +#define TEST_ALL(T) \ + TEST_TYPE (T, int32_t) \ + TEST_TYPE (T, uint32_t) \ + TEST_TYPE (T, int64_t) \ + TEST_TYPE (T, uint64_t) + +TEST_ALL (DEF_LOOP) + +/* { dg-final { scan-assembler-times {\tv_lshlrev_b32\tv[0-9]+, 3, v[0-9]+} 10 } } */ +/* { dg-final { scan-assembler-times {\tv_ashrrev_i32\tv[0-9]+, 3, v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vashlv64si3_exec} 18 } } */ +/* { dg-final { scan-assembler-times {vashrv64si3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vashlv64di3_exec} 2 } } */ +/* { dg-final { scan-assembler-times {vashrv64di3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vlshrv64si3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vlshrv64di3_exec} 1 } } */ + +/* { dg-final { scan-assembler-not {v_cndmask_b32} } } */ +/* { dg-final { scan-assembler-not {movv64di_exec/2} } } */ diff --git gcc/testsuite/gcc.target/gcn/cond_shift_3_run.c gcc/testsuite/gcc.target/gcn/cond_shift_3_run.c new file mode 100644 index 00000000000..8f89918e8ac --- /dev/null +++ gcc/testsuite/gcc.target/gcn/cond_shift_3_run.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +#include "cond_shift_3.c" + +#define N 99 + +#define TEST_LOOP(TYPE, NAME, OP) \ + { \ + TYPE r[N], a[N], b[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + a[i] = (i & 1 ? i : 3 * i); \ + b[i] = (i >> 4) << (i & 15); \ + asm volatile ("" ::: "memory"); \ + } \ + test_##TYPE##_##NAME (r, a, b, N); \ + for (int i = 0; i < N; ++i) \ + if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : 72)) \ + __builtin_abort (); \ + } + +int main () +{ + TEST_ALL (TEST_LOOP) + return 0; +} diff --git gcc/testsuite/gcc.target/gcn/cond_shift_4.c gcc/testsuite/gcc.target/gcn/cond_shift_4.c new file mode 100644 index 00000000000..c610363d9df --- /dev/null +++ gcc/testsuite/gcc.target/gcn/cond_shift_4.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -dp" } */ + +#include + +#define DEF_LOOP(TYPE, NAME, OP) \ + void __attribute__ ((noipa)) \ + test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \ + TYPE *__restrict b, int n) \ + { \ + for (int i = 0; i < n; ++i) \ + r[i] = a[i] > 20 ? b[i] OP 3 : 0; \ + } + +#define TEST_TYPE(T, TYPE) \ + T (TYPE, shl, <<) \ + T (TYPE, shr, >>) + +#define TEST_ALL(T) \ + TEST_TYPE (T, int32_t) \ + TEST_TYPE (T, uint32_t) \ + TEST_TYPE (T, int64_t) \ + TEST_TYPE (T, uint64_t) + +TEST_ALL (DEF_LOOP) + +/* { dg-final { scan-assembler-times {\tv_lshlrev_b32\tv[0-9]+, 3, v[0-9]+} 10 } } */ +/* { dg-final { scan-assembler-times {\tv_ashrrev_i32\tv[0-9]+, 3, v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vashlv64si3_exec} 18 } } */ +/* { dg-final { scan-assembler-times {vashrv64si3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vashlv64di3_exec} 2 } } */ +/* { dg-final { scan-assembler-times {vashrv64di3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vlshrv64si3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vlshrv64di3_exec} 1 } } */ + +/* { dg-final { scan-assembler-not {v_cndmask_b32} } } */ +/* { dg-final { scan-assembler-not {movv64di_exec/2} } } */ + diff --git gcc/testsuite/gcc.target/gcn/cond_shift_4_run.c gcc/testsuite/gcc.target/gcn/cond_shift_4_run.c new file mode 100644 index 00000000000..6017d68e820 --- /dev/null +++ gcc/testsuite/gcc.target/gcn/cond_shift_4_run.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +#include "cond_shift_4.c" + +#define N 99 + +#define TEST_LOOP(TYPE, NAME, OP) \ + { \ + TYPE r[N], a[N], b[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + a[i] = (i & 1 ? i : 3 * i); \ + b[i] = (i >> 4) << (i & 15); \ + asm volatile ("" ::: "memory"); \ + } \ + test_##TYPE##_##NAME (r, a, b, N); \ + for (int i = 0; i < N; ++i) \ + if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : 0)) \ + __builtin_abort (); \ + } + +int main () +{ + TEST_ALL (TEST_LOOP) + return 0; +} diff --git gcc/testsuite/gcc.target/gcn/cond_shift_8.c gcc/testsuite/gcc.target/gcn/cond_shift_8.c new file mode 100644 index 00000000000..0749e2e5e53 --- /dev/null +++ gcc/testsuite/gcc.target/gcn/cond_shift_8.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -dp" } */ + +#include + +#define DEF_LOOP(TYPE, NAME, OP) \ + void __attribute__ ((noipa)) \ + test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \ + TYPE *__restrict b, TYPE *__restrict c, int n) \ + { \ + for (int i = 0; i < n; ++i) \ + r[i] = a[i] > 20 ? b[i] OP c[i] : 91; \ + } + +#define TEST_TYPE(T, TYPE) \ + T (TYPE, shl, <<) \ + T (TYPE, shr, >>) + +#define TEST_ALL(T) \ + TEST_TYPE (T, int32_t) \ + TEST_TYPE (T, uint32_t) \ + TEST_TYPE (T, int64_t) \ + TEST_TYPE (T, uint64_t) + +TEST_ALL (DEF_LOOP) + +/* { dg-final { scan-assembler-times {vashlv64si3_exec} 18 } } */ +/* { dg-final { scan-assembler-times {vashrv64si3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vashlv64di3_exec} 2 } } */ +/* { dg-final { scan-assembler-times {vashrv64di3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vlshrv64si3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vlshrv64di3_exec} 1 } } */ + +/* { dg-final { scan-assembler-not {movv64si_exec/0} } } */ +/* { dg-final { scan-assembler-not {movv64di_exec/0} } } */ diff --git gcc/testsuite/gcc.target/gcn/cond_shift_8_run.c gcc/testsuite/gcc.target/gcn/cond_shift_8_run.c new file mode 100644 index 00000000000..13da0197569 --- /dev/null +++ gcc/testsuite/gcc.target/gcn/cond_shift_8_run.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +#include "cond_shift_8.c" + +#define N 99 + +#define TEST_LOOP(TYPE, NAME, OP) \ + { \ + TYPE r[N], a[N], b[N], c[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + a[i] = (i & 1 ? i : 3 * i); \ + b[i] = (i >> 4) << (i & 15); \ + c[i] = ~i & 7; \ + asm volatile ("" ::: "memory"); \ + } \ + test_##TYPE##_##NAME (r, a, b, c, N); \ + for (int i = 0; i < N; ++i) \ + if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : 91)) \ + __builtin_abort (); \ + } + +int main () +{ + TEST_ALL (TEST_LOOP) + return 0; +} diff --git gcc/testsuite/gcc.target/gcn/cond_shift_9.c gcc/testsuite/gcc.target/gcn/cond_shift_9.c new file mode 100644 index 00000000000..61aba27504e --- /dev/null +++ gcc/testsuite/gcc.target/gcn/cond_shift_9.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -dp" } */ + +#include + +#define DEF_LOOP(TYPE, NAME, OP) \ + void __attribute__ ((noipa)) \ + test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \ + TYPE *__restrict b, TYPE *__restrict c, int n) \ + { \ + for (int i = 0; i < n; ++i) \ + r[i] = a[i] > 20 ? b[i] OP c[i] : 0; \ + } + +#define TEST_TYPE(T, TYPE) \ + T (TYPE, shl, <<) \ + T (TYPE, shr, >>) + +#define TEST_ALL(T) \ + TEST_TYPE (T, int32_t) \ + TEST_TYPE (T, uint32_t) \ + TEST_TYPE (T, int64_t) \ + TEST_TYPE (T, uint64_t) + +TEST_ALL (DEF_LOOP) + +/* { dg-final { scan-assembler-times {vashlv64si3_exec} 18 } } */ +/* { dg-final { scan-assembler-times {vashrv64si3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vashlv64di3_exec} 2 } } */ +/* { dg-final { scan-assembler-times {vashrv64di3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vlshrv64si3_exec} 1 } } */ +/* { dg-final { scan-assembler-times {vlshrv64di3_exec} 1 } } */ + +/* { dg-final { scan-assembler-not {v_cndmask_b32} } } */ +/* { dg-final { scan-assembler-not {movv64si_exec/2} } } */ +/* { dg-final { scan-assembler-not {movv64di_exec/1} } } */ diff --git gcc/testsuite/gcc.target/gcn/cond_shift_9_run.c gcc/testsuite/gcc.target/gcn/cond_shift_9_run.c new file mode 100644 index 00000000000..de8e010bdab --- /dev/null +++ gcc/testsuite/gcc.target/gcn/cond_shift_9_run.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +#include "cond_shift_9.c" + +#define N 99 + +#define TEST_LOOP(TYPE, NAME, OP) \ + { \ + TYPE r[N], a[N], b[N], c[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + a[i] = (i & 1 ? i : 3 * i); \ + b[i] = (i >> 4) << (i & 15); \ + c[i] = ~i & 7; \ + asm volatile ("" ::: "memory"); \ + } \ + test_##TYPE##_##NAME (r, a, b, c, N); \ + for (int i = 0; i < N; ++i) \ + if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : 0)) \ + __builtin_abort (); \ + } + +int main () +{ + TEST_ALL (TEST_LOOP) + return 0; +} -- 2.39.1