[gcc r14-11112] Revert "arm: [MVE intrinsics] Fix support for predicate constants [PR target/114801]"
https://gcc.gnu.org/g:ecd031a9470257324484c66b51c6baff943e01ab commit r14-2-gecd031a9470257324484c66b51c6baff943e01ab Author: Christophe Lyon Date: Mon Dec 23 08:11:34 2024 + Revert "arm: [MVE intrinsics] Fix support for predicate constants [PR target/114801]" This reverts commit 0631c5770e8162dbe67c73dee0327313c19822c2. Diff: --- gcc/config/arm/arm-mve-builtins.cc | 32 +--- gcc/testsuite/gcc.target/arm/mve/pr108443-run.c | 2 +- gcc/testsuite/gcc.target/arm/mve/pr108443.c | 4 +-- gcc/testsuite/gcc.target/arm/mve/pr114801.c | 39 - 4 files changed, 4 insertions(+), 73 deletions(-) diff --git a/gcc/config/arm/arm-mve-builtins.cc b/gcc/config/arm/arm-mve-builtins.cc index ec856f7d6168..e1826ae40527 100644 --- a/gcc/config/arm/arm-mve-builtins.cc +++ b/gcc/config/arm/arm-mve-builtins.cc @@ -2107,37 +2107,7 @@ function_expander::add_input_operand (insn_code icode, rtx x) mode = GET_MODE (x); } else if (VALID_MVE_PRED_MODE (mode)) -{ - if (CONST_INT_P (x)) - { - if (mode == V8BImode || mode == V4BImode) - { - /* In V8BI or V4BI each element has 2 or 4 bits, if those bits -aren't all the same, gen_lowpart might ICE. Canonicalize all -the 2 or 4 bits to all ones if any of them is non-zero. V8BI -and V4BI multi-bit masks are interpreted byte-by-byte at -instruction level, but such constants should describe lanes, -rather than bytes. See the section on MVE intrinsics in the -Arm ACLE specification. */ - unsigned HOST_WIDE_INT xi = UINTVAL (x); - xi |= ((xi & 0x) << 1) | ((xi & 0x) >> 1); - if (mode == V4BImode) - xi |= ((xi & 0x) << 2) | ((xi & 0x) >> 2); - if (xi != UINTVAL (x)) - warning_at (location, 0, "constant predicate argument %d" - " (%wx) does not map to %d lane numbers," - " converted to %wx", - opno, UINTVAL (x) & 0x, - mode == V8BImode ? 8 : 4, - xi & 0x); - - x = gen_int_mode (xi, HImode); - } - x = gen_lowpart (mode, x); - } - else - x = force_lowpart_subreg (mode, x, GET_MODE (x)); -} +x = gen_lowpart (mode, x); m_ops.safe_grow (m_ops.length () + 1, true); create_input_operand (&m_ops.last (), x, mode); diff --git a/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c b/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c index b894f019b8bb..cb4b45bd3056 100644 --- a/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c +++ b/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c @@ -16,7 +16,7 @@ __attribute__ ((noipa)) partial_write (uint32_t *a, uint32x4_t v, unsigned short int main (void) { - unsigned short p = 0x00FF; + unsigned short p = 0x00CC; uint32_t a[] = {0, 0, 0, 0}; uint32_t b[] = {0, 0, 0, 0}; uint32x4_t v = vdupq_n_u32 (0xU); diff --git a/gcc/testsuite/gcc.target/arm/mve/pr108443.c b/gcc/testsuite/gcc.target/arm/mve/pr108443.c index 0c0e2dd6eb8f..c5fbfa4a1bb7 100644 --- a/gcc/testsuite/gcc.target/arm/mve/pr108443.c +++ b/gcc/testsuite/gcc.target/arm/mve/pr108443.c @@ -7,8 +7,8 @@ void __attribute__ ((noipa)) partial_write_cst (uint32_t *a, uint32x4_t v) { - vstrwq_p_u32 (a, v, 0x00FF); + vstrwq_p_u32 (a, v, 0x00CC); } -/* { dg-final { scan-assembler {mov\tr[0-9]+, #255} } } */ +/* { dg-final { scan-assembler {mov\tr[0-9]+, #204} } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/pr114801.c b/gcc/testsuite/gcc.target/arm/mve/pr114801.c deleted file mode 100644 index ab3130fd4ce8.. --- a/gcc/testsuite/gcc.target/arm/mve/pr114801.c +++ /dev/null @@ -1,39 +0,0 @@ -/* { dg-do compile } */ -/* { dg-require-effective-target arm_v8_1m_mve_ok } */ -/* { dg-options "-O2" } */ -/* { dg-add-options arm_v8_1m_mve } */ -/* { dg-final { check-function-bodies "**" "" "" } } */ - -#include - -/* -** test_32: -**... -** mov r[0-9]+, #65295 @ movhi -**... -*/ -uint32x4_t test_32() { - /* V4BI predicate converted to 0xff0f. */ - return vdupq_m_n_u32(vdupq_n_u32(0x), 0, 0x4f02); /* { dg-warning {constant predicate argument 3 \(0x4f02\) does not map to 4 lane numbers, converted to 0xff0f} } */ -} - -/* -** test_16: -**... -** mov r[0-9]+, #12339 @ movhi -**... -*/ -uint16x8_t test_16() { - /* V8BI predicate converted to 0x3033. */ - return vdupq_m_n_u16(vdupq_n_u16(0x), 0, 0x3021); /* { dg-warning {constant predicate argument 3 \(0x3021\) does not map to 8 lane numbers, converted to 0x3033} } */ -} - -/* -** test_8: -**... -** mov r[0-9]+, #23055 @ movhi -**... -*/ -uint8x16_t test_8() { - return vdupq_m_n_u8(vdupq_n_u8(0xff), 0, 0x5a0f); -}
[gcc r15-6424] libcc1: Fix tags generation target
https://gcc.gnu.org/g:6c59463a6fc6cd3ed4d0aad492af40c7ddd12f2a commit r15-6424-g6c59463a6fc6cd3ed4d0aad492af40c7ddd12f2a Author: Simon Martin Date: Mon Dec 23 13:28:31 2024 +0100 libcc1: Fix tags generation target 'make tags' currently fails for libcc1 with this: *** No rule to make target `marshall-c.hh', needed by `tags-am'. Stop. The problem is that while marshall-c.hh has been removed via r12-454-g25d1a6ecdc443f, it's still part of the libcc1_la_SOURCES variable, hence the 'tags' target has a dependency on it. This patch simply removes the marshall_c_source variable, that should be empty. libcc1/ChangeLog: * Makefile.am: Remove reference to deleted marshall-c.h. * Makefile.in: Regenerate. Diff: --- libcc1/Makefile.am | 5 ++--- libcc1/Makefile.in | 9 - 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/libcc1/Makefile.am b/libcc1/Makefile.am index b592bc8645f1..062f4a74cc23 100644 --- a/libcc1/Makefile.am +++ b/libcc1/Makefile.am @@ -51,12 +51,11 @@ endif shared_source = callbacks.cc callbacks.hh connection.cc connection.hh \ marshall.cc marshall.hh rpc.hh status.hh -marshall_c_source = marshall-c.hh marshall_cxx_source = marshall-cp.hh libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \ - $(shared_source) $(marshall_c_source) + $(shared_source) libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C) libcc1plugin_la_LIBADD = $(libiberty) libcc1plugin_la_DEPENDENCIES = $(libiberty_dep) @@ -78,7 +77,7 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \ compiler.cc compiler.hh names.cc names.hh $(shared_source) \ - $(marshall_c_source) $(marshall_cxx_source) + $(marshall_cxx_source) libcc1_la_LIBADD = $(libiberty) libcc1_la_DEPENDENCIES = $(libiberty_dep) libcc1_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ diff --git a/libcc1/Makefile.in b/libcc1/Makefile.in index f8f590d71e9b..9d56a8323b05 100644 --- a/libcc1/Makefile.in +++ b/libcc1/Makefile.in @@ -145,11 +145,11 @@ LTLIBRARIES = $(cc1lib_LTLIBRARIES) $(plugin_LTLIBRARIES) am__objects_1 = callbacks.lo connection.lo marshall.lo am__objects_2 = am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo compiler.lo \ - names.lo $(am__objects_1) $(am__objects_2) $(am__objects_2) + names.lo $(am__objects_1) $(am__objects_2) libcc1_la_OBJECTS = $(am_libcc1_la_OBJECTS) @ENABLE_PLUGIN_TRUE@am_libcc1_la_rpath = -rpath $(cc1libdir) am_libcc1plugin_la_OBJECTS = libcc1plugin.lo context.lo \ - $(am__objects_1) $(am__objects_2) + $(am__objects_1) libcc1plugin_la_OBJECTS = $(am_libcc1plugin_la_OBJECTS) @ENABLE_PLUGIN_TRUE@am_libcc1plugin_la_rpath = -rpath $(plugindir) am_libcp1plugin_la_OBJECTS = libcp1plugin.lo context.lo \ @@ -403,11 +403,10 @@ cc1libdir = $(libdir)/$(libsuffix) shared_source = callbacks.cc callbacks.hh connection.cc connection.hh \ marshall.cc marshall.hh rpc.hh status.hh -marshall_c_source = marshall-c.hh marshall_cxx_source = marshall-cp.hh libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \ - $(shared_source) $(marshall_c_source) + $(shared_source) libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C) libcc1plugin_la_LIBADD = $(libiberty) @@ -431,7 +430,7 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \ compiler.cc compiler.hh names.cc names.hh $(shared_source) \ - $(marshall_c_source) $(marshall_cxx_source) + $(marshall_cxx_source) libcc1_la_LIBADD = $(libiberty) libcc1_la_DEPENDENCIES = $(libiberty_dep)
[gcc r15-6423] Fortran: Bugs found in class_transformational_1/2.f90[PR116254/118059].
https://gcc.gnu.org/g:d21efb65d15273d50ca80aea14787efa6245174c commit r15-6423-gd21efb65d15273d50ca80aea14787efa6245174c Author: Paul Thomas Date: Mon Dec 23 15:32:40 2024 + Fortran: Bugs found in class_transformational_1/2.f90[PR116254/118059]. 2024-12-23 Paul Thomas gcc/fortran/ChangeLog PR fortran/116254 * trans-array.cc (gfc_trans_create_temp_array): Make sure that transformational intrinsics of class objects that change rank, most particularly spread, go through the correct code path. Re- factor so that changes to the dtype are done on the temporary before the class data of the result points to it. PR fortran/118059 * trans-expr.cc (arrayfunc_assign_needs_temporary): Character array function expressions assigned to an unlimited polymorphic variable require a temporary. Diff: --- gcc/fortran/trans-array.cc | 47 ++ gcc/fortran/trans-expr.cc | 3 +++ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index e531dd5efb7b..4506c86f166c 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -1632,9 +1632,20 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, tree class_data; tree dtype; gfc_expr *expr1 = fcn_ss ? fcn_ss->info->expr : NULL; + bool rank_changer; + + /* Pick out these transformational functions because they change the rank +or shape of the first argument. This requires that the class type be +changed, the dtype updated and the correct rank used. */ + rank_changer = expr1 && expr1->expr_type == EXPR_FUNCTION +&& expr1->value.function.isym +&& (expr1->value.function.isym->id == GFC_ISYM_RESHAPE +|| expr1->value.function.isym->id == GFC_ISYM_SPREAD +|| expr1->value.function.isym->id == GFC_ISYM_PACK +|| expr1->value.function.isym->id == GFC_ISYM_UNPACK); /* Create a class temporary for the result using the lhs class object. */ - if (class_expr != NULL_TREE) + if (class_expr != NULL_TREE && !rank_changer) { tmp = gfc_create_var (TREE_TYPE (class_expr), "ctmp"); gfc_add_modify (pre, tmp, class_expr); @@ -1672,33 +1683,29 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, elemsize = gfc_evaluate_now (elemsize, pre); } - /* Assign the new descriptor to the _data field. This allows the -vptr _copy to be used for scalarized assignment since the class -temporary can be found from the descriptor. */ class_data = gfc_class_data_get (tmp); - tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR, -TREE_TYPE (desc), desc); - gfc_add_modify (pre, class_data, tmp); - if (expr1 && expr1->expr_type == EXPR_FUNCTION - && expr1->value.function.isym - && (expr1->value.function.isym->id == GFC_ISYM_RESHAPE - || expr1->value.function.isym->id == GFC_ISYM_UNPACK)) + if (rank_changer) { /* Take the dtype from the class expression. */ dtype = gfc_conv_descriptor_dtype (gfc_class_data_get (class_expr)); - tmp = gfc_conv_descriptor_dtype (class_data); + tmp = gfc_conv_descriptor_dtype (desc); gfc_add_modify (pre, tmp, dtype); - /* Transformational functions reshape and reduce can change the rank. */ - if (fcn_ss && fcn_ss->info && fcn_ss->info->class_container) - { - tmp = gfc_conv_descriptor_rank (class_data); - gfc_add_modify (pre, tmp, - build_int_cst (TREE_TYPE (tmp), ss->loop->dimen)); - fcn_ss->info->class_container = NULL_TREE; - } + /* These transformational functions change the rank. */ + tmp = gfc_conv_descriptor_rank (desc); + gfc_add_modify (pre, tmp, + build_int_cst (TREE_TYPE (tmp), ss->loop->dimen)); + fcn_ss->info->class_container = NULL_TREE; } + + /* Assign the new descriptor to the _data field. This allows the +vptr _copy to be used for scalarized assignment since the class +temporary can be found from the descriptor. */ + tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR, +TREE_TYPE (desc), desc); + gfc_add_modify (pre, class_data, tmp); + /* Point desc to the class _data field. */ desc = class_data; } diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 34891afb54ce..9aedecb9780e 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11445,6 +11445,9 @@ arr
[gcc r15-6425] Fortran: Fixup broken build on 32bit after r15-6415 [PR107635]
https://gcc.gnu.org/g:dae506f73bdc03628e23d5e8c566b2e642086b60 commit r15-6425-gdae506f73bdc03628e23d5e8c566b2e642086b60 Author: Andre Vehreschild Date: Mon Dec 23 15:01:30 2024 +0100 Fortran: Fixup broken build on 32bit after r15-6415 [PR107635] gcc/testsuite/ChangeLog: PR fortran/107635 * gfortran.dg/coarray_lib_comm_1.f90: Use less complicated pattern, because all we need is the right count. Diff: --- gcc/testsuite/gfortran.dg/coarray_lib_comm_1.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/gfortran.dg/coarray_lib_comm_1.f90 b/gcc/testsuite/gfortran.dg/coarray_lib_comm_1.f90 index 68aa47ecd325..609f3c10cefa 100644 --- a/gcc/testsuite/gfortran.dg/coarray_lib_comm_1.f90 +++ b/gcc/testsuite/gfortran.dg/coarray_lib_comm_1.f90 @@ -38,6 +38,6 @@ B(1:5) = B(3:7) if (any (A-B /= 0)) STOP 4 end -! { dg-final { scan-tree-dump-times "_gfortran_caf_get_by_ct \\\(caf_token.., 0B, 0B, 1, \\\(unsigned long\\\) atmp.\[0-9\]+.span" 4 "original" } } +! { dg-final { scan-tree-dump-times "_gfortran_caf_get_by_ct" 4 "original" } } ! { dg-final { scan-tree-dump-times "_gfortran_caf_sendget \\\(caf_token.., \\\(integer\\\(kind=\[48\]\\\)\\\) parm.\[0-9\]+.data - \\\(integer\\\(kind=\[48\]\\\)\\\) a, 1, &parm.\[0-9\]+, 0B, caf_token.., \\\(integer\\\(kind=\[48\]\\\)\\\) parm.\[0-9\]+.data - \\\(integer\\\(kind=\[48\]\\\)\\\) a, 1, &parm.\[0-9\]+, 0B, 4, 4, 1, 0B\\\);" 1 "original" } }
[gcc r15-6426] Fortran: fix NULL without MOLD argument to scalar DT pointer dummy [PR118179]
https://gcc.gnu.org/g:f25250e0d5938a81f9f1b37ca873381dcfa26211 commit r15-6426-gf25250e0d5938a81f9f1b37ca873381dcfa26211 Author: Harald Anlauf Date: Mon Dec 23 17:56:46 2024 +0100 Fortran: fix NULL without MOLD argument to scalar DT pointer dummy [PR118179] Commit r15-6408 overlooked the case of passing NULL without MOLD argument to a derived type pointer dummy argument without specified intent. Since it is prohibited to modify the dummy argument, we treat it as if intent(in) were specified and suppress copying back of the pointer address. PR fortran/118179 gcc/fortran/ChangeLog: * trans-expr.cc (conv_null_actual): Suppress copying back of pointer address for unspecified intent. gcc/testsuite/ChangeLog: * gfortran.dg/null_actual_7.f90: Extend testcase to also cover scalar variants with pointer or allocatable dummy with or without specified intent. Diff: --- gcc/fortran/trans-expr.cc | 3 +- gcc/testsuite/gfortran.dg/null_actual_7.f90 | 77 + 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 9aedecb9780e..4b022989e6f4 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6488,7 +6488,8 @@ conv_null_actual (gfc_se * parmse, gfc_expr * e, gfc_symbol * fsym) int dummy_rank; tree tmp = parmse->expr; - if (fsym->attr.allocatable && fsym->attr.intent == INTENT_UNKNOWN) + if ((fsym->attr.allocatable || fsym->attr.pointer) + && fsym->attr.intent == INTENT_UNKNOWN) fsym->attr.intent = INTENT_IN; tmp = gfc_conv_scalar_to_descriptor (parmse, tmp, fsym->attr); dummy_rank = fsym->as ? fsym->as->rank : 0; diff --git a/gcc/testsuite/gfortran.dg/null_actual_7.f90 b/gcc/testsuite/gfortran.dg/null_actual_7.f90 index ba3cd10f21b5..8891a3620ce6 100644 --- a/gcc/testsuite/gfortran.dg/null_actual_7.f90 +++ b/gcc/testsuite/gfortran.dg/null_actual_7.f90 @@ -10,6 +10,8 @@ program null_actual end type t type(t), pointer :: p2(:,:) => NULL() type(t), allocatable :: a2(:,:) + type(t), pointer :: p0 => NULL () + type(t), allocatable :: a0 ! Basic tests passing unallocated allocatable / disassociated pointer stop_base = 0 @@ -27,6 +29,16 @@ program null_actual call chk2_t_p (p2) call opt2_t_a (a2) call opt2_t_p (p2) + ! ... to rank-0 dummy: + stop_base = 60 + call chk0_t_a (a0) + call chk0_t_p (p0) + call opt0_t_a (a0) + call opt0_t_p (p0) + call chk0_t_a_i (a0) + call chk0_t_p_i (p0) + call opt0_t_a_i (a0) + call opt0_t_p_i (p0) ! Test NULL with MOLD argument stop_base = 20 @@ -43,6 +55,16 @@ program null_actual call opt2_t_a (null(a2)) call opt2_t_p (null(p2)) + stop_base = 80 + call chk0_t_a (null(a0)) + call chk0_t_p (null(p0)) + call opt0_t_a (null(a0)) + call opt0_t_p (null(p0)) + call chk0_t_a_i (null(a0)) + call chk0_t_p_i (null(p0)) + call opt0_t_a_i (null(a0)) + call opt0_t_p_i (null(p0)) + ! Test NULL without MOLD argument stop_base = 40 call chk2_t_a (null()) @@ -50,6 +72,16 @@ program null_actual call opt2_t_a (null()) call opt2_t_p (null()) + stop_base = 100 + call chk0_t_a (null()) + call chk0_t_p (null()) + call opt0_t_a (null()) + call opt0_t_p (null()) + call chk0_t_a_i (null()) + call chk0_t_p_i (null()) + call opt0_t_a_i (null()) + call opt0_t_p_i (null()) + contains ! Check assumed-rank dummy: subroutine chk_t_a (x) @@ -120,4 +152,49 @@ contains if (.not. present (x)) stop stop_base + 19 if (associated (x))stop stop_base + 20 end subroutine opt2_t_p + + ! Checks for rank-0 dummy: + subroutine chk0_t_p (x) +type(t), pointer :: x +if (associated (x)) stop stop_base + 1 + end subroutine chk0_t_p + + subroutine chk0_t_p_i (x) +type(t), pointer, intent(in) :: x +if (associated (x)) stop stop_base + 2 + end subroutine chk0_t_p_i + + subroutine opt0_t_p (x) +type(t), pointer, optional :: x +if (.not. present (x)) stop stop_base + 3 +if (associated (x))stop stop_base + 4 + end subroutine opt0_t_p + + subroutine opt0_t_p_i (x) +type(t), pointer, optional, intent(in) :: x +if (.not. present (x)) stop stop_base + 5 +if (associated (x))stop stop_base + 6 + end subroutine opt0_t_p_i + + subroutine chk0_t_a (x) +type(t), allocatable :: x +if (allocated (x)) stop stop_base + 7 + end subroutine chk0_t_a + + subroutine chk0_t_a_i (x) +type(t), allocatable, intent(in) :: x +if (allocated (x)) stop stop_base + 8 + end subroutine chk0_t_a_i + + subroutine opt0_t_a (x) +type(t), allocatable, optional :: x +if (.not. present (x)) stop stop_base + 9 +if (allocated (x)) stop stop_base + 10 + end subroutine opt0_t_a + + subroutine opt0_t_a_i (x) +type(t), allocatabl
[gcc r14-11113] c++: integer overflow during constraint subsumption [PR118069]
https://gcc.gnu.org/g:83646dd4859b8c64b63a5b441c1673a3db5ccdaf commit r14-3-g83646dd4859b8c64b63a5b441c1673a3db5ccdaf Author: Patrick Palka Date: Thu Dec 19 12:00:29 2024 -0500 c++: integer overflow during constraint subsumption [PR118069] For the testcase in the PR we hang during constraint subsumption ultimately because one of the constraints is complex enough that its conjunctive normal form is calculated to have more than 2^31 clauses, which causes the size calculation (through an int) to overflow and so the optimization in subsumes_constraints_nonnull if (dnf_size (lhs) <= cnf_size (rhs)) // iterate over DNF of LHS else // iterate over CNF of RHS incorrectly decides to loop over the CNF (>> billions of clauses) instead of the DNF (thousands of clauses). I haven't verified that the result of cnf_size is correct for the problematic constraint but integer overflow is definitely plausible given that CNF/DNF can be exponentially larger than the original constraint in the worst case. This patch fixes this by using 64-bit saturating arithmetic during these size calculations (via new add/mul_sat_hwi functions) so that overflow is less likely and if it does occur we handle it gracefully. It should be highly unlikely that both the DNF and CNF sizes overflow, and if they do then it doesn't matter which form we select, subsumption will take forever either way. The testcase now compiles in ~3 seconds on my machine after this change. PR c++/118069 gcc/ChangeLog: * hwint.h (add_sat_hwi): New function. (mul_sat_hwi): Likewise. gcc/cp/ChangeLog: * logic.cc (dnf_size_r): Use HOST_WIDE_INT instead of int, and handle overflow gracefully via add_sat_hwi and mul_sat_hwi. (cnf_size_r): Likewise. (dnf_size): Use HOST_WIDE_INT instead of int. (cnf_size): Likewise. Reviewed-by: Jason Merrill (cherry picked from commit 875f14e15d49dce7de501a6357a3d5811b5c36d4) Diff: --- gcc/cp/logic.cc | 68 +++-- gcc/hwint.h | 26 ++ 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/gcc/cp/logic.cc b/gcc/cp/logic.cc index 5466dbe2ec26..d23309a3b19f 100644 --- a/gcc/cp/logic.cc +++ b/gcc/cp/logic.cc @@ -350,7 +350,7 @@ atomic_p (tree t) distributing. In general, a conjunction for which this flag is set is considered a disjunction for the purpose of counting. */ -static std::pair +static std::pair dnf_size_r (tree t) { if (atomic_p (t)) @@ -361,9 +361,9 @@ dnf_size_r (tree t) the results. */ tree lhs = TREE_OPERAND (t, 0); tree rhs = TREE_OPERAND (t, 1); - std::pair p1 = dnf_size_r (lhs); - std::pair p2 = dnf_size_r (rhs); - int n1 = p1.first, n2 = p2.first; + auto p1 = dnf_size_r (lhs); + auto p2 = dnf_size_r (rhs); + HOST_WIDE_INT n1 = p1.first, n2 = p2.first; bool d1 = p1.second, d2 = p2.second; if (disjunction_p (t)) @@ -377,22 +377,24 @@ dnf_size_r (tree t) { if (disjunction_p (rhs) || (conjunction_p (rhs) && d2)) /* Both P and Q are disjunctions. */ - return std::make_pair (n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (n1, n2), d1 | d2); else /* Only LHS is a disjunction. */ - return std::make_pair (1 + n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (1, add_sat_hwi (n1, n2)), + d1 | d2); gcc_unreachable (); } if (conjunction_p (lhs)) { if ((disjunction_p (rhs) && d1) || (conjunction_p (rhs) && d1 && d2)) /* Both P and Q are disjunctions. */ - return std::make_pair (n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (n1, n2), d1 | d2); if (disjunction_p (rhs) || (conjunction_p (rhs) && d1 != d2) || (atomic_p (rhs) && d1)) /* Either LHS or RHS is a disjunction. */ - return std::make_pair (1 + n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (1, add_sat_hwi (n1, n2)), + d1 | d2); else /* Neither LHS nor RHS is a disjunction. */ return std::make_pair (2, false); @@ -401,7 +403,8 @@ dnf_size_r (tree t) { if (disjunction_p (rhs) || (conjunction_p (rhs) && d2)) /* Only RHS is a disjunction. */ - return std::make_pair (1 + n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (1, add_sat_hwi (n1, n2)), + d1 | d2); else /* Neither LHS nor RHS is a disjunction. */ return std::make_pair (2, false); @@ -419,22 +422,22 @@ dnf_size_r (tree t) {
[gcc r15-6429] testsuite/gcc.dg/memcmp-1.c: Cut down a factor of 7 for simulators
https://gcc.gnu.org/g:11090da81e49c37fa5f271b0e0f10291eb0971bc commit r15-6429-g11090da81e49c37fa5f271b0e0f10291eb0971bc Author: Hans-Peter Nilsson Date: Mon Dec 23 01:45:04 2024 +0100 testsuite/gcc.dg/memcmp-1.c: Cut down a factor of 7 for simulators Running tests in parallel on my 4.5y+ old laptop made this test time out: the test itself runs in 9m20s, the timeout being 10 minutes with the 2x factor. That's a bit too close. This commit does to the base test a similar change as was done for gcc.dg/torture/inline-mem-cpy-1.c in commit r14-8188-g6eca0d23b7ea84; or IOW cut it down a factor of 7 (r14-8188 was by a factor of 11). * gcc.dg/memcmp-1.c: Pass -DRUN_FRACTION=7 when testing in a simulator. Diff: --- gcc/testsuite/gcc.dg/memcmp-1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/gcc.dg/memcmp-1.c b/gcc/testsuite/gcc.dg/memcmp-1.c index 13ef5b3380d0..7a7832221560 100644 --- a/gcc/testsuite/gcc.dg/memcmp-1.c +++ b/gcc/testsuite/gcc.dg/memcmp-1.c @@ -2,6 +2,7 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ /* { dg-require-effective-target ptr32plus } */ +/* { dg-additional-options "-DRUN_FRACTION=7" { target simulator } } */ /* { dg-timeout-factor 2 } */ #include
[gcc r15-6430] libcpp: Fix overly large buffer allocation
https://gcc.gnu.org/g:27af1a14f3a0c897f5da3fc36cd2f9fe5ca4b0ed commit r15-6430-g27af1a14f3a0c897f5da3fc36cd2f9fe5ca4b0ed Author: Lewis Hyatt Date: Tue Oct 22 15:23:40 2024 -0400 libcpp: Fix overly large buffer allocation It seems that tokens_buff_new() has always been allocating the virtual location buffer 4 times larger than intended, and now that location_t is 64-bit, it is 8 times larger. Fixed. libcpp/ChangeLog: * macro.cc (tokens_buff_new): Fix length argument to XNEWVEC. Diff: --- libcpp/macro.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libcpp/macro.cc b/libcpp/macro.cc index 0b8eebee0610..66c0bb031456 100644 --- a/libcpp/macro.cc +++ b/libcpp/macro.cc @@ -2579,10 +2579,8 @@ tokens_buff_new (cpp_reader *pfile, size_t len, location_t **virt_locs) { size_t tokens_size = len * sizeof (cpp_token *); - size_t locs_size = len * sizeof (location_t); - if (virt_locs != NULL) -*virt_locs = XNEWVEC (location_t, locs_size); +*virt_locs = XNEWVEC (location_t, len); return _cpp_get_buff (pfile, tokens_size); }
[gcc r15-6427] libgfortran: Fix build for targets with int32_t=long int
https://gcc.gnu.org/g:a5b1f3e14ae6354bd7944dd5dd9c74880c7546db commit r15-6427-ga5b1f3e14ae6354bd7944dd5dd9c74880c7546db Author: Hans-Peter Nilsson Date: Tue Dec 24 00:07:54 2024 +0100 libgfortran: Fix build for targets with int32_t=long int Without this, after r15-6415-g586477d67bf2e3, you'll see, for targets where int32_t is a typedef of long int (beware of artificially broken lines): /x/gcc/libgfortran/caf/single.c: In function '_gfortran_caf_get_by_ct': /x/gcc/libgfortran/caf/single.c:2943:56: error: passing argument 2 of '\ (accessor_hash_table + (sizetype)((unsigned int)getter_index * 12))->ac\ cessor' from incompatible pointer type [-Wincompatible-pointer-types] 2943 | accessor_hash_table[getter_index].accessor (dst_ptr, &free_bu\ ffer, src_ptr, |^~~~\ || |int * /x/gcc/libgfortran/caf/single.c:2943:56: note: expected 'int32_t *' {ak\ a 'long int *'} but argument is of type 'int *' libgfortran: * caf/single.c (_gfortran_caf_get_by_ct): Correct type of free_buffer to int32_t. Diff: --- libgfortran/caf/single.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c index f5414ff1f7ef..23ad44e1c162 100644 --- a/libgfortran/caf/single.c +++ b/libgfortran/caf/single.c @@ -2927,7 +2927,7 @@ _gfortran_caf_get_by_ct ( { caf_single_token_t single_token = TOKEN (token); void *src_ptr = opt_src_desc ? (void *) opt_src_desc : single_token->memptr; - int free_buffer; + int32_t free_buffer; void *dst_ptr = opt_dst_desc ? (void *)opt_dst_desc : dst_data; void *old_dst_data_ptr = NULL;