From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by sourceware.org (Postfix) with ESMTPS id 0C3A43854159 for ; Tue, 11 Oct 2022 23:03:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0C3A43854159 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-wm1-x32a.google.com with SMTP id o20-20020a05600c4fd400b003b4a516c479so207108wmq.1 for ; Tue, 11 Oct 2022 16:03:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=list-id:mime-version:subject:message-id:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=NcyczbRUbnasv1WrOjO/r0XAiPySiFnpxlZecKK430w=; b=wU9WJoL9T2ODL39dhEisnMA2C3KCeQXh3gmpFAxGc8IUNrocx/m2SpG3/KsqZZS3lk 8FZqzcwO/A6zLwMCbVTmgGrBnd4dLNHF/OzjeoJKIgVIPBmiy+IQFIG0DVfeCQhWc19J 5+sO2mZCwnb/2k8xSwEy466m8HBkzUUp581/UJVBlG2WPg9W9eQiw8gxn0PVqPw7gY6d w+gpEy+5iJ5tt2DTYmy7FNP6bvlMomxVow6JEvYMkC7f2MpfQ0oJbcaJi4UTGktVf2gQ NJcgOlPm6AOnweCPRvcdSmvKYLiYbEoOFrFa/6LrCtCZbccrPuaky+YZkCbQPuJwZ4Ig z7GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=list-id:mime-version:subject:message-id:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NcyczbRUbnasv1WrOjO/r0XAiPySiFnpxlZecKK430w=; b=yPix55yAZONp2RemGjU7JFHodN3ZWAdjuN5ugeiz2NpcVsLEDBhnY0iOjmKtd5H/2C sEgHg4LvJV0/QVQ9bsl9Zy+f0zFKLtuHQgPtGf5lVReXRHC1hNNKUbenkF0StqOTfX3N nwXpz+XwLMb5y0gLENUfpjhycZHgOlqqO8Ma2XiJZB5S9Rc3oSwMBQuhpZ3D0BojgdwH 7YqTSyLA0vFQfTfffHAo16zguHX3YbNGI/b+iXngnoZyP7jCTRTvpW186IUS4BlbEJcC N8FDFwtuYt6cPViS5bj59cyEd/p8KW+Wj1xvy3Wr+7F4V65J6MOQ+l+CkUVkIQHmCH6g cFow== X-Gm-Message-State: ACrzQf2mdGlKAwletmjQ3eOirXg6nw00YFNQ9ElbQhhPJMxl7z5LDAF7 W3cXKuotPA34LambhjKBDiCp1w== X-Google-Smtp-Source: AMsMyM4QMZFTuvy4oC5laEpZs7V1xcz75+JH90mY9NUFOAvjwhoVLA/5TGiKLit/Sev6mMFbhy50kA== X-Received: by 2002:a05:600c:15cc:b0:3c6:6ff5:21b8 with SMTP id v12-20020a05600c15cc00b003c66ff521b8mr787442wmf.55.1665529415339; Tue, 11 Oct 2022 16:03:35 -0700 (PDT) Received: from jenkins.jenkins (ci.linaro.org. [88.99.136.175]) by smtp.gmail.com with ESMTPSA id q5-20020a05600000c500b0022e2eaa2bdcsm12350815wrx.98.2022.10.11.16.03.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Oct 2022 16:03:34 -0700 (PDT) From: ci_notify@linaro.org X-Google-Original-From: linaro-infrastructure-errors@lists.linaro.org Date: Tue, 11 Oct 2022 23:03:32 +0000 (UTC) To: Andre Vieira Cc: gcc-regression@gcc.gnu.org Message-ID: <1286803146.10588.1665529413985@jenkins.jenkins> Subject: [TCWG CI] Failure after basepoints/gcc-13-3219-g25413fdb2ac: vect: Teach vectorizer how to handle bitfield accesses MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_10587_1762195138.1665529412809" X-Jenkins-Job: TCWG Build tcwg_gcc_bootstrap/master-arm-bootstrap X-Jenkins-Result: SUCCESS List-ID: X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,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 ------=_Part_10587_1762195138.1665529412809 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Failure after basepoints/gcc-13-3219-g25413fdb2ac: vect: Teach vectorizer h= ow to handle bitfield accesses: Results changed to -10 # true: 0 # build_abe binutils: 1 # build_abe bootstrap: # FAILED # First few build errors in logs: # 00:06:09 make[3]: [Makefile:1815: armv8l-unknown-linux-gnueabihf/bits/lar= gefile-config.h] Error 1 (ignored) # 00:29:03 make[3]: [Makefile:1815: armv8l-unknown-linux-gnueabihf/bits/lar= gefile-config.h] Error 1 (ignored) # 00:31:57 /home/tcwg-buildslave/workspace/tcwg_gnu_11/abe/snapshots/gcc.gi= t~master/gcc/lra.cc:803:1: error: position plus size exceeds size of refere= nced object in =E2=80=98bit_field_ref=E2=80=99 # 00:31:57 /home/tcwg-buildslave/workspace/tcwg_gnu_11/abe/snapshots/gcc.gi= t~master/gcc/lra.cc:803:1: internal compiler error: verify_gimple failed # 00:31:57 make[3]: *** [Makefile:1147: lra.o] Error 1 # 00:38:17 make[2]: *** [Makefile:5020: all-stage3-gcc] Error 2 # 00:38:17 make[1]: *** [Makefile:25706: stage3-bubble] Error 2 # 00:38:17 make: *** [Makefile:1064: all] Error 2 from -10 # true: 0 # build_abe binutils: 1 # build_abe bootstrap: 2 THIS IS THE END OF INTERESTING STUFF. BELOW ARE LINKS TO BUILDS, REPRODUCT= ION INSTRUCTIONS, AND THE RAW COMMIT. For latest status see comments in https://linaro.atlassian.net/browse/GNU-6= 92 . Status of basepoints/gcc-13-3219-g25413fdb2ac commit for tcwg_gcc_bootstrap= : commit 25413fdb2ac24933214123e24ba165026452a6f2 Author: Andre Vieira Date: Tue Oct 11 10:49:27 2022 +0100 vect: Teach vectorizer how to handle bitfield accesses =20 gcc/ChangeLog: =20 * tree-if-conv.cc (if_convertible_loop_p_1): Move ordering of l= oop bb's from here... (tree_if_conversion): ... to here. Also call bitfield lowering= when appropriate. (version_loop_for_if_conversion): Adapt to enable loop versioni= ng when we only need to lower bitfields. (ifcvt_split_critical_edges): Relax condition of expected loop = form as this is checked earlier. (get_bitfield_rep): New function. (lower_bitfield): Likewise. (bitfields_to_lower_p): Likewise. (need_to_lower_bitfields): New global boolean. (need_to_ifcvt): Likewise. * tree-vect-data-refs.cc (vect_find_stmt_data_reference): Impro= ve diagnostic message. * tree-vect-patterns.cc (vect_recog_temp_ssa_var): Add default = value for last parameter. (vect_recog_bitfield_ref_pattern): New. (vect_recog_bit_insert_pattern): New. =20 gcc/testsuite/ChangeLog: =20 * gcc.dg/vect/vect-bitfield-read-1.c: New test. * gcc.dg/vect/vect-bitfield-read-2.c: New test. * gcc.dg/vect/vect-bitfield-read-3.c: New test. * gcc.dg/vect/vect-bitfield-read-4.c: New test. * gcc.dg/vect/vect-bitfield-read-5.c: New test. * gcc.dg/vect/vect-bitfield-read-6.c: New test. * gcc.dg/vect/vect-bitfield-write-1.c: New test. * gcc.dg/vect/vect-bitfield-write-2.c: New test. * gcc.dg/vect/vect-bitfield-write-3.c: New test. * gcc.dg/vect/vect-bitfield-write-4.c: New test. * gcc.dg/vect/vect-bitfield-write-5.c: New test. * master-arm-bootstrap ** Failure after basepoints/gcc-13-3219-g25413fdb2ac: vect: Teach vectorize= r how to handle bitfield accesses: ** https://ci.linaro.org/job/tcwg_gcc_bootstrap-build-master-arm-bootstrap/= 1603/ Bad build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-build-master-arm-b= ootstrap/1603/artifact/artifacts Good build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-build-master-arm-b= ootstrap/1602/artifact/artifacts Reproduce current build: mkdir -p investigate-gcc-25413fdb2ac24933214123e24ba165026452a6f2 cd investigate-gcc-25413fdb2ac24933214123e24ba165026452a6f2 # Fetch scripts git clone https://git.linaro.org/toolchain/jenkins-scripts # Fetch manifests for bad and good builds mkdir -p bad/artifacts good/artifacts curl -o bad/artifacts/manifest.sh https://ci.linaro.org/job/tcwg_gcc_bootst= rap-build-master-arm-bootstrap/1603/artifact/artifacts/manifest.sh --fail curl -o good/artifacts/manifest.sh https://ci.linaro.org/job/tcwg_gcc_boots= trap-build-master-arm-bootstrap/1602/artifact/artifacts/manifest.sh --fail # Reproduce bad build (cd bad; ../jenkins-scripts/tcwg_gnu-build.sh ^^ true %%rr[top_artifacts] a= rtifacts) # Reproduce good build (cd good; ../jenkins-scripts/tcwg_gnu-build.sh ^^ true %%rr[top_artifacts] = artifacts) Full commit (up to 1000 lines): commit 25413fdb2ac24933214123e24ba165026452a6f2 Author: Andre Vieira Date: Tue Oct 11 10:49:27 2022 +0100 vect: Teach vectorizer how to handle bitfield accesses =20 gcc/ChangeLog: =20 * tree-if-conv.cc (if_convertible_loop_p_1): Move ordering of l= oop bb's from here... (tree_if_conversion): ... to here. Also call bitfield lowering= when appropriate. (version_loop_for_if_conversion): Adapt to enable loop versioni= ng when we only need to lower bitfields. (ifcvt_split_critical_edges): Relax condition of expected loop = form as this is checked earlier. (get_bitfield_rep): New function. (lower_bitfield): Likewise. (bitfields_to_lower_p): Likewise. (need_to_lower_bitfields): New global boolean. (need_to_ifcvt): Likewise. * tree-vect-data-refs.cc (vect_find_stmt_data_reference): Impro= ve diagnostic message. * tree-vect-patterns.cc (vect_recog_temp_ssa_var): Add default = value for last parameter. (vect_recog_bitfield_ref_pattern): New. (vect_recog_bit_insert_pattern): New. =20 gcc/testsuite/ChangeLog: =20 * gcc.dg/vect/vect-bitfield-read-1.c: New test. * gcc.dg/vect/vect-bitfield-read-2.c: New test. * gcc.dg/vect/vect-bitfield-read-3.c: New test. * gcc.dg/vect/vect-bitfield-read-4.c: New test. * gcc.dg/vect/vect-bitfield-read-5.c: New test. * gcc.dg/vect/vect-bitfield-read-6.c: New test. * gcc.dg/vect/vect-bitfield-write-1.c: New test. * gcc.dg/vect/vect-bitfield-write-2.c: New test. * gcc.dg/vect/vect-bitfield-write-3.c: New test. * gcc.dg/vect/vect-bitfield-write-4.c: New test. * gcc.dg/vect/vect-bitfield-write-5.c: New test. --- gcc/testsuite/gcc.dg/vect/vect-bitfield-read-1.c | 40 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-read-2.c | 43 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-read-3.c | 44 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-read-4.c | 45 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-read-5.c | 42 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-read-6.c | 42 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-write-1.c | 39 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-write-2.c | 42 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-write-3.c | 43 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-write-4.c | 42 +++ gcc/testsuite/gcc.dg/vect/vect-bitfield-write-5.c | 42 +++ gcc/tree-if-conv.cc | 313 ++++++++++++++++++= -- gcc/tree-vect-data-refs.cc | 3 +- gcc/tree-vect-patterns.cc | 330 ++++++++++++++++++= +++- 14 files changed, 1079 insertions(+), 31 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-1.c b/gcc/testsui= te/gcc.dg/vect/vect-bitfield-read-1.c new file mode 100644 index 00000000000..01cf34fb444 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-1.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { int i : 31; }; + +#define ELT0 {0} +#define ELT1 {1} +#define ELT2 {2} +#define ELT3 {3} +#define N 32 +#define RES 48 +struct s A[N] + =3D { ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3}; + +int __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + int res =3D 0; + for (int i =3D 0; i < n; ++i) + res +=3D ptr[i].i; + return res; +} + +int main (void) +{ + check_vect (); + + if (f(&A[0], N) !=3D RES) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-2.c b/gcc/testsui= te/gcc.dg/vect/vect-bitfield-read-2.c new file mode 100644 index 00000000000..1a4a1579c14 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-2.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { + unsigned i : 31; + char a : 4; +}; + +#define N 32 +#define ELT0 {0x7FFFFFFFUL, 0} +#define ELT1 {0x7FFFFFFFUL, 1} +#define ELT2 {0x7FFFFFFFUL, 2} +#define ELT3 {0x7FFFFFFFUL, 3} +#define RES 48 +struct s A[N] + =3D { ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3}; + +int __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + int res =3D 0; + for (int i =3D 0; i < n; ++i) + res +=3D ptr[i].a; + return res; +} + +int main (void) +{ + check_vect (); + + if (f(&A[0], N) !=3D RES) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-3.c b/gcc/testsui= te/gcc.dg/vect/vect-bitfield-read-3.c new file mode 100644 index 00000000000..849f4a017e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-3.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" +#include + +extern void abort(void); + +typedef struct { + int c; + int b; + bool a : 1; + int d : 31; +} struct_t; + +#define N 16 +#define ELT_F { 0xFFFFFFFF, 0xFFFFFFFF, 0, 0x7FFFFFFF } +#define ELT_T { 0xFFFFFFFF, 0xFFFFFFFF, 1, 0x7FFFFFFF } + +struct_t vect_false[N] =3D { ELT_F, ELT_F, ELT_F, ELT_F, ELT_F, ELT_F, ELT= _F, ELT_F, +=09=09=09 ELT_F, ELT_F, ELT_F, ELT_F, ELT_F, ELT_F, ELT_F, ELT_F }; +struct_t vect_true[N] =3D { ELT_F, ELT_F, ELT_T, ELT_F, ELT_F, ELT_F, ELT= _F, ELT_F, +=09=09=09 ELT_F, ELT_F, ELT_T, ELT_F, ELT_F, ELT_F, ELT_F, ELT_F }; +int main (void) +{ + unsigned ret =3D 0; + for (unsigned i =3D 0; i < N; i++) + { + ret |=3D vect_false[i].a; + } + if (ret) + abort (); + + for (unsigned i =3D 0; i < N; i++) + { + ret |=3D vect_true[i].a; + } + if (!ret) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-4.c b/gcc/testsui= te/gcc.dg/vect/vect-bitfield-read-4.c new file mode 100644 index 00000000000..5bc9c412e96 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-4.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { + unsigned i : 31; + char x : 2; + char a : 4; +}; + +#define N 32 +#define ELT0 {0x7FFFFFFFUL, 3, 0} +#define ELT1 {0x7FFFFFFFUL, 3, 1} +#define ELT2 {0x7FFFFFFFUL, 3, 2} +#define ELT3 {0x7FFFFFFFUL, 3, 3} +#define RES 48 +struct s A[N] + =3D { ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3}; + +int __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + int res =3D 0; + for (int i =3D 0; i < n; ++i) + res +=3D ptr[i].a; + return res; +} + +int main (void) +{ + check_vect (); + + if (f(&A[0], N) !=3D RES) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-5.c b/gcc/testsui= te/gcc.dg/vect/vect-bitfield-read-5.c new file mode 100644 index 00000000000..1dc24d3eded --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-5.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { + unsigned a : 23; unsigned b : 9; +}; + +#define N 32 +#define ELT0 {0x7FFFFFUL, 0} +#define ELT1 {0x7FFFFFUL, 1} +#define ELT2 {0x7FFFFFUL, 2} +#define ELT3 {0x7FFFFFUL, 3} +#define RES 48 +struct s A[N] + =3D { ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3}; + +int __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + int res =3D 0; + for (int i =3D 0; i < n; ++i) + res +=3D ptr[i].b; + return res; +} + +int main (void) +{ + check_vect (); + + if (f(&A[0], N) !=3D RES) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-6.c b/gcc/testsui= te/gcc.dg/vect/vect-bitfield-read-6.c new file mode 100644 index 00000000000..7d24c299758 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-6.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { + unsigned a : 23; unsigned b : 8; +}; + +#define N 32 +#define ELT0 {0x7FFFFFUL, 0} +#define ELT1 {0x7FFFFFUL, 1} +#define ELT2 {0x7FFFFFUL, 2} +#define ELT3 {0x7FFFFFUL, 3} +#define RES 48 +struct s A[N] + =3D { ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3, + ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3}; + +int __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + int res =3D 0; + for (int i =3D 0; i < n; ++i) + res +=3D ptr[i].b; + return res; +} + +int main (void) +{ + check_vect (); + + if (f(&A[0], N) !=3D RES) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-1.c b/gcc/testsu= ite/gcc.dg/vect/vect-bitfield-write-1.c new file mode 100644 index 00000000000..19683d277b1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-1.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { int i : 31; }; + +#define N 32 +#define V 5 +struct s A[N]; + +void __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + for (int i =3D 0; i < n; ++i) + ptr[i].i =3D V; +} + +void __attribute__ ((noipa)) +check_f(struct s *ptr) { + for (unsigned i =3D 0; i < N; ++i) + if (ptr[i].i !=3D V) +=09abort (); +} + +int main (void) +{ + check_vect (); + __builtin_memset (&A[0], 0, sizeof(struct s) * N); + + f(&A[0], N); + check_f (&A[0]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-2.c b/gcc/testsu= ite/gcc.dg/vect/vect-bitfield-write-2.c new file mode 100644 index 00000000000..d550dd35ab7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-2.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { + unsigned i : 31; + char a : 4; +}; + +#define N 32 +#define V 5 +struct s A[N]; + +void __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + for (int i =3D 0; i < n; ++i) + ptr[i].a =3D V; +} + +void __attribute__ ((noipa)) +check_f(struct s *ptr) { + for (unsigned i =3D 0; i < N; ++i) + if (ptr[i].a !=3D V) +=09abort (); +} + +int main (void) +{ + check_vect (); + __builtin_memset (&A[0], 0, sizeof(struct s) * N); + + f(&A[0], N); + check_f (&A[0]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-3.c b/gcc/testsu= ite/gcc.dg/vect/vect-bitfield-write-3.c new file mode 100644 index 00000000000..3303d2610ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-3.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { + unsigned i : 31; + char x : 2; + char a : 4; +}; + +#define N 32 +#define V 5 +struct s A[N]; + +void __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + for (int i =3D 0; i < n; ++i) + ptr[i].a =3D V; +} + +void __attribute__ ((noipa)) +check_f(struct s *ptr) { + for (unsigned i =3D 0; i < N; ++i) + if (ptr[i].a !=3D V) +=09abort (); +} + +int main (void) +{ + check_vect (); + __builtin_memset (&A[0], 0, sizeof(struct s) * N); + + f(&A[0], N); + check_f (&A[0]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-4.c b/gcc/testsu= ite/gcc.dg/vect/vect-bitfield-write-4.c new file mode 100644 index 00000000000..fae6ea3557d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-4.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { + unsigned b : 23; + unsigned a : 9; +}; + +#define N 32 +#define V 5 +struct s A[N]; + +void __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + for (int i =3D 0; i < n; ++i) + ptr[i].a =3D V; +} + +void __attribute__ ((noipa)) +check_f(struct s *ptr) { + for (unsigned i =3D 0; i < N; ++i) + if (ptr[i].a !=3D V) +=09abort (); +} + +int main (void) +{ + check_vect (); + __builtin_memset (&A[0], 0, sizeof(struct s) * N); + + f(&A[0], N); + check_f (&A[0]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-5.c b/gcc/testsu= ite/gcc.dg/vect/vect-bitfield-write-5.c new file mode 100644 index 00000000000..99360c2967b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-write-5.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +extern void abort(void); + +struct s { + unsigned b : 23; + unsigned a : 8; +}; + +#define N 32 +#define V 5 +struct s A[N]; + +void __attribute__ ((noipa)) +f(struct s *ptr, unsigned n) { + for (int i =3D 0; i < n; ++i) + ptr[i].a =3D V; +} + +void __attribute__ ((noipa)) +check_f(struct s *ptr) { + for (unsigned i =3D 0; i < N; ++i) + if (ptr[i].a !=3D V) +=09abort (); +} + +int main (void) +{ + check_vect (); + __builtin_memset (&A[0], 0, sizeof(struct s) * N); + + f(&A[0], N); + check_f (&A[0]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ + diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index bac29fb5574..e468a4659fa 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -91,6 +91,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "ssa.h" #include "expmed.h" +#include "expr.h" #include "optabs-query.h" #include "gimple-pretty-print.h" #include "alias.h" @@ -123,6 +124,9 @@ along with GCC; see the file COPYING3. If not see #include "tree-vectorizer.h" #include "tree-eh.h" =20 +/* For lang_hooks.types.type_for_mode. */ +#include "langhooks.h" + /* Only handle PHIs with no more arguments unless we are asked to by simd pragma. */ #define MAX_PHI_ARG_NUM \ @@ -145,6 +149,12 @@ static bool need_to_rewrite_undefined; before phi_convertible_by_degenerating_args. */ static bool any_complicated_phi; =20 +/* True if we have bitfield accesses we can lower. */ +static bool need_to_lower_bitfields; + +/* True if there is any ifcvting to be done. */ +static bool need_to_ifcvt; + /* Hash for struct innermost_loop_behavior. It depends on the user to free the memory. */ =20 @@ -1411,15 +1421,6 @@ if_convertible_loop_p_1 (class loop *loop, vec *refs) =20 calculate_dominance_info (CDI_DOMINATORS); =20 - /* Allow statements that can be handled during if-conversion. */ - ifc_bbs =3D get_loop_body_in_if_conv_order (loop); - if (!ifc_bbs) - { - if (dump_file && (dump_flags & TDF_DETAILS)) -=09fprintf (dump_file, "Irreducible loop\n"); - return false; - } - for (i =3D 0; i < loop->num_nodes; i++) { basic_block bb =3D ifc_bbs[i]; @@ -2899,18 +2900,22 @@ version_loop_for_if_conversion (class loop *loop, v= ec *preds) class loop *new_loop; gimple *g; gimple_stmt_iterator gsi; - unsigned int save_length; + unsigned int save_length =3D 0; =20 g =3D gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2, =09=09=09=09 build_int_cst (integer_type_node, loop->num), =09=09=09=09 integer_zero_node); gimple_call_set_lhs (g, cond); =20 - /* Save BB->aux around loop_version as that uses the same field. */ - save_length =3D loop->inner ? loop->inner->num_nodes : loop->num_nodes; - void **saved_preds =3D XALLOCAVEC (void *, save_length); - for (unsigned i =3D 0; i < save_length; i++) - saved_preds[i] =3D ifc_bbs[i]->aux; + void **saved_preds =3D NULL; + if (any_complicated_phi || need_to_predicate) + { + /* Save BB->aux around loop_version as that uses the same field. */ + save_length =3D loop->inner ? loop->inner->num_nodes : loop->num_nod= es; + saved_preds =3D XALLOCAVEC (void *, save_length); + for (unsigned i =3D 0; i < save_length; i++) +=09saved_preds[i] =3D ifc_bbs[i]->aux; + } =20 initialize_original_copy_tables (); /* At this point we invalidate porfile confistency until IFN_LOOP_VECTOR= IZED @@ -2922,8 +2927,9 @@ version_loop_for_if_conversion (class loop *loop, vec= *preds) =09=09=09 profile_probability::always (), true); free_original_copy_tables (); =20 - for (unsigned i =3D 0; i < save_length; i++) - ifc_bbs[i]->aux =3D saved_preds[i]; + if (any_complicated_phi || need_to_predicate) + for (unsigned i =3D 0; i < save_length; i++) + ifc_bbs[i]->aux =3D saved_preds[i]; =20 if (new_loop =3D=3D NULL) return NULL; @@ -2999,7 +3005,7 @@ ifcvt_split_critical_edges (class loop *loop, bool ag= gressive_if_conv) auto_vec critical_edges; =20 /* Loop is not well formed. */ - if (num <=3D 2 || loop->inner || !single_exit (loop)) + if (loop->inner) return false; =20 body =3D get_loop_body (loop); @@ -3260,6 +3266,201 @@ ifcvt_hoist_invariants (class loop *loop, edge pe) free (body); } =20 +/* Returns the DECL_FIELD_BIT_OFFSET of the bitfield accesse in stmt iff i= ts + type mode is not BLKmode. If BITPOS is not NULL it will hold the poly_= int64 + value of the DECL_FIELD_BIT_OFFSET of the bitfield access and STRUCT_EX= PR, + if not NULL, will hold the tree representing the base struct of this + bitfield. */ + +static tree +get_bitfield_rep (gassign *stmt, bool write, tree *bitpos, +=09=09 tree *struct_expr) +{ + tree comp_ref =3D write ? gimple_assign_lhs (stmt) +=09=09=09: gimple_assign_rhs1 (stmt); + + tree field_decl =3D TREE_OPERAND (comp_ref, 1); + tree rep_decl =3D DECL_BIT_FIELD_REPRESENTATIVE (field_decl); + + /* Bail out if the representative is BLKmode as we will not be able to + vectorize this. */ + if (TYPE_MODE (TREE_TYPE (rep_decl)) =3D=3D E_BLKmode) + return NULL_TREE; + + /* Bail out if the DECL_SIZE of the field_decl isn't the same as the BF'= s + precision. */ + unsigned HOST_WIDE_INT bf_prec + =3D TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt))); + if (compare_tree_int (DECL_SIZE (field_decl), bf_prec) !=3D 0) + return NULL_TREE; + + if (struct_expr) + *struct_expr =3D TREE_OPERAND (comp_ref, 0); + + if (bitpos) + *bitpos + =3D fold_build2 (MINUS_EXPR, bitsizetype, +=09=09 DECL_FIELD_BIT_OFFSET (field_decl), +=09=09 DECL_FIELD_BIT_OFFSET (rep_decl)); + + return rep_decl; + +} + +/* Lowers the bitfield described by DATA. + For a write like: + + struct.bf =3D _1; + + lower to: + + __ifc_1 =3D struct.; + __ifc_2 =3D BIT_INSERT_EXPR (__ifc_1, _1, bitpos); + struct. =3D __ifc_2; + + For a read: + + _1 =3D struct.bf; + + lower to: + + __ifc_1 =3D struct.; + _1 =3D BIT_FIELD_REF (__ifc_1, bitsize, bitpos); + + where representative is a legal load that contains the bitfield value, + bitsize is the size of the bitfield and bitpos the offset to the start= of + the bitfield within the representative. */ + +static void +lower_bitfield (gassign *stmt, bool write) +{ + tree struct_expr; + tree bitpos; + tree rep_decl =3D get_bitfield_rep (stmt, write, &bitpos, &struct_expr); + tree rep_type =3D TREE_TYPE (rep_decl); + tree bf_type =3D TREE_TYPE (gimple_assign_lhs (stmt)); + + gimple_stmt_iterator gsi =3D gsi_for_stmt (stmt); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Lowering:\n"); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + fprintf (dump_file, "to:\n"); + } + + /* REP_COMP_REF is a COMPONENT_REF for the representative. NEW_VAL is i= t's + defining SSA_NAME. */ + tree rep_comp_ref =3D build3 (COMPONENT_REF, rep_type, struct_expr, rep_= decl, +=09=09=09 NULL_TREE); + tree new_val =3D ifc_temp_var (rep_type, rep_comp_ref, &gsi); + + if (dump_file && (dump_flags & TDF_DETAILS)) + print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (new_val), 0, TDF_SLIM= ); + + if (write) + { + new_val =3D ifc_temp_var (rep_type, +=09=09=09 build3 (BIT_INSERT_EXPR, rep_type, new_val, +=09=09=09=09 unshare_expr (gimple_assign_rhs1 (stmt)), +=09=09=09=09 bitpos), &gsi); + + if (dump_file && (dump_flags & TDF_DETAILS)) +=09print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (new_val), 0, TDF_SLIM)= ; + + gimple *new_stmt =3D gimple_build_assign (unshare_expr (rep_comp_ref= ), +=09=09=09=09=09 new_val); + gimple_move_vops (new_stmt, stmt); + gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); + + if (dump_file && (dump_flags & TDF_DETAILS)) +=09print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM); + } + else + { + tree bfr =3D build3 (BIT_FIELD_REF, bf_type, new_val, +=09=09=09 build_int_cst (bitsizetype, TYPE_PRECISION (bf_type)), +=09=09=09 bitpos); + new_val =3D ifc_temp_var (bf_type, bfr, &gsi); + + gimple *new_stmt =3D gimple_build_assign (gimple_assign_lhs (stmt), +=09=09=09=09=09 new_val); + gimple_move_vops (new_stmt, stmt); + gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); + + if (dump_file && (dump_flags & TDF_DETAILS)) +=09print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM); + } + + gsi_remove (&gsi, true); +} + +/* Return TRUE if there are bitfields to lower in this LOOP. Fill TO_LOWE= R + with data structures representing these bitfields. */ + +static bool +bitfields_to_lower_p (class loop *loop, +=09=09 vec &reads_to_lower, +=09=09 vec &writes_to_lower) +{ + gimple_stmt_iterator gsi; + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Analyzing loop %d for bitfields:\n", loop->num)= ; + } + + for (unsigned i =3D 0; i < loop->num_nodes; ++i) + { + basic_block bb =3D ifc_bbs[i]; + for (gsi =3D gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) +=09{ +=09 gassign *stmt =3D dyn_cast (gsi_stmt (gsi)); +=09 if (!stmt) +=09 continue; + +=09 tree op =3D gimple_assign_lhs (stmt); +=09 bool write =3D TREE_CODE (op) =3D=3D COMPONENT_REF; + +=09 if (!write) +=09 op =3D gimple_assign_rhs1 (stmt); + +=09 if (TREE_CODE (op) !=3D COMPONENT_REF) +=09 continue; + +=09 if (DECL_BIT_FIELD_TYPE (TREE_OPERAND (op, 1))) +=09 { +=09 if (dump_file && (dump_flags & TDF_DETAILS)) +=09=09print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + +=09 if (!INTEGRAL_TYPE_P (TREE_TYPE (op))) +=09=09{ +=09=09 if (dump_file && (dump_flags & TDF_DETAILS)) +=09=09 fprintf (dump_file, "\t Bitfield NO OK to lower," +=09=09=09=09=09" field type is not Integral.\n"); +=09=09 return false; +=09=09} + +=09 if (!get_bitfield_rep (stmt, write, NULL, NULL)) +=09=09{ +=09=09 if (dump_file && (dump_flags & TDF_DETAILS)) +=09=09 fprintf (dump_file, "\t Bitfield NOT OK to lower," +=09=09=09=09=09" representative is BLKmode.\n"); +=09=09 return false; +=09=09} + +=09 if (dump_file && (dump_flags & TDF_DETAILS)) +=09=09fprintf (dump_file, "\tBitfield OK to lower.\n"); +=09 if (write) +=09=09writes_to_lower.safe_push (stmt); +=09 else +=09=09reads_to_lower.safe_push (stmt); +=09 } +=09} + } + return !reads_to_lower.is_empty () || !writes_to_lower.is_empty (); +} + + /* If-convert LOOP when it is legal. For the moment this pass has no profitability analysis. Returns non-zero todo flags when something changed. */ @@ -3270,12 +3471,16 @@ tree_if_conversion (class loop *loop, vec= *preds) unsigned int todo =3D 0; bool aggressive_if_conv; class loop *rloop; + auto_vec reads_to_lower; + auto_vec writes_to_lower; bitmap exit_bbs; edge pe; =20 again: rloop =3D NULL; ifc_bbs =3D NULL; + need_to_lower_bitfields =3D false; + need_to_ifcvt =3D false; need_to_predicate =3D false; need_to_rewrite_undefined =3D false; any_complicated_phi =3D false; @@ -3291,16 +3496,42 @@ tree_if_conversion (class loop *loop, vec= *preds) =09aggressive_if_conv =3D true; } =20 - if (!ifcvt_split_critical_edges (loop, aggressive_if_conv)) + if (!single_exit (loop)) goto cleanup; =20 - if (!if_convertible_loop_p (loop) - || !dbg_cnt (if_conversion_tree)) + /* If there are more than two BBs in the loop then there is at least one= if + to convert. */ + if (loop->num_nodes > 2 + && !ifcvt_split_critical_edges (loop, aggressive_if_conv)) goto cleanup; =20 - if ((need_to_predicate || any_complicated_phi) - && ((!flag_tree_loop_vectorize && !loop->force_vectorize) -=09 || loop->dont_vectorize)) + ifc_bbs =3D get_loop_body_in_if_conv_order (loop); + if (!ifc_bbs) + { + if (dump_file && (dump_flags & TDF_DETAILS)) +=09fprintf (dump_file, "Irreducible loop\n"); + goto cleanup; + } + + if (loop->num_nodes > 2) + { + need_to_ifcvt =3D true; + + if (!if_convertible_loop_p (loop) || !dbg_cnt (if_conversion_tree)) +=09goto cleanup; + + if ((need_to_predicate || any_complicated_phi) +=09 && ((!flag_tree_loop_vectorize && !loop->force_vectorize) +=09 || loop->dont_vectorize)) +=09goto cleanup; + } + + if ((flag_tree_loop_vectorize || loop->force_vectorize) + && !loop->dont_vectorize) + need_to_lower_bitfields =3D bitfields_to_lower_p (loop, reads_to_lower= , +=09=09=09=09=09=09 writes_to_lower); + + if (!need_to_ifcvt && !need_to_lower_bitfields) goto cleanup; =20 /* The edge to insert invariant stmts on. */ @@ -3311,7 +3542,8 @@ tree_if_conversion (class loop *loop, vec *= preds) Either version this loop, or if the pattern is right for outer-loop vectorization, version the outer loop. In the latter case we will still if-convert the original inner loop. */ - if (need_to_predicate + if (need_to_lower_bitfields + || need_to_predicate || any_complicated_phi || flag_tree_loop_if_convert !=3D 1) { @@ -3351,10 +3583,31 @@ tree_if_conversion (class loop *loop, vec= *preds) =09pe =3D single_pred_edge (gimple_bb (preds->last ())); } =20 - /* Now all statements are if-convertible. Combine all the basic - blocks into one huge basic block doing the if-conversion - on-the-fly. */ - combine_blocks (loop); + if (need_to_lower_bitfields) + { + if (dump_file && (dump_flags & TDF_DETAILS)) +=09{ +=09 fprintf (dump_file, "-------------------------\n"); +=09 fprintf (dump_file, "Start lowering bitfields\n"); +=09} + while (!reads_to_lower.is_empty ()) +=09lower_bitfield (reads_to_lower.pop (), false); + while (!writes_to_lower.is_empty ()) +=09lower_bitfield (writes_to_lower.pop (), true); + + if (dump_file && (dump_flags & TDF_DETAILS)) +=09{ +=09 fprintf (dump_file, "Done lowering bitfields\n"); +=09 fprintf (dump_file, "-------------------------\n"); +=09} + } + if (need_to_ifcvt) + { + /* Now all statements are if-convertible. Combine all the basic +=09 blocks into one huge basic block doing the if-conversion +=09 on-the-fly. */ + combine_blocks (loop); + } ------=_Part_10587_1762195138.1665529412809--