commit:     29fc9edc64e0e00a0ade3065238365a4aa46ec59
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Thu Feb  8 10:48:38 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Feb  8 10:53:06 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=29fc9edc

14.0.0: backport more vectorisation fixes & postgres const expression fix

Bug: https://gcc.gnu.org/PR113808
Bug: https://gcc.gnu.org/PR113750
Bug: https://gcc.gnu.org/PR113731
Bug: https://gcc.gnu.org/PR113734 (should be same as PR113808)
Bug: https://gcc.gnu.org/PR113776
Bug: https://bugs.gentoo.org/923804
Bug: https://bugs.gentoo.org/923936
Signed-off-by: Sam James <sam <AT> gentoo.org>

 ...fix-ICE-when-moving-statements-to-empty-B.patch | 129 +++++++++++
 ...fix-ICE-when-destination-BB-for-stores-st.patch | 250 +++++++++++++++++++++
 ...-don-t-cache-restart_loop-in-vectorizable.patch |  93 ++++++++
 .../78_all_PR113776-c-boolean-conversion.patch     | 117 ++++++++++
 14.0.0/gentoo/README.history                       |   7 +
 5 files changed, 596 insertions(+)

diff --git 
a/14.0.0/gentoo/75_all_PR113731_fix-ICE-when-moving-statements-to-empty-B.patch 
b/14.0.0/gentoo/75_all_PR113731_fix-ICE-when-moving-statements-to-empty-B.patch
new file mode 100644
index 0000000..1146246
--- /dev/null
+++ 
b/14.0.0/gentoo/75_all_PR113731_fix-ICE-when-moving-statements-to-empty-B.patch
@@ -0,0 +1,129 @@
+From c22a0c0ca1a5c31d107f90efd2221eb8bc198205 Mon Sep 17 00:00:00 2001
+From: Tamar Christina <tamar.christ...@arm.com>
+Date: Wed, 7 Feb 2024 10:58:25 +0000
+Subject: [PATCH 1/3] middle-end: fix ICE when moving statements to empty BB
+ [PR113731]
+
+We use gsi_move_before (&stmt_gsi, &dest_gsi); to request that the new 
statement
+be placed before any other statement.  Typically this then moves the current
+pointer to be after the statement we just inserted.
+
+However it looks like when the BB is empty, this does not happen and the CUR
+pointer stays NULL.   There's a comment in the source of gsi_insert_before that
+explains:
+
+/* If CUR is NULL, we link at the end of the sequence (this case happens
+
+This adds a default parameter to gsi_move_before to allow us to control where
+the insertion happens.
+
+gcc/ChangeLog:
+
+       PR tree-optimization/113731
+       * gimple-iterator.cc (gsi_move_before): Take new parameter for update
+       method.
+       * gimple-iterator.h (gsi_move_before): Default new param to
+       GSI_SAME_STMT.
+       * tree-vect-loop.cc (move_early_exit_stmts): Call gsi_move_before with
+       GSI_NEW_STMT.
+
+gcc/testsuite/ChangeLog:
+
+       PR tree-optimization/113731
+       * gcc.dg/vect/vect-early-break_111-pr113731.c: New test.
+
+(cherry picked from commit 8f6ed71d8fff3c3c6249651a72aee084e31ffb9e)
+---
+ gcc/gimple-iterator.cc                        |  7 +++---
+ gcc/gimple-iterator.h                         |  3 ++-
+ .../vect/vect-early-break_111-pr113731.c      | 22 +++++++++++++++++++
+ gcc/tree-vect-loop.cc                         |  3 +--
+ 4 files changed, 29 insertions(+), 6 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
+
+diff --git a/gcc/gimple-iterator.cc b/gcc/gimple-iterator.cc
+index 517c53376f05..55ef3198c52b 100644
+--- a/gcc/gimple-iterator.cc
++++ b/gcc/gimple-iterator.cc
+@@ -666,10 +666,11 @@ gsi_move_after (gimple_stmt_iterator *from, 
gimple_stmt_iterator *to)
+ 
+ 
+ /* Move the statement at FROM so it comes right before the statement
+-   at TO.  */
++   at TO using method M.  M defaults to GSI_SAME_STMT.  */
+ 
+ void
+-gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
++gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to,
++               gsi_iterator_update m)
+ {
+   gimple *stmt = gsi_stmt (*from);
+   gsi_remove (from, false);
+@@ -677,7 +678,7 @@ gsi_move_before (gimple_stmt_iterator *from, 
gimple_stmt_iterator *to)
+   /* For consistency with gsi_move_after, it might be better to have
+      GSI_NEW_STMT here; however, that breaks several places that expect
+      that TO does not change.  */
+-  gsi_insert_before (to, stmt, GSI_SAME_STMT);
++  gsi_insert_before (to, stmt, m);
+ }
+ 
+ 
+diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h
+index 2e83a9660efc..78014a43cb93 100644
+--- a/gcc/gimple-iterator.h
++++ b/gcc/gimple-iterator.h
+@@ -86,7 +86,8 @@ extern gimple_stmt_iterator gsi_for_stmt (gimple *);
+ extern gimple_stmt_iterator gsi_for_stmt (gimple *, gimple_seq *);
+ extern gphi_iterator gsi_for_phi (gphi *);
+ extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
+-extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
++extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *,
++                           gsi_iterator_update = GSI_SAME_STMT);
+ extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
+ extern void gsi_insert_on_edge (edge, gimple *);
+ extern void gsi_insert_seq_on_edge (edge, gimple_seq);
+diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
+new file mode 100644
+index 000000000000..b205f470660a
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_111-pr113731.c
+@@ -0,0 +1,22 @@
++/* { dg-do compile } */
++/* { dg-add-options vect_early_break } */
++/* { dg-require-effective-target vect_early_break } */
++/* { dg-require-effective-target vect_long } */
++/* { dg-additional-options "-msse4.2" { target i?86-*-* x86_64-*-* } } */
++
++/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
++
++char* inet_net_pton_ipv4_bits;
++char inet_net_pton_ipv4_odst;
++void __errno_location();
++void inet_net_pton_ipv4();
++void inet_net_pton() { inet_net_pton_ipv4(); }
++void inet_net_pton_ipv4(char *dst, int size) {
++  while ((inet_net_pton_ipv4_bits > dst) & inet_net_pton_ipv4_odst) {
++    if (size-- <= 0)
++      goto emsgsize;
++    *dst++ = '\0';
++  }
++emsgsize:
++  __errno_location();
++}
+diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
+index 30b90d99925b..9aba94bd6ca2 100644
+--- a/gcc/tree-vect-loop.cc
++++ b/gcc/tree-vect-loop.cc
+@@ -11800,8 +11800,7 @@ move_early_exit_stmts (loop_vec_info loop_vinfo)
+       dump_printf_loc (MSG_NOTE, vect_location, "moving stmt %G", stmt);
+ 
+       gimple_stmt_iterator stmt_gsi = gsi_for_stmt (stmt);
+-      gsi_move_before (&stmt_gsi, &dest_gsi);
+-      gsi_prev (&dest_gsi);
++      gsi_move_before (&stmt_gsi, &dest_gsi, GSI_NEW_STMT);
+     }
+ 
+   /* Update all the stmts with their new reaching VUSES.  */
+-- 
+2.43.0
+

diff --git 
a/14.0.0/gentoo/76_all_PR113750_fix-ICE-when-destination-BB-for-stores-st.patch 
b/14.0.0/gentoo/76_all_PR113750_fix-ICE-when-destination-BB-for-stores-st.patch
new file mode 100644
index 0000000..e502439
--- /dev/null
+++ 
b/14.0.0/gentoo/76_all_PR113750_fix-ICE-when-destination-BB-for-stores-st.patch
@@ -0,0 +1,250 @@
+From 7140d52db24a930955fca57f3e8b6147d0a7fa97 Mon Sep 17 00:00:00 2001
+From: Tamar Christina <tamar.christ...@arm.com>
+Date: Wed, 7 Feb 2024 10:59:32 +0000
+Subject: [PATCH 2/3] middle-end: fix ICE when destination BB for stores starts
+ with a label [PR113750]
+
+The report shows that if the FE leaves a label as the first thing in the dest
+BB then we ICE because we move the stores before the label.
+
+This is easy to fix if we know that there's still only one way into the BB.
+We would have already rejected the loop if there was multiple paths into the BB
+however I added an additional check just for early break in case the other
+constraints are relaxed later with an explanation.
+
+After that we fix the issue just by getting the GSI after the labels and I add
+a bunch of testcases for different positions the label can be added.  Only the
+vect-early-break_112-pr113750.c one results in the label being kept.
+
+gcc/ChangeLog:
+
+       PR tree-optimization/113750
+       * tree-vect-data-refs.cc (vect_analyze_early_break_dependences): Check
+       for single predecessor when doing early break vect.
+       * tree-vect-loop.cc (move_early_exit_stmts): Get gsi at the start but
+       after labels.
+
+gcc/testsuite/ChangeLog:
+
+       PR tree-optimization/113750
+       * gcc.dg/vect/vect-early-break_112-pr113750.c: New test.
+       * gcc.dg/vect/vect-early-break_113-pr113750.c: New test.
+       * gcc.dg/vect/vect-early-break_114-pr113750.c: New test.
+       * gcc.dg/vect/vect-early-break_115-pr113750.c: New test.
+       * gcc.dg/vect/vect-early-break_116-pr113750.c: New test.
+
+(cherry picked from commit 5c3ba60024fedc6b3d374ebb071bcf5b3e27cd62)
+---
+ .../vect/vect-early-break_112-pr113750.c      | 26 +++++++++++++++++++
+ .../vect/vect-early-break_113-pr113750.c      | 26 +++++++++++++++++++
+ .../vect/vect-early-break_114-pr113750.c      | 26 +++++++++++++++++++
+ .../vect/vect-early-break_115-pr113750.c      | 26 +++++++++++++++++++
+ .../vect/vect-early-break_116-pr113750.c      | 26 +++++++++++++++++++
+ gcc/tree-vect-data-refs.cc                    | 12 +++++++++
+ gcc/tree-vect-loop.cc                         |  2 +-
+ 7 files changed, 143 insertions(+), 1 deletion(-)
+ create mode 100644 gcc/testsuite/gcc.dg/vect/vect-early-break_112-pr113750.c
+ create mode 100644 gcc/testsuite/gcc.dg/vect/vect-early-break_113-pr113750.c
+ create mode 100644 gcc/testsuite/gcc.dg/vect/vect-early-break_114-pr113750.c
+ create mode 100644 gcc/testsuite/gcc.dg/vect/vect-early-break_115-pr113750.c
+ create mode 100644 gcc/testsuite/gcc.dg/vect/vect-early-break_116-pr113750.c
+
+diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_112-pr113750.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_112-pr113750.c
+new file mode 100644
+index 000000000000..559ebd84d5c3
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_112-pr113750.c
+@@ -0,0 +1,26 @@
++/* { dg-do compile } */
++/* { dg-add-options vect_early_break } */
++/* { dg-require-effective-target vect_early_break } */
++/* { dg-require-effective-target vect_int } */
++
++/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
++
++#ifndef N
++#define N 800
++#endif
++unsigned vect_a[N];
++unsigned vect_b[N];
++
++unsigned test4(unsigned x)
++{
++ unsigned ret = 0;
++ for (int i = 0; i < N; i++)
++ {
++   vect_b[i] = x + i;
++   if (vect_a[i] != x)
++     break;
++foo:
++   vect_a[i] = x;
++ }
++ return ret;
++}
+diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_113-pr113750.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_113-pr113750.c
+new file mode 100644
+index 000000000000..ba85780a46b1
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_113-pr113750.c
+@@ -0,0 +1,26 @@
++/* { dg-do compile } */
++/* { dg-add-options vect_early_break } */
++/* { dg-require-effective-target vect_early_break } */
++/* { dg-require-effective-target vect_int } */
++
++/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
++
++#ifndef N
++#define N 800
++#endif
++unsigned vect_a[N];
++unsigned vect_b[N];
++
++unsigned test4(unsigned x)
++{
++ unsigned ret = 0;
++ for (int i = 0; i < N; i++)
++ {
++   vect_b[i] = x + i;
++   if (vect_a[i] != x)
++     break;
++   vect_a[i] = x;
++foo:
++ }
++ return ret;
++}
+diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_114-pr113750.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_114-pr113750.c
+new file mode 100644
+index 000000000000..37af2998688f
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_114-pr113750.c
+@@ -0,0 +1,26 @@
++/* { dg-do compile } */
++/* { dg-add-options vect_early_break } */
++/* { dg-require-effective-target vect_early_break } */
++/* { dg-require-effective-target vect_int } */
++
++/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
++
++#ifndef N
++#define N 800
++#endif
++unsigned vect_a[N];
++unsigned vect_b[N];
++
++unsigned test4(unsigned x)
++{
++ unsigned ret = 0;
++ for (int i = 0; i < N; i++)
++ {
++   vect_b[i] = x + i;
++foo:
++   if (vect_a[i] != x)
++     break;
++   vect_a[i] = x;
++ }
++ return ret;
++}
+diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_115-pr113750.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_115-pr113750.c
+new file mode 100644
+index 000000000000..502686d308e2
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_115-pr113750.c
+@@ -0,0 +1,26 @@
++/* { dg-do compile } */
++/* { dg-add-options vect_early_break } */
++/* { dg-require-effective-target vect_early_break } */
++/* { dg-require-effective-target vect_int } */
++
++/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
++
++#ifndef N
++#define N 800
++#endif
++unsigned vect_a[N];
++unsigned vect_b[N];
++
++unsigned test4(unsigned x)
++{
++ unsigned ret = 0;
++ for (int i = 0; i < N; i++)
++ {
++foo:
++   vect_b[i] = x + i;
++   if (vect_a[i] != x)
++     break;
++   vect_a[i] = x;
++ }
++ return ret;
++}
+diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_116-pr113750.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_116-pr113750.c
+new file mode 100644
+index 000000000000..4e02158aa351
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_116-pr113750.c
+@@ -0,0 +1,26 @@
++/* { dg-do compile } */
++/* { dg-add-options vect_early_break } */
++/* { dg-require-effective-target vect_early_break } */
++/* { dg-require-effective-target vect_int } */
++
++/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
++
++#ifndef N
++#define N 800
++#endif
++unsigned vect_a[N];
++unsigned vect_b[N];
++
++unsigned test4(unsigned x)
++{
++ unsigned ret = 0;
++ for (int i = 0; i < N; i++)
++ {
++   vect_b[i] = x + i;
++   if (vect_a[i] != x)
++foo:
++     break;
++   vect_a[i] = x;
++ }
++ return ret;
++}
+diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
+index 2ca5a1b131bf..2d3691a14564 100644
+--- a/gcc/tree-vect-data-refs.cc
++++ b/gcc/tree-vect-data-refs.cc
+@@ -819,6 +819,18 @@ vect_analyze_early_break_dependences (loop_vec_info 
loop_vinfo)
+      trapped already during loop form analysis.  */
+   gcc_assert (dest_bb->loop_father == loop);
+ 
++  /* Check that the destination block we picked has only one pred.  To relax 
this we
++     have to take special care when moving the statements.  We don't 
currently support
++     such control flow however this check is there to simplify how we handle
++     labels that may be present anywhere in the IL.  This check is to ensure 
that the
++     labels aren't significant for the CFG.  */
++  if (!single_pred (dest_bb))
++    return opt_result::failure_at (vect_location,
++                           "chosen loop exit block (BB %d) does not have a "
++                           "single predecessor which is currently not "
++                           "supported for early break vectorization.\n",
++                           dest_bb->index);
++
+   LOOP_VINFO_EARLY_BRK_DEST_BB (loop_vinfo) = dest_bb;
+ 
+   if (!LOOP_VINFO_EARLY_BRK_VUSES (loop_vinfo).is_empty ())
+diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
+index 9aba94bd6ca2..190df9ec7741 100644
+--- a/gcc/tree-vect-loop.cc
++++ b/gcc/tree-vect-loop.cc
+@@ -11786,7 +11786,7 @@ move_early_exit_stmts (loop_vec_info loop_vinfo)
+ 
+   /* Move all stmts that need moving.  */
+   basic_block dest_bb = LOOP_VINFO_EARLY_BRK_DEST_BB (loop_vinfo);
+-  gimple_stmt_iterator dest_gsi = gsi_start_bb (dest_bb);
++  gimple_stmt_iterator dest_gsi = gsi_after_labels (dest_bb);
+ 
+   for (gimple *stmt : LOOP_VINFO_EARLY_BRK_STORES (loop_vinfo))
+     {
+-- 
+2.43.0
+

diff --git 
a/14.0.0/gentoo/77_all_PR113808-middle-end-don-t-cache-restart_loop-in-vectorizable.patch
 
b/14.0.0/gentoo/77_all_PR113808-middle-end-don-t-cache-restart_loop-in-vectorizable.patch
new file mode 100644
index 0000000..1983aa7
--- /dev/null
+++ 
b/14.0.0/gentoo/77_all_PR113808-middle-end-don-t-cache-restart_loop-in-vectorizable.patch
@@ -0,0 +1,93 @@
+From ce2e742d5439c3f70f6ff641164541e506c808d1 Mon Sep 17 00:00:00 2001
+From: Tamar Christina <tamar.christ...@arm.com>
+Date: Thu, 8 Feb 2024 10:43:13 +0000
+Subject: [PATCH 3/3] middle-end: don't cache restart_loop in
+ vectorizable_live_operations [PR113808]
+
+There's a bug in vectorizable_live_operation that restart_loop is defined
+outside the loop.
+
+This variable is supposed to indicate whether we are doing a first or last
+index reduction.  The problem is that by defining it outside the loop it 
becomes
+dependent on the order we visit the USE/DEFs.
+
+In the given example, the loop isn't PEELED, but we visit the early exit uses
+first.  This then sets the boolean to true and it can't get to false again.
+
+So when we visit the main exit we still treat it as an early exit for that
+SSA name.
+
+This cleans it up and renames the variables to something that's hopefully
+clearer to their intention.
+
+gcc/ChangeLog:
+
+       PR tree-optimization/113808
+       * tree-vect-loop.cc (vectorizable_live_operation): Don't cache the
+       value cross iterations.
+
+gcc/testsuite/ChangeLog:
+
+       PR tree-optimization/113808
+       * gfortran.dg/vect/vect-early-break_1-PR113808.f90: New test.
+
+(cherry picked from commit 3f69db1812106cb5bab203e17a60300ac51cdc68)
+---
+ .../vect/vect-early-break_1-PR113808.f90      | 21 +++++++++++++++++++
+ gcc/tree-vect-loop.cc                         |  5 ++---
+ 2 files changed, 23 insertions(+), 3 deletions(-)
+ create mode 100644 
gcc/testsuite/gfortran.dg/vect/vect-early-break_1-PR113808.f90
+
+diff --git a/gcc/testsuite/gfortran.dg/vect/vect-early-break_1-PR113808.f90 
b/gcc/testsuite/gfortran.dg/vect/vect-early-break_1-PR113808.f90
+new file mode 100644
+index 000000000000..5c339fa7a348
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/vect/vect-early-break_1-PR113808.f90
+@@ -0,0 +1,21 @@
++! { dg-add-options vect_early_break }
++! { dg-require-effective-target vect_early_break }
++! { dg-require-effective-target vect_long_long }
++! { dg-additional-options "-fopenmp-simd" }
++
++! { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } }
++
++program main
++  integer :: n, i,k
++  n = 11
++  do i = 1, n,2
++    !$omp simd lastprivate(k)
++    do k = 1, i + 41
++      if (k > 11 + 41 .or. k < 1) error stop
++    end do
++  end do
++  if (k /= 53) then
++    print *, k, 53
++    error stop
++  endif
++end
+diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
+index 190df9ec7741..eed2268e9bae 100644
+--- a/gcc/tree-vect-loop.cc
++++ b/gcc/tree-vect-loop.cc
+@@ -10950,7 +10950,7 @@ vectorizable_live_operation (vec_info *vinfo, 
stmt_vec_info stmt_info,
+        did.  For the live values we want the value at the start of the 
iteration
+        rather than at the end.  */
+       edge main_e = LOOP_VINFO_IV_EXIT (loop_vinfo);
+-      bool restart_loop = LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo);
++      bool all_exits_as_early_p = LOOP_VINFO_EARLY_BREAKS_VECT_PEELED 
(loop_vinfo);
+       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs)
+       if (!is_gimple_debug (use_stmt)
+           && !flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
+@@ -10966,8 +10966,7 @@ vectorizable_live_operation (vec_info *vinfo, 
stmt_vec_info stmt_info,
+             /* For early exit where the exit is not in the BB that leads
+                to the latch then we're restarting the iteration in the
+                scalar loop.  So get the first live value.  */
+-            restart_loop = restart_loop || !main_exit_edge;
+-            if (restart_loop
++            if ((all_exits_as_early_p || !main_exit_edge)
+                 && STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
+               {
+                 tmp_vec_lhs = vec_lhs0;
+-- 
+2.43.0
+

diff --git a/14.0.0/gentoo/78_all_PR113776-c-boolean-conversion.patch 
b/14.0.0/gentoo/78_all_PR113776-c-boolean-conversion.patch
new file mode 100644
index 0000000..52d731f
--- /dev/null
+++ b/14.0.0/gentoo/78_all_PR113776-c-boolean-conversion.patch
@@ -0,0 +1,117 @@
+From bfcee89a63538b80b966b2fa7ad21d4d38fd8b3c Mon Sep 17 00:00:00 2001
+From: Joseph Myers <josmy...@redhat.com>
+Date: Thu, 8 Feb 2024 01:34:09 +0000
+Subject: [PATCH] c: Fix boolean conversion of floating constant as integer
+ constant expression [PR113776]
+
+My fix for bug 111059 and bug 111911 caused a conversion of a floating
+constant to boolean to wrongly no longer be considered an integer
+constant expression, because logic to insert a NOP_EXPR in
+c_objc_common_truthvalue_conversion for an argument not an integer
+constant expression itself now took place after rather than before the
+conversion to bool.  In the specific case of casting a floating
+constant to bool, the result is an integer constant expression even
+though the argument isn't (build_c_cast deals with ensuring that casts
+to integer type of anything of floating type more complicated than a
+single floating constant don't get wrongly treated as integer constant
+expressions even if they fold to constants), so fix the logic in
+c_objc_common_truthvalue_conversion to handle that special case.
+
+Bootstrapped with no regressions for x86_64-pc-linux-gnu.
+
+       PR c/113776
+
+gcc/c
+       * c-typeck.cc (c_objc_common_truthvalue_conversion): Return an
+       integer constant expression for boolean conversion of floating
+       constant.
+
+gcc/testsuite/
+       * gcc.dg/pr113776-1.c, gcc.dg/pr113776-2.c, gcc.dg/pr113776-3.c,
+       gcc.dg/pr113776-4.c: New tests.
+
+(cherry picked from commit bfd72bb44eca83b0db2b0bab895f27a8a44247a2)
+---
+ gcc/c/c-typeck.cc                 | 12 +++++++++++-
+ gcc/testsuite/gcc.dg/pr113776-1.c |  5 +++++
+ gcc/testsuite/gcc.dg/pr113776-2.c |  4 ++++
+ gcc/testsuite/gcc.dg/pr113776-3.c |  7 +++++++
+ gcc/testsuite/gcc.dg/pr113776-4.c |  6 ++++++
+ 5 files changed, 33 insertions(+), 1 deletion(-)
+ create mode 100644 gcc/testsuite/gcc.dg/pr113776-1.c
+ create mode 100644 gcc/testsuite/gcc.dg/pr113776-2.c
+ create mode 100644 gcc/testsuite/gcc.dg/pr113776-3.c
+ create mode 100644 gcc/testsuite/gcc.dg/pr113776-4.c
+
+diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
+index 3b519c48ae0a..ddeab1e2a8a1 100644
+--- a/gcc/c/c-typeck.cc
++++ b/gcc/c/c-typeck.cc
+@@ -13572,7 +13572,17 @@ c_objc_common_truthvalue_conversion (location_t 
location, tree expr, tree type)
+       break;
+     }
+ 
+-  int_const = (TREE_CODE (expr) == INTEGER_CST && !TREE_OVERFLOW (expr));
++  /* Conversion of a floating constant to boolean goes through here
++     and yields an integer constant expression.  Otherwise, the result
++     is only an integer constant expression if the argument is.  */
++  int_const = ((TREE_CODE (expr) == INTEGER_CST && !TREE_OVERFLOW (expr))
++             || ((TREE_CODE (expr) == REAL_CST
++                  || TREE_CODE (expr) == COMPLEX_CST)
++                 && (TREE_CODE (type) == BOOLEAN_TYPE
++                     || (TREE_CODE (type) == ENUMERAL_TYPE
++                         && ENUM_UNDERLYING_TYPE (type) != NULL_TREE
++                         && (TREE_CODE (ENUM_UNDERLYING_TYPE (type))
++                             == BOOLEAN_TYPE)))));
+   int_operands = EXPR_INT_CONST_OPERANDS (expr);
+   if (int_operands && TREE_CODE (expr) != INTEGER_CST)
+     {
+diff --git a/gcc/testsuite/gcc.dg/pr113776-1.c 
b/gcc/testsuite/gcc.dg/pr113776-1.c
+new file mode 100644
+index 000000000000..36190fbc3fec
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/pr113776-1.c
+@@ -0,0 +1,5 @@
++/* { dg-do compile } */
++/* { dg-options "-std=c11 -pedantic" } */
++
++char d[(_Bool)0.5 == 1 ? 1 : -1];
++char f[(_Bool)0.0 == 0 ? 1 : -1];
+diff --git a/gcc/testsuite/gcc.dg/pr113776-2.c 
b/gcc/testsuite/gcc.dg/pr113776-2.c
+new file mode 100644
+index 000000000000..9e88210892a4
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/pr113776-2.c
+@@ -0,0 +1,4 @@
++/* { dg-do compile } */
++/* { dg-options "-std=c11 -pedantic" } */
++
++enum e { A = (_Bool) 0.0, B = (_Bool) 0.5, C = (_Bool) 1.0 };
+diff --git a/gcc/testsuite/gcc.dg/pr113776-3.c 
b/gcc/testsuite/gcc.dg/pr113776-3.c
+new file mode 100644
+index 000000000000..c615994a89f6
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/pr113776-3.c
+@@ -0,0 +1,7 @@
++/* { dg-do compile } */
++/* { dg-options "-std=c23 -pedantic" } */
++
++enum ebool : bool { BF, BT };
++
++char d[(enum ebool)0.5 == 1 ? 1 : -1];
++char f[(enum ebool)0.0 == 0 ? 1 : -1];
+diff --git a/gcc/testsuite/gcc.dg/pr113776-4.c 
b/gcc/testsuite/gcc.dg/pr113776-4.c
+new file mode 100644
+index 000000000000..1b57557746e1
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/pr113776-4.c
+@@ -0,0 +1,6 @@
++/* { dg-do compile } */
++/* { dg-options "-std=c23 -pedantic" } */
++
++enum ebool : bool { BF, BT };
++
++enum e { A = (enum ebool) 0.0, B = (enum ebool) 0.5, C = (enum ebool) 1.0 };
+-- 
+2.43.0
+

diff --git a/14.0.0/gentoo/README.history b/14.0.0/gentoo/README.history
index afaa988..dd2e0a0 100644
--- a/14.0.0/gentoo/README.history
+++ b/14.0.0/gentoo/README.history
@@ -1,3 +1,10 @@
+20     8 Feb 2024
+
+       + 75_all_PR113731_fix-ICE-when-moving-statements-to-empty-B.patch
+       + 76_all_PR113750_fix-ICE-when-destination-BB-for-stores-st.patch
+       + 
77_all_PR113808-middle-end-don-t-cache-restart_loop-in-vectorizable.patch
+       + 78_all_PR113776-c-boolean-conversion.patch
+       
 19     5 Feb 2024
 
        - 76_all_PR113467-vect-miscompile.patch

Reply via email to