[gcc r15-1879] libstdc++: Fix memchr path in std::ranges::find for non-common range [PR115799]
https://gcc.gnu.org/g:762ee55d369a3257997092ef7853cf9dd4d5cc4f commit r15-1879-g762ee55d369a3257997092ef7853cf9dd4d5cc4f Author: Jonathan Wakely Date: Fri Jul 5 18:58:00 2024 +0100 libstdc++: Fix memchr path in std::ranges::find for non-common range [PR115799] The memchr optimization introduced in r15-1857 needs to advance the start iterator instead of returning the sentinel. libstdc++-v3/ChangeLog: PR libstdc++/115799 * include/bits/ranges_util.h (__find_fn): Return iterator instead of sentinel. * testsuite/25_algorithms/find/constrained.cc: Check non-common contiguous sized range of char. Diff: --- libstdc++-v3/include/bits/ranges_util.h | 19 +-- .../testsuite/25_algorithms/find/constrained.cc | 10 ++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index 186acae4f70..a1f42875b11 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -501,17 +501,16 @@ namespace ranges if constexpr (contiguous_iterator<_Iter>) if (!is_constant_evaluated()) { - if (static_cast>(__value) != __value) - return __last; - + using _Vt = iter_value_t<_Iter>; auto __n = __last - __first; - if (__n > 0) - { - const int __ival = static_cast(__value); - const void* __p0 = std::to_address(__first); - if (auto __p1 = __builtin_memchr(__p0, __ival, __n)) - __n = (const char*)__p1 - (const char*)__p0; - } + if (static_cast<_Vt>(__value) == __value) [[likely]] + if (__n > 0) + { + const int __ival = static_cast(__value); + const void* __p0 = std::to_address(__first); + if (auto __p1 = __builtin_memchr(__p0, __ival, __n)) + __n = (const char*)__p1 - (const char*)__p0; + } return __first + __n; } diff --git a/libstdc++-v3/testsuite/25_algorithms/find/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/find/constrained.cc index e94751fcf89..7357a40bcc4 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/constrained.cc @@ -66,9 +66,19 @@ test02() static_assert(ranges::find(y, 5, &Y::j) == y+3); } +void +test_pr115799() +{ + const char str[3] = { 'a', 'b', 'c' }; + __gnu_test::test_contiguous_sized_range r(str); + VERIFY(std::ranges::find(r, 'a') == std::ranges::begin(r)); + VERIFY(std::ranges::find(r, 'a'+255) == std::ranges::end(r)); +} + int main() { test01(); test02(); + test_pr115799(); }
[gcc r15-1880] libstdc++: Fix std::find for non-contiguous iterators [PR115799]
https://gcc.gnu.org/g:ce34fcc572a0dceebcffef76e98064546feebb38 commit r15-1880-gce34fcc572a0dceebcffef76e98064546feebb38 Author: Jonathan Wakely Date: Sat Jul 6 21:34:29 2024 +0100 libstdc++: Fix std::find for non-contiguous iterators [PR115799] The r15-1857 change didn't correctly restrict the new optimization to contiguous iterators. libstdc++-v3/ChangeLog: PR libstdc++/115799 * include/bits/stl_algo.h (find): Use 'if constexpr' so that memchr optimization is a discarded statement for non-contiguous iterators. * testsuite/25_algorithms/find/bytes.cc: Check with input iterators. Diff: --- libstdc++-v3/include/bits/stl_algo.h | 44 ++ libstdc++-v3/testsuite/25_algorithms/find/bytes.cc | 7 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 45c3b591326..d250b2e04d4 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -3849,32 +3849,28 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO #if __cpp_if_constexpr && __glibcxx_type_trait_variable_templates using _ValT = typename iterator_traits<_InputIterator>::value_type; if constexpr (__can_use_memchr_for_find<_ValT, _Tp>) - { - // If converting the value to the 1-byte value_type alters its value, - // then it would not be found by std::find using equality comparison. - // We need to check this here, because otherwise something like - // memchr("a", 'a'+256, 1) would give a false positive match. - if (!(static_cast<_ValT>(__val) == __val)) - return __last; - else if (!__is_constant_evaluated()) - { - const void* __p0 = nullptr; - if constexpr (is_pointer_v) - __p0 = std::__niter_base(__first); + if constexpr (is_pointer_v #if __cpp_lib_concepts - else if constexpr (contiguous_iterator<_InputIterator>) - __p0 = std::to_address(__first); + || contiguous_iterator<_InputIterator> #endif - if (__p0) - { - const int __ival = static_cast(__val); - if (auto __n = std::distance(__first, __last); __n > 0) - if (auto __p1 = __builtin_memchr(__p0, __ival, __n)) - return __first + ((const char*)__p1 - (const char*)__p0); - return __last; - } - } - } +) + { + // If conversion to the 1-byte value_type alters the value, + // it would not be found by std::find using equality comparison. + // We need to check this here, because otherwise something like + // memchr("a", 'a'+256, 1) would give a false positive match. + if (!(static_cast<_ValT>(__val) == __val)) + return __last; + else if (!__is_constant_evaluated()) + { + const void* __p0 = std::__to_address(__first); + const int __ival = static_cast(__val); + if (auto __n = std::distance(__first, __last); __n > 0) + if (auto __p1 = __builtin_memchr(__p0, __ival, __n)) + return __first + ((const char*)__p1 - (const char*)__p0); + return __last; + } + } #endif return std::__find_if(__first, __last, diff --git a/libstdc++-v3/testsuite/25_algorithms/find/bytes.cc b/libstdc++-v3/testsuite/25_algorithms/find/bytes.cc index f4ac5d4018d..e1d6c01ab21 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/bytes.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/bytes.cc @@ -3,6 +3,7 @@ #include #include // std::byte #include +#include // PR libstdc++/88545 made std::find use memchr as an optimization. // This test verifies that it didn't change any semantics. @@ -113,6 +114,12 @@ test_non_characters() #endif } +void +test_pr115799c2(__gnu_test::input_iterator_wrapper i) +{ + (void) std::find(i, i, 'a'); +} + int main() { test_char();
[gcc r15-1881] ada: Make the names of uninstalled cross-gnattools consistent across builds
https://gcc.gnu.org/g:d364c4ced8823bc41fda84f182e1d64e7870549e commit r15-1881-gd364c4ced8823bc41fda84f182e1d64e7870549e Author: Maciej W. Rozycki Date: Sun Jul 7 15:04:51 2024 +0100 ada: Make the names of uninstalled cross-gnattools consistent across builds We suffer from an inconsistency in the names of uninstalled gnattools executables in cross-compiler configurations. The cause is a recipe we have: ada.all.cross: for tool in $(ADA_TOOLS) ; do \ if [ -f $$tool$(exeext) ] ; \ then \ $(MV) $$tool$(exeext) $$tool-cross$(exeext); \ fi; \ done the intent of which is to give the names of gnattools executables the '-cross' suffix, consistently with the compiler drivers: 'gcc-cross', 'g++-cross', etc. A problem with the recipe is that this 'make' target is called too early in the build process, before gnattools have been made. Consequently no renames happen and owing to that they are conditional on the presence of the individual executables the recipe succeeds doing nothing. However if a target is requested later on such as 'make pdf' that does not cause gnattools executables to be rebuilt, then 'ada.all.cross' does succeed in renaming the executables already present in the build tree. Then if the 'gnat' testsuite is run later on which expects non-suffixed 'gnatmake' executable, it does not find the 'gnatmake-cross' executable in the build tree and may either catastrophically fail or incorrectly use a system-installed copy of 'gnatmake'. Of course if a target is requested such as `make all' that does cause gnattools executables to be rebuilt, then both suffixed and non-suffixed uninstalled executables result. Fix the problem by moving the renaming of gnattools to a separate 'make' recipe, pasted into a new 'gnattools-cross-mv' target and the existing legacy 'cross-gnattools' target. Then invoke the new target explicitly from the 'gnattools-cross' recipe in gnattools/. Update the test harness accordingly, so that suffixed gnattools are used in cross-compilation testsuite runs. gcc/ada/ * gcc-interface/Make-lang.in (ada.all.cross): Move recipe to... (GNATTOOLS_CROSS_MV): ... this new variable. (cross-gnattools): Paste it here. (gnattools-cross-mv): New target. gnattools/ * Makefile.in (gnattools-cross): Also build 'gnattools-cross-mv' in GCC_DIR. gcc/testsuite/ * lib/gnat.exp (local_find_gnatmake, find_gnatclean): Use '-cross' suffix where testing a cross-compiler. Diff: --- gcc/ada/gcc-interface/Make-lang.in | 19 --- gcc/testsuite/lib/gnat.exp | 22 ++ gnattools/Makefile.in | 1 + 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index ebf1f70de78..b2841104651 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -780,6 +780,7 @@ regnattools: cross-gnattools: force $(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools1-re $(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools2 + $(GNATTOOLS_CROSS_MV) canadian-gnattools: force $(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools1-re @@ -795,19 +796,23 @@ gnatlib gnatlib-sjlj gnatlib-zcx gnatlib-shared: force FORCE_DEBUG_ADAFLAGS="$(FORCE_DEBUG_ADAFLAGS)" \ $@ +gnattools-cross-mv: + $(GNATTOOLS_CROSS_MV) + +GNATTOOLS_CROSS_MV=\ + for tool in $(ADA_TOOLS) ; do \ +if [ -f $$tool$(exeext) ] ; \ +then \ + $(MV) $$tool$(exeext) $$tool-cross$(exeext); \ +fi; \ + done + # use only for native compiler gnatlib_and_tools: gnatlib gnattools # Build hooks: ada.all.cross: - for tool in $(ADA_TOOLS) ; do \ - if [ -f $$tool$(exeext) ] ; \ - then \ - $(MV) $$tool$(exeext) $$tool-cross$(exeext); \ - fi; \ - done - ada.start.encap: ada.rest.encap: ada.man: diff --git a/gcc/testsuite/lib/gnat.exp b/gcc/testsuite/lib/gnat.exp index 471f83e9844..c278cb7f044 100644 --- a/gcc/testsuite/lib/gnat.exp +++ b/gcc/testsuite/lib/gnat.exp @@ -199,12 +199,19 @@ proc prune_gnat_output { text } { # which prevent multilib from working, so define a new one. proc local_find_gnatmake {} { +global target_triplet global tool_root_dir +global host_triplet if ![is_remote host] { -set file [lookfor_file $tool_root_dir gnatmake] + if { "$host_triplet" == "$target_triplet" } { + set gnatmake gnatmake + } else { + set gnatmake gnatmake-cross + } + set file [lookfor_file $tool_root_dir $gnatmake] if { $file == "" } { - s
[gcc r15-1882] c++: Simplify uses of LAMBDA_EXPR_EXTRA_SCOPE
https://gcc.gnu.org/g:24cb586cafd40f8fbea68641f97e3431ea76c1b8 commit r15-1882-g24cb586cafd40f8fbea68641f97e3431ea76c1b8 Author: Nathaniel Shead Date: Sat Jun 15 22:47:07 2024 +1000 c++: Simplify uses of LAMBDA_EXPR_EXTRA_SCOPE I noticed there already exists a getter to get the scope of a lambda from its type directly rather than needing to go via CLASSTYPE_LAMBDA_EXPR, we may as well use it. gcc/cp/ChangeLog: * module.cc (trees_out::get_merge_kind): Use LAMBDA_TYPE_EXTRA_SCOPE instead of LAMBDA_EXPR_EXTRA_SCOPE. (trees_out::key_mergeable): Likewise. Signed-off-by: Nathaniel Shead Diff: --- gcc/cp/module.cc | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index dc5d046f04d..da180244e03 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -10686,9 +10686,7 @@ trees_out::get_merge_kind (tree decl, depset *dep) g++.dg/modules/lambda-6_a.C. */ if (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl)) && LAMBDA_TYPE_P (TREE_TYPE (decl))) - if (tree scope - = LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR -(TREE_TYPE (decl + if (tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl))) { /* Lambdas attached to fields are keyed to its class. */ if (TREE_CODE (scope) == FIELD_DECL) @@ -10993,8 +10991,7 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, case MK_keyed: { gcc_checking_assert (LAMBDA_TYPE_P (TREE_TYPE (inner))); - tree scope = LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR - (TREE_TYPE (inner))); + tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (inner)); gcc_checking_assert (TREE_CODE (scope) == VAR_DECL || TREE_CODE (scope) == FIELD_DECL || TREE_CODE (scope) == PARM_DECL
[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] RISC-V: Fix asm check failure for truncated after SAT_SUB
https://gcc.gnu.org/g:b810058b87e322cf66e0130f6cfb04f08764b701 commit b810058b87e322cf66e0130f6cfb04f08764b701 Author: Pan Li Date: Wed Jul 3 13:17:16 2024 +0800 RISC-V: Fix asm check failure for truncated after SAT_SUB It seems that the asm check is incorrect for truncated after SAT_SUB, we should take the vx check for vssubu instead of vv check. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-1.c: Update vssubu check from vv to vx. * gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-2.c: Ditto. * gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-3.c: Ditto. Signed-off-by: Pan Li (cherry picked from commit ab3e3d2f0564c2eb0640de3f4d0a50e1fcc8c318) Diff: --- .../gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-1.c | 2 +- .../gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-2.c | 2 +- .../gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-3.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-1.c index dd9e3999a29..1e380657d74 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-1.c @@ -11,7 +11,7 @@ ** vsetvli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*e16,\s*m1,\s*ta,\s*ma ** ... ** vle16\.v\s+v[0-9]+,\s*0\([atx][0-9]+\) -** vssubu\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+ +** vssubu\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+ ** vsetvli\s+zero,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma ** vncvt\.x\.x\.w\s+v[0-9]+,\s*v[0-9]+ ** ... diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-2.c index 738d1465a01..d7b8931f0ec 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-2.c @@ -11,7 +11,7 @@ ** vsetvli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*e32,\s*m1,\s*ta,\s*ma ** ... ** vle32\.v\s+v[0-9]+,\s*0\([atx][0-9]+\) -** vssubu\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+ +** vssubu\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+ ** vsetvli\s+zero,\s*zero,\s*e16,\s*mf2,\s*ta,\s*ma ** vncvt\.x\.x\.w\s+v[0-9]+,\s*v[0-9]+ ** ... diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-3.c index b008b21cf0c..edf42a1f776 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vec_sat_u_sub_trunc-3.c @@ -11,7 +11,7 @@ ** vsetvli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*e64,\s*m1,\s*ta,\s*ma ** ... ** vle64\.v\s+v[0-9]+,\s*0\([atx][0-9]+\) -** vssubu\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+ +** vssubu\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+ ** vsetvli\s+zero,\s*zero,\s*e32,\s*mf2,\s*ta,\s*ma ** vncvt\.x\.x\.w\s+v[0-9]+,\s*v[0-9]+ ** ...
[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] RISC-V: Bugfix vfmv insn honor zvfhmin for FP16 SEW [PR115763]
https://gcc.gnu.org/g:7013a4562f74ba14cd14f4e57cc318225752c762 commit 7013a4562f74ba14cd14f4e57cc318225752c762 Author: Pan Li Date: Wed Jul 3 22:06:48 2024 +0800 RISC-V: Bugfix vfmv insn honor zvfhmin for FP16 SEW [PR115763] According to the ISA, the zvfhmin sub extension should only contain convertion insn. Thus, the vfmv insn acts on FP16 should not be present when only the zvfhmin option is given. This patch would like to fix it by split the pred_broadcast define_insn into zvfhmin and zvfh part. Given below example: void test (_Float16 *dest, _Float16 bias) { dest[0] = bias; dest[1] = bias; } when compile with -march=rv64gcv_zfh_zvfhmin Before this patch: test: vsetivlizero,2,e16,mf4,ta,ma vfmv.v.fv1,fa0 // should not leverage vfmv for zvfhmin vse16.v v1,0(a0) ret After this patch: test: addi sp,sp,-16 fsh fa0,14(sp) addi a5,sp,14 vsetivli zero,2,e16,mf4,ta,ma vlse16.v v1,0(a5),zero vse16.v v1,0(a0) addi sp,sp,16 jr ra PR target/115763 gcc/ChangeLog: * config/riscv/vector.md (*pred_broadcast): Split into zvfh and zvfhmin part. (*pred_broadcast_zvfh): New define_insn for zvfh part. (*pred_broadcast_zvfhmin): Ditto but for zvfhmin. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/scalar_move-5.c: Adjust asm check. * gcc.target/riscv/rvv/base/scalar_move-6.c: Ditto. * gcc.target/riscv/rvv/base/scalar_move-7.c: Ditto. * gcc.target/riscv/rvv/base/scalar_move-8.c: Ditto. * gcc.target/riscv/rvv/base/pr115763-1.c: New test. * gcc.target/riscv/rvv/base/pr115763-2.c: New test. Signed-off-by: Pan Li (cherry picked from commit de9254e224eb3d89303cb9b3ba50b4c479c55f7c) Diff: --- gcc/config/riscv/vector.md | 49 +++--- .../gcc.target/riscv/rvv/base/pr115763-1.c | 9 .../gcc.target/riscv/rvv/base/pr115763-2.c | 10 + .../gcc.target/riscv/rvv/base/scalar_move-5.c | 4 +- .../gcc.target/riscv/rvv/base/scalar_move-6.c | 6 +-- .../gcc.target/riscv/rvv/base/scalar_move-7.c | 6 +-- .../gcc.target/riscv/rvv/base/scalar_move-8.c | 6 +-- 7 files changed, 64 insertions(+), 26 deletions(-) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index fe18ee5b5f7..d9474262d54 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -2080,31 +2080,50 @@ [(set_attr "type" "vimov,vimov,vlds,vlds,vlds,vlds,vimovxv,vimovxv") (set_attr "mode" "")]) -(define_insn "*pred_broadcast" - [(set (match_operand:V_VLSF_ZVFHMIN 0 "register_operand" "=vr, vr, vr, vr, vr, vr, vr, vr") - (if_then_else:V_VLSF_ZVFHMIN +(define_insn "*pred_broadcast_zvfh" + [(set (match_operand:V_VLSF0 "register_operand" "=vr, vr, vr, vr") + (if_then_else:V_VLSF (unspec: - [(match_operand: 1 "vector_broadcast_mask_operand" "Wc1,Wc1, vm, vm,Wc1,Wc1,Wb1,Wb1") -(match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK, rK, rK, rK") -(match_operand 5 "const_int_operand" " i, i, i, i, i, i, i, i") -(match_operand 6 "const_int_operand" " i, i, i, i, i, i, i, i") -(match_operand 7 "const_int_operand" " i, i, i, i, i, i, i, i") + [(match_operand: 1 "vector_broadcast_mask_operand" "Wc1, Wc1, Wb1, Wb1") +(match_operand 4 "vector_length_operand" " rK, rK, rK, rK") +(match_operand 5 "const_int_operand" " i, i, i, i") +(match_operand 6 "const_int_operand" " i, i, i, i") +(match_operand 7 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (vec_duplicate:V_VLSF_ZVFHMIN - (match_operand: 3 "direct_broadcast_operand" " f, f,Wdm,Wdm,Wdm,Wdm, f, f")) - (match_operand:V_VLSF_ZVFHMIN 2 "vector_merge_operand""vu, 0, vu, 0, vu, 0, vu, 0")))] + (vec_duplicate:V_VLSF + (match_operand: 3 "direct_broadcast_operand" " f, f, f, f")) + (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" "@ vfmv.v.f\t%0,%3 vfmv.v.f\t%0,%3 + vfmv.s.f\t%0,%3 + vfmv.s.f\t%0,%3" + [(set_attr "type" "vfmov,vfmov,vfmovfv,vfmovfv") + (set_attr "mode" "")]) + +(define_insn "*pred_broadcast_zvfhmin" + [(set (match_operand:V_VLSF_ZVFHMIN 0 "register_operand" "=vr, vr, vr, vr") + (if_then_else:V_VLSF_ZV
[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] RISC-V: Add support for Zabha extension
https://gcc.gnu.org/g:de6abc8953cdba01e27be7427afe7834a68c583d commit de6abc8953cdba01e27be7427afe7834a68c583d Author: Gianluca Guida Date: Tue Jul 2 18:05:14 2024 -0700 RISC-V: Add support for Zabha extension The Zabha extension adds support for subword Zaamo ops. Extension: https://github.com/riscv/riscv-zabha.git Ratification: https://jira.riscv.org/browse/RVS-1685 gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_subset_list::to_string): Skip zabha when not supported by the assembler. * config.in: Regenerate. * config/riscv/arch-canonicalize: Make zabha imply zaamo. * config/riscv/iterators.md (amobh): Add iterator for amo byte/halfword. * config/riscv/riscv.opt: Add zabha. * config/riscv/sync.md (atomic_): Add subword atomic op pattern. (zabha_atomic_fetch_): Add subword atomic_fetch op pattern. (lrsc_atomic_fetch_): Prefer zabha over lrsc for subword atomic ops. (zabha_atomic_exchange): Add subword atomic exchange pattern. (lrsc_atomic_exchange): Prefer zabha over lrsc for subword atomic exchange ops. * configure: Regenerate. * configure.ac: Add zabha assembler check. * doc/sourcebuild.texi: Add zabha documentation. gcc/testsuite/ChangeLog: * lib/target-supports.exp: Add zabha testsuite infra support. * gcc.target/riscv/amo/inline-atomics-1.c: Remove zabha to continue to test the lr/sc subword patterns. * gcc.target/riscv/amo/inline-atomics-2.c: Ditto. * gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-acq-rel.c: Ditto. * gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-acquire.c: Ditto. * gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-relaxed.c: Ditto. * gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-release.c: Ditto. * gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-seq-cst.c: Ditto. * gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-acq-rel.c: Ditto. * gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-acquire.c: Ditto. * gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-relaxed.c: Ditto. * gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-release.c: Ditto. * gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-seq-cst.c: Ditto. * gcc.target/riscv/amo/zabha-all-amo-ops-char-run.c: New test. * gcc.target/riscv/amo/zabha-all-amo-ops-short-run.c: New test. * gcc.target/riscv/amo/zabha-rvwmo-all-amo-ops-char.c: New test. * gcc.target/riscv/amo/zabha-rvwmo-all-amo-ops-short.c: New test. * gcc.target/riscv/amo/zabha-rvwmo-amo-add-char.c: New test. * gcc.target/riscv/amo/zabha-rvwmo-amo-add-short.c: New test. * gcc.target/riscv/amo/zabha-ztso-amo-add-char.c: New test. * gcc.target/riscv/amo/zabha-ztso-amo-add-short.c: New test. Co-Authored-By: Patrick O'Neill Signed-Off-By: Gianluca Guida Tested-by: Andrea Parri (cherry picked from commit 7b2b2e3d660edc8ef3a8cfbdfc2b0fd499459601) Diff: --- gcc/common/config/riscv/riscv-common.cc| 12 gcc/config.in | 6 ++ gcc/config/riscv/arch-canonicalize | 3 + gcc/config/riscv/iterators.md | 3 + gcc/config/riscv/riscv.opt | 2 + gcc/config/riscv/sync.md | 81 +- gcc/configure | 31 + gcc/configure.ac | 5 ++ gcc/doc/sourcebuild.texi | 12 +++- .../gcc.target/riscv/amo/inline-atomics-1.c| 1 + .../gcc.target/riscv/amo/inline-atomics-2.c| 1 + .../riscv/amo/zabha-all-amo-ops-char-run.c | 5 ++ .../riscv/amo/zabha-all-amo-ops-short-run.c| 5 ++ .../riscv/amo/zabha-rvwmo-all-amo-ops-char.c | 23 ++ .../riscv/amo/zabha-rvwmo-all-amo-ops-short.c | 23 ++ .../riscv/amo/zabha-rvwmo-amo-add-char.c | 57 +++ .../riscv/amo/zabha-rvwmo-amo-add-short.c | 57 +++ .../gcc.target/riscv/amo/zabha-ztso-amo-add-char.c | 57 +++ .../riscv/amo/zabha-ztso-amo-add-short.c | 57 +++ .../zalrsc-rvwmo-subword-amo-add-char-acq-rel.c| 1 + .../zalrsc-rvwmo-subword-amo-add-char-acquire.c| 1 + .../zalrsc-rvwmo-subword-amo-add-char-relaxed.c| 1 + .../zalrsc-rvwmo-subword-amo-add-char-release.c| 1 + .../zalrsc-rvwmo-subword-amo-add-char-seq-cst.c| 1 + .../amo/zalrsc-ztso-subword-amo-add-char-acq-rel.c | 1 + .../
[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] RISC-V: Describe -march behavior for dependent extensions
https://gcc.gnu.org/g:316bda6c8e290853cfca060f38b2f0f4281d65f9 commit 316bda6c8e290853cfca060f38b2f0f4281d65f9 Author: Palmer Dabbelt Date: Tue Jul 2 18:20:39 2024 -0700 RISC-V: Describe -march behavior for dependent extensions gcc/ChangeLog: * doc/invoke.texi: Describe -march behavior for dependent extensions on RISC-V. (cherry picked from commit 70f6bc39c4b0e147a816ad1dad583f944616c367) Diff: --- gcc/doc/invoke.texi | 4 1 file changed, 4 insertions(+) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 023ee575b86..9486758d463 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -30927,6 +30927,10 @@ If both @option{-march} and @option{-mcpu=} are not specified, the default for this argument is system dependent, users who want a specific architecture extensions should specify one explicitly. +When the RISC-V specifications define an extension as depending on other +extensions, GCC will implicitly add the dependent extensions to the enabled +extension set if they weren't added explicitly. + @opindex mcpu @item -mcpu=@var{processor-string} Use architecture of and optimize the output for the given processor, specified
[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] [committed][RISC-V] Fix test expectations after recent late-combine changes
https://gcc.gnu.org/g:a2b380b973fc48b5b2f8c7ebff775ab5aab5a5cb commit a2b380b973fc48b5b2f8c7ebff775ab5aab5a5cb Author: Jeff Law Date: Thu Jul 4 09:25:20 2024 -0600 [committed][RISC-V] Fix test expectations after recent late-combine changes With the recent DCE related adjustment to late-combine the rvv/base/vcreate.c test no longer has those undesirable vmvNr statements. It's a bit unclear why this wasn't written as a scan-assembler-not and xfailed given the comment says we don't want to see vmvNr insructions. I must have missed that during review. This patch adjusts the test to expect no vmvNr statements and if they're ever re-introduced, we'll get a nice unexpected failure. gcc/testsuite * gcc.target/riscv/rvv/base/vcreate.c: Update expected output. (cherry picked from commit b611f3969249967d7f098c6adfcf5f701192a2d0) Diff: --- gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c index 01006de7c81..1c7c154637e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vcreate.c @@ -256,6 +256,6 @@ test_vcreate_v_i64m2x4 (vint64m2_t v0, vint64m2_t v1, vint64m2_t v2, } // Ideally with O3, should find 0 instances of any vmvnr.v PR113913 -/* { dg-final { scan-assembler-times {vmv1r.v\s+v[0-9]+,\s*v[0-9]+} 72 } } */ -/* { dg-final { scan-assembler-times {vmv2r.v\s+v[0-9]+,\s*v[0-9]+} 36 } } */ -/* { dg-final { scan-assembler-times {vmv4r.v\s+v[0-9]+,\s*v[0-9]+} 16 } } */ +/* { dg-final { scan-assembler-not {vmv1r.v\s+v[0-9]+,\s*v[0-9]+} } } */ +/* { dg-final { scan-assembler-not {vmv2r.v\s+v[0-9]+,\s*v[0-9]+} } } */ +/* { dg-final { scan-assembler-not {vmv4r.v\s+v[0-9]+,\s*v[0-9]+} } } */
[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] RISC-V: Use tu policy for first-element vec_set [PR115725].
https://gcc.gnu.org/g:30267a9ae0d49265e80d7d6748cd0851eb4fe1ad commit 30267a9ae0d49265e80d7d6748cd0851eb4fe1ad Author: Robin Dapp Date: Mon Jul 1 13:37:17 2024 +0200 RISC-V: Use tu policy for first-element vec_set [PR115725]. This patch changes the tail policy for vmv.s.x from ta to tu. By default the bug does not show up with qemu because qemu's current vmv.s.x implementation always uses the tail-undisturbed policy. With a local qemu version that overwrites the tail with ones when the tail-agnostic policy is specified, the bug shows. gcc/ChangeLog: * config/riscv/autovec.md: Add TU policy. * config/riscv/riscv-protos.h (enum insn_type): Define SCALAR_MOVE_MERGED_OP_TU. gcc/testsuite/ChangeLog: PR target/115725 * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c: Adjust test expectation. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-4.c: Ditto. (cherry picked from commit acc3b703c05debc6276451f9daae5d0ffc797eac) Diff: --- gcc/config/riscv/autovec.md | 3 ++- gcc/config/riscv/riscv-protos.h | 4 .../gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c | 12 .../gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c | 12 .../gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c | 12 .../gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-4.c | 12 6 files changed, 22 insertions(+), 33 deletions(-) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 66d70f678a6..0fb6316a2cf 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1341,7 +1341,8 @@ { rtx ops[] = {operands[0], operands[0], operands[1]}; riscv_vector::emit_nonvlmax_insn (code_for_pred_broadcast (mode), - riscv_vector::SCALAR_MOVE_MERGED_OP, ops, CONST1_RTX (Pmode)); + riscv_vector::SCALAR_MOVE_MERGED_OP_TU, + ops, CONST1_RTX (Pmode)); } else { diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index a8b76173fa0..abf6e34b5cc 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -524,6 +524,10 @@ enum insn_type : unsigned int SCALAR_MOVE_MERGED_OP = HAS_DEST_P | HAS_MASK_P | USE_ONE_TRUE_MASK_P | HAS_MERGE_P | TDEFAULT_POLICY_P | MDEFAULT_POLICY_P | UNARY_OP_P, + + SCALAR_MOVE_MERGED_OP_TU = HAS_DEST_P | HAS_MASK_P | USE_ONE_TRUE_MASK_P + | HAS_MERGE_P | TU_POLICY_P | MDEFAULT_POLICY_P + | UNARY_OP_P, }; enum vlmul_type diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c index ecb160933d6..99b0f625c83 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c @@ -64,14 +64,10 @@ typedef double vnx2df __attribute__((vector_size (16))); TEST_ALL1 (VEC_SET) TEST_ALL_VAR1 (VEC_SET_VAR1) -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m1,\s*tu,\s*ma} 5 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m1,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m1,\s*tu,\s*ma} 6 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m1,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m1,\s*tu,\s*ma} 6 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m1,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m1,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m1,\s*tu,\s*ma} 6 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m1,\s*tu,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m1,\s*tu,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m1,\s*tu,\s*ma} 6 } } */ /* { dg-final { scan-assembler-times {\tvmv.v.x} 13 } } */ /* { dg-final { scan-assembler-times {\tvfmv.v.f} 8 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c index 194abff77cc..64a40308eb1 100644 --- a/gcc
[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] RISC-V: fix internal error on global variable-length array
https://gcc.gnu.org/g:a3d53feb6ab6b71a11e220a800d8f5a013e7590c commit a3d53feb6ab6b71a11e220a800d8f5a013e7590c Author: Eric Botcazou Date: Sat Jul 6 11:56:19 2024 +0200 RISC-V: fix internal error on global variable-length array This is an ICE in the RISC-V back-end calling tree_to_uhwi on the DECL_SIZE of a global variable-length array. gcc/ PR target/115591 * config/riscv/riscv.cc (riscv_valid_lo_sum_p): Add missing test on tree_fits_uhwi_p before calling tree_to_uhwi. gcc/testsuite/ * gnat.dg/array41.ads, gnat.dg/array41.adb: New test. (cherry picked from commit 8bc5561c43b195e1638e5acace8b41b3f7512be3) Diff: --- gcc/config/riscv/riscv.cc | 4 +++- gcc/testsuite/gnat.dg/array41.adb | 37 + gcc/testsuite/gnat.dg/array41.ads | 5 + 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index cca7ffde33a..4acd643fd8d 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1702,7 +1702,9 @@ riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode, align = (SYMBOL_REF_DECL (x) ? DECL_ALIGN (SYMBOL_REF_DECL (x)) : 1); - size = (SYMBOL_REF_DECL (x) && DECL_SIZE (SYMBOL_REF_DECL (x)) + size = (SYMBOL_REF_DECL (x) + && DECL_SIZE (SYMBOL_REF_DECL (x)) + && tree_fits_uhwi_p (DECL_SIZE (SYMBOL_REF_DECL (x))) ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x))) : 2*BITS_PER_WORD); } diff --git a/gcc/testsuite/gnat.dg/array41.adb b/gcc/testsuite/gnat.dg/array41.adb new file mode 100644 index 000..d0d5a69eeaf --- /dev/null +++ b/gcc/testsuite/gnat.dg/array41.adb @@ -0,0 +1,37 @@ +-- { dg-do compile } + +with System.Storage_Elements; + +package body Array41 is + + procedure Program_Initialization + with + Export, + Convention => Ada, + External_Name => "program_initialization"; + + procedure Program_Initialization is + use System.Storage_Elements; + + Sdata : Storage_Element +with Import, Convention => Asm, External_Name => "_sdata"; + Edata : Storage_Element +with Import, Convention => Asm, External_Name => "_edata"; + + Data_Size : constant Storage_Offset := Edata'Address - Sdata'Address; + + -- Index from 1 so as to avoid subtracting 1 from the size + Data_In_Flash : constant Storage_Array (1 .. Data_Size) +with Import, Convention => Asm, External_Name => "_sidata"; + + Data_In_Sram : Storage_Array (1 .. Data_Size) +with Volatile, Import, Convention => Asm, External_Name => "_sdata"; + + begin + -- Copy rw data from flash to ram + for J in Data_In_Flash'Range loop + Data_In_Sram (J) := Data_In_Flash (J); + end loop; + end Program_Initialization; + +end Array41; diff --git a/gcc/testsuite/gnat.dg/array41.ads b/gcc/testsuite/gnat.dg/array41.ads new file mode 100644 index 000..50cde3cd819 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array41.ads @@ -0,0 +1,5 @@ +package Array41 is + + pragma Elaborate_Body; + +end Array41;
[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] [to-be-committed][v3][RISC-V] Handle bit manipulation of SImode values
https://gcc.gnu.org/g:576d8c0e57bc6894ab1215bfd45406b8adcfd2dd commit 576d8c0e57bc6894ab1215bfd45406b8adcfd2dd Author: Jeff Law Date: Sat Jul 6 12:57:59 2024 -0600 [to-be-committed][v3][RISC-V] Handle bit manipulation of SImode values Last patch in this round of bitmanip work... At least I think I'm going to pause here and switch gears to other projects that need attention 🙂 This patch introduces the ability to generate bitmanip instructions for rv64 when operating on SI objects when we know something about the range of the bit position (due to masking of the position). I've got note that the (7-pos % 8) bit position form was discovered by RAU in 500.perl. I took that and expanded it to the simple (pos & mask) form as well as covering bset, binv and bclr. As far as the implementation is concerned This turns the recently added define_splits into define_insn_and_split constructs. This allows combine to "see" enough RTL to realize a sign extension is unnecessary. Otherwise we get undesirable sign extensions for the new testcases. Second it adds new patterns for the logical operations. Two patterns for IOR/XOR and two patterns for AND. I think a key concept to keep in mind is that once we determine a Zbs operation is safe to perform on a SI value, we can rewrite the RTL in 64bit form. If we were ever to try and use range information at expand time for this stuff (and we probably should investigate that), that's the path I'd suggest. This is notably cleaner than my original implementation which actually kept the more complex RTL form through final and emitted 2/3 instructions (mask the bit position, then the bset/bclr/binv). Tested in my tester, but waiting for pre-commit CI to report back before taking further action. gcc/ * config/riscv/bitmanip.md (bset splitters): Turn into define_and_splits. Don't depend on combine splitting the "andn with constant" form. (bset, binv, bclr with masked bit position): New patterns. gcc/testsuite * gcc.target/riscv/binv-for-simode-1.c: New test. * gcc.target/riscv/bset-for-simode-1.c: New test. * gcc.target/riscv/bclr-for-simode-1.c: New test. (cherry picked from commit 273f16a125c4fab664683376ae04a9a31e7d6a22) Diff: --- gcc/config/riscv/bitmanip.md | 135 ++--- gcc/testsuite/gcc.target/riscv/bclr-for-simode-1.c | 25 gcc/testsuite/gcc.target/riscv/binv-for-simode-1.c | 24 gcc/testsuite/gcc.target/riscv/bset-for-simode-1.c | 24 4 files changed, 192 insertions(+), 16 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 3eedabffca0..f403ba8dbba 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -615,37 +615,140 @@ ;; shift constant. With the limited range we know the SImode sign ;; bit is never set, thus we can treat this as zero extending and ;; generate the bsetdi_2 pattern. -(define_split - [(set (match_operand:DI 0 "register_operand") +(define_insn_and_split "" + [(set (match_operand:DI 0 "register_operand" "=r") (any_extend:DI (ashift:SI (const_int 1) (subreg:QI - (and:DI (not:DI (match_operand:DI 1 "register_operand")) + (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) (match_operand 2 "const_int_operand")) 0 - (clobber (match_operand:DI 3 "register_operand"))] + (clobber (match_scratch:X 3 "=&r"))] "TARGET_64BIT && TARGET_ZBS && (TARGET_ZBB || TARGET_ZBKB) && (INTVAL (operands[2]) & 0x1f) != 0x1f" - [(set (match_dup 0) (and:DI (not:DI (match_dup 1)) (match_dup 2))) -(set (match_dup 0) (zero_extend:DI (ashift:SI - (const_int 1) - (subreg:QI (match_dup 0) 0]) + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 2)) +(set (match_dup 3) (and:DI (not:DI (match_dup 1)) (match_dup 3))) +(set (match_dup 0) (zero_extend:DI +(ashift:SI (const_int 1) (match_dup 4] + { operands[4] = gen_lowpart (QImode, operands[3]); } + [(set_attr "type" "bitmanip")]) -(define_split - [(set (match_operand:DI 0 "register_operand") - (any_extend:DI +(define_insn_and_split "" + [(set (match_operand:DI 0 "register_operand" "=r") +(any_extend:DI (ashift:SI (const_int 1) (subreg:QI - (and:DI (match_operand:DI 1 "register_operand") + (and:DI (match_operand:DI 1 "register_operand" "r") (match_operand 2 "const_int_operand")) 0] "TARGET_64BIT && TARGET_ZBS && (INTVAL (operands[2]) & 0x1f) != 0x1f" - [(set
[gcc r14-10387] Fortran: fix associate with assumed-length character array [PR115700]
https://gcc.gnu.org/g:36ca07f0a95c00cc985fc06e46df4028e6f2b77e commit r14-10387-g36ca07f0a95c00cc985fc06e46df4028e6f2b77e Author: Harald Anlauf Date: Tue Jul 2 21:26:05 2024 +0200 Fortran: fix associate with assumed-length character array [PR115700] gcc/fortran/ChangeLog: PR fortran/115700 * trans-stmt.cc (trans_associate_var): When the associate target is an array-valued character variable, the length is known at entry of the associate block. Move setting of string length of the selector to the initialization part of the block. gcc/testsuite/ChangeLog: PR fortran/115700 * gfortran.dg/associate_69.f90: New test. (cherry picked from commit 7b7f203472d07a05d959a29638c7c95d98bf0c1c) Diff: --- gcc/fortran/trans-stmt.cc | 18 gcc/testsuite/gfortran.dg/associate_69.f90 | 33 ++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc index 1fd75c6a37c..59237b8cdfb 100644 --- a/gcc/fortran/trans-stmt.cc +++ b/gcc/fortran/trans-stmt.cc @@ -1911,6 +1911,8 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) gfc_se se; tree desc; bool cst_array_ctor; + stmtblock_t init; + gfc_init_block (&init); desc = sym->backend_decl; cst_array_ctor = e->expr_type == EXPR_ARRAY @@ -1935,10 +1937,17 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) && !sym->attr.select_type_temporary && sym->ts.u.cl->backend_decl && VAR_P (sym->ts.u.cl->backend_decl) + && se.string_length && se.string_length != sym->ts.u.cl->backend_decl) - gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl, - fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl), - se.string_length)); + { + /* When the target is a variable, its length is already known. */ + tree len = fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl), + se.string_length); + if (e->expr_type == EXPR_VARIABLE) + gfc_add_modify (&init, sym->ts.u.cl->backend_decl, len); + else + gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl, len); + } /* If we didn't already do the pointer assignment, set associate-name descriptor to the one generated for the temporary. */ @@ -1978,7 +1987,8 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) } /* Done, register stuff as init / cleanup code. */ - gfc_add_init_cleanup (block, gfc_finish_block (&se.pre), + gfc_add_block_to_block (&init, &se.pre); + gfc_add_init_cleanup (block, gfc_finish_block (&init), gfc_finish_block (&se.post)); } diff --git a/gcc/testsuite/gfortran.dg/associate_69.f90 b/gcc/testsuite/gfortran.dg/associate_69.f90 new file mode 100644 index 000..28f488bb274 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_69.f90 @@ -0,0 +1,33 @@ +! { dg-do compile } +! { dg-options "-Og -Wuninitialized -Wmaybe-uninitialized -fdump-tree-optimized" } +! +! PR fortran/115700 - Bogus warning for associate with assumed-length character array +! +subroutine mvce(x) + implicit none + character(len=*), dimension(:), intent(in) :: x + + associate (tmp1 => x) +if (len (tmp1) /= len (x)) stop 1 + end associate + + associate (tmp2 => x(1:)) +if (len (tmp2) /= len (x)) stop 2 + end associate + + associate (tmp3 => x(1:)(:)) +if (len (tmp3) /= len (x)) stop 3 + end associate + +! The following associate blocks still produce bogus warnings: + +! associate (tmp4 => x(:)(1:)) +! if (len (tmp4) /= len (x)) stop 4 +! end associate +! +! associate (tmp5 => x(1:)(1:)) +! if (len (tmp5) /= len (x)) stop 5 +! end associate +end + +! { dg-final { scan-tree-dump-not " \\.tmp" "optimized" } }
[gcc r15-1883] doc: Remove dubious example around bug reporting
https://gcc.gnu.org/g:a28046e215307cf11c7a133c8b33dc0c0bcf74ec commit r15-1883-ga28046e215307cf11c7a133c8b33dc0c0bcf74ec Author: Gerald Pfeifer Date: Sun Jul 7 22:01:40 2024 +0200 doc: Remove dubious example around bug reporting gcc: * doc/bugreport.texi (Bug Criteria): Remove dubious example. Diff: --- gcc/doc/bugreport.texi | 5 - 1 file changed, 5 deletions(-) diff --git a/gcc/doc/bugreport.texi b/gcc/doc/bugreport.texi index b7cfb5dd6ae..7a603241f77 100644 --- a/gcc/doc/bugreport.texi +++ b/gcc/doc/bugreport.texi @@ -50,11 +50,6 @@ However, you must double-check to make sure, because you may have a program whose behavior is undefined, which happened by chance to give the desired results with another C or C++ compiler. -For example, in many nonoptimizing compilers, you can write @samp{x;} -at the end of a function instead of @samp{return x;}, with the same -results. But the value of the function is undefined if @code{return} -is omitted; it is not a bug when GCC produces different results. - Problems often result from expressions with two increment operators, as in @code{f (*p++, *p++)}. Your previous compiler might have interpreted that expression the way you intended; GCC might
[gcc r15-1884] maintainer-scripts: Switch bug reporting URL to https
https://gcc.gnu.org/g:e3b8480f94ee15e7fffc662d40270ee57c6ad82b commit r15-1884-ge3b8480f94ee15e7fffc662d40270ee57c6ad82b Author: Gerald Pfeifer Date: Sun Jul 7 22:20:45 2024 +0200 maintainer-scripts: Switch bug reporting URL to https maintainer-scripts: * update_web_docs_git (BUGURL): Switch to https. Diff: --- maintainer-scripts/update_web_docs_git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maintainer-scripts/update_web_docs_git b/maintainer-scripts/update_web_docs_git index c651e567424..0d7b6c90fe9 100755 --- a/maintainer-scripts/update_web_docs_git +++ b/maintainer-scripts/update_web_docs_git @@ -45,7 +45,7 @@ MANUALS="cpp libiberty porting" -BUGURL="http://gcc.gnu.org/bugs/"; +BUGURL="https://gcc.gnu.org/bugs/"; CSS=/texinfo-manuals.css WWWBASE=${WWWBASE:-"/www/gcc/htdocs"}
[gcc r15-1885] libstdc++: Tweak two links in configuration docs
https://gcc.gnu.org/g:6fa4802eee9c82152a8c56a73fba815122f75e93 commit r15-1885-g6fa4802eee9c82152a8c56a73fba815122f75e93 Author: Gerald Pfeifer Date: Sun Jul 7 23:18:11 2024 +0200 libstdc++: Tweak two links in configuration docs libstdc++-v3: * doc/xml/manual/configure.xml: Update Autobook 14 link. Update GCC installation instructions link. * doc/html/manual/configure.html: Regenerate. Diff: --- libstdc++-v3/doc/html/manual/configure.html | 4 ++-- libstdc++-v3/doc/xml/manual/configure.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/doc/html/manual/configure.html b/libstdc++-v3/doc/html/manual/configure.html index 346b5d345cd..3564b0c409f 100644 --- a/libstdc++-v3/doc/html/manual/configure.html +++ b/libstdc++-v3/doc/html/manual/configure.html @@ -9,7 +9,7 @@ Here are all of the configure options specific to libstdc++. Keep in mind that - http://sourceware.org/autobook/autobook/autobook_14.html"; target="_top">they + https://sourceware.org/autobook/autobook/autobook_14.html"; target="_top">they all have opposite forms as well (enable/disable and with/without). The defaults are for the current development sources, which may be different than those @@ -82,7 +82,7 @@ (described next). --enable-threads=OPTIONSelect a threading library. A full description is given in the - general http://gcc.gnu.org/install/configure.html"; target="_top">compiler + general https://gcc.gnu.org/install/configure.html"; target="_top">compiler configuration instructions. This option can change the library ABI. --enable-libstdcxx-threadsEnable C++11 threads support. If not explicitly specified, diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml index 0a477ab85e5..cd5f44458a2 100644 --- a/libstdc++-v3/doc/xml/manual/configure.xml +++ b/libstdc++-v3/doc/xml/manual/configure.xml @@ -24,7 +24,7 @@ Here are all of the configure options specific to libstdc++. Keep in mind that - http://www.w3.org/1999/xlink"; xlink:href="http://sourceware.org/autobook/autobook/autobook_14.html";>they + http://www.w3.org/1999/xlink"; xlink:href="https://sourceware.org/autobook/autobook/autobook_14.html";>they all have opposite forms as well (enable/disable and with/without). The defaults are for the current development sources, which may be different than those @@ -148,7 +148,7 @@ --enable-threads=OPTION Select a threading library. A full description is given in the - general http://www.w3.org/1999/xlink"; xlink:href="http://gcc.gnu.org/install/configure.html";>compiler + general http://www.w3.org/1999/xlink"; xlink:href="https://gcc.gnu.org/install/configure.html";>compiler configuration instructions. This option can change the library ABI.
[gcc r15-1886] PR modula2/115804 ICE during gimplification with new isfinite optab
https://gcc.gnu.org/g:4594d555aa551a9998fc921363c5f6ea50630d5c commit r15-1886-g4594d555aa551a9998fc921363c5f6ea50630d5c Author: Gaius Mulley Date: Sun Jul 7 22:42:51 2024 +0100 PR modula2/115804 ICE during gimplification with new isfinite optab The calls to five m2 builtins have the incorrect return type. This was detected when adding isfinitedf2 optab to the s390 backend which results in ICEs during gimplification in the gm2 testsuite. gcc/m2/ChangeLog: PR modula2/115804 * gm2-gcc/m2builtins.cc (builtin_function_entry): Add GTY. (DoBuiltinMemCopy): Add rettype and use rettype in the call. (DoBuiltinAlloca): Ditto. (DoBuiltinIsfinite): Ditto. (DoBuiltinIsnan): Ditto. (m2builtins_BuiltInHugeVal): Ditto. (m2builtins_BuiltInHugeValShort): Ditto. (m2builtins_BuiltInHugeValLong): Ditto. Co-Authored-By: Stefan Schulze Frielinghaus Co-Authored-By: Andrew Pinski Signed-off-by: Gaius Mulley Diff: --- gcc/m2/gm2-gcc/m2builtins.cc | 26 +++--- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/gcc/m2/gm2-gcc/m2builtins.cc b/gcc/m2/gm2-gcc/m2builtins.cc index cfb4751e15a..31c344c4a59 100644 --- a/gcc/m2/gm2-gcc/m2builtins.cc +++ b/gcc/m2/gm2-gcc/m2builtins.cc @@ -138,7 +138,7 @@ struct builtin_function_entry /* Entries are added by examining gcc/builtins.def and copying those functions which can be applied to Modula-2. */ -static struct builtin_function_entry list_of_builtins[] = { +static struct GTY(()) builtin_function_entry list_of_builtins[] = { { "__builtin_alloca", BT_FN_PTR_SIZE, BUILT_IN_ALLOCA, BUILT_IN_NORMAL, "alloca", NULL, NULL, bf_extension_lib }, { "__builtin_memcpy", BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE, BUILT_IN_MEMCPY, @@ -1007,10 +1007,11 @@ static tree DoBuiltinMemCopy (location_t location, tree dest, tree src, tree bytes) { tree functype = TREE_TYPE (gm2_memcpy_node); + tree rettype = TREE_TYPE (functype); tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_memcpy_node); tree call - = m2treelib_DoCall3 (location, ptr_type_node, funcptr, dest, src, bytes); + = m2treelib_DoCall3 (location, rettype, funcptr, dest, src, bytes); return call; } @@ -1018,10 +1019,10 @@ static tree DoBuiltinAlloca (location_t location, tree bytes) { tree functype = TREE_TYPE (gm2_alloca_node); + tree rettype = TREE_TYPE (functype); tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_alloca_node); - tree call = m2treelib_DoCall1 (location, ptr_type_node, funcptr, bytes); - + tree call = m2treelib_DoCall1 (location, rettype, funcptr, bytes); return call; } @@ -1029,10 +1030,10 @@ static tree DoBuiltinIsfinite (location_t location, tree value) { tree functype = TREE_TYPE (gm2_isfinite_node); + tree rettype = TREE_TYPE (functype); tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_isfinite_node); - tree call = m2treelib_DoCall1 (location, ptr_type_node, funcptr, value); - + tree call = m2treelib_DoCall1 (location, rettype, funcptr, value); return call; } @@ -1040,10 +1041,10 @@ static tree DoBuiltinIsnan (location_t location, tree value) { tree functype = TREE_TYPE (gm2_isnan_node); + tree rettype = TREE_TYPE (functype); tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_isnan_node); - tree call = m2treelib_DoCall1 (location, ptr_type_node, funcptr, value); - + tree call = m2treelib_DoCall1 (location, rettype, funcptr, value); return call; } @@ -1051,9 +1052,10 @@ tree m2builtins_BuiltInHugeVal (location_t location) { tree functype = TREE_TYPE (gm2_huge_val_node); + tree rettype = TREE_TYPE (functype); tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_val_node); - tree call = m2treelib_DoCall0 (location, ptr_type_node, funcptr); + tree call = m2treelib_DoCall0 (location, rettype, funcptr); return call; } @@ -1061,9 +1063,10 @@ tree m2builtins_BuiltInHugeValShort (location_t location) { tree functype = TREE_TYPE (gm2_huge_valf_node); + tree rettype = TREE_TYPE (functype); tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_valf_node); - tree call = m2treelib_DoCall0 (location, ptr_type_node, funcptr); + tree call = m2treelib_DoCall0 (location, rettype, funcptr); return call; } @@ -1071,9 +1074,10 @@ tree m2builtins_BuiltInHugeValLong (location_t location) { tree functype = TREE_TYPE (gm2_huge_vall_node); + tree rettype = TREE_TYPE (functype); tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_vall_node); - tree call = m2treelib_DoCall0 (location, ptr_type_node, funcptr); + tree call = m2treelib_DoCall0 (location, rettype, funcptr); return call; }
[gcc r14-10389] Fix MinGW option -mcrtdll=
https://gcc.gnu.org/g:a8617b5ec39f81a59650193be1db2cfecdd76fb6 commit r14-10389-ga8617b5ec39f81a59650193be1db2cfecdd76fb6 Author: Pali Rohár Date: Sun Jun 23 18:40:59 2024 +0200 Fix MinGW option -mcrtdll= Add missing msvcr40* and msvcrtd* cases to CPP_SPEC and document missing _UCRT macro and msvcr71* case. Fixes commit 453cb585f0f8673a5d69d1b420ffd4b3f53aca00. gcc/ * config/i386/mingw-w64.h (CPP_SPEC): Add missing -mcrtdll= cases: msvcr40*, msvcrtd*. * config/i386/mingw32.h (CPP_SPEC): Add missing -mcrtdll= cases: msvcr40*, msvcrtd*. * doc/invoke.texi: Add missing -mcrtdll= cases: msvcr40*, msvcrtd*, msvcr71*. Express wildcards with *. Document _UCRT. (cherry picked from commit 0de0476e47c774db21c94a75d60485a55ec7b5b4) Signed-off-by: Jonathan Yong <10wa...@gmail.com> Diff: --- gcc/config/i386/mingw-w64.h | 2 ++ gcc/config/i386/mingw32.h | 2 ++ gcc/doc/invoke.texi | 13 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h index dde26413e221..0a9986c44d40 100644 --- a/gcc/config/i386/mingw-w64.h +++ b/gcc/config/i386/mingw-w64.h @@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see "%{mcrtdll=msvcrt10*:-D__MSVCRT_VERSION__=0x100} " \ "%{mcrtdll=msvcrt20*:-D__MSVCRT_VERSION__=0x200} " \ "%{mcrtdll=msvcrt40*:-D__MSVCRT_VERSION__=0x400} " \ +"%{mcrtdll=msvcr40*:-D__MSVCRT_VERSION__=0x400} " \ +"%{mcrtdll=msvcrtd*:-D__MSVCRT_VERSION__=0x600} " \ "%{mcrtdll=msvcrt-os*:-D__MSVCRT_VERSION__=0x700} " \ "%{mcrtdll=msvcr70*:-D__MSVCRT_VERSION__=0x700} " \ "%{mcrtdll=msvcr71*:-D__MSVCRT_VERSION__=0x701} " \ diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h index 58304fc55f62..7753affd36d4 100644 --- a/gcc/config/i386/mingw32.h +++ b/gcc/config/i386/mingw32.h @@ -94,6 +94,8 @@ along with GCC; see the file COPYING3. If not see "%{mcrtdll=msvcrt10*:-D__MSVCRT_VERSION__=0x100} " \ "%{mcrtdll=msvcrt20*:-D__MSVCRT_VERSION__=0x200} " \ "%{mcrtdll=msvcrt40*:-D__MSVCRT_VERSION__=0x400} " \ +"%{mcrtdll=msvcr40*:-D__MSVCRT_VERSION__=0x400} " \ +"%{mcrtdll=msvcrtd*:-D__MSVCRT_VERSION__=0x600} " \ "%{mcrtdll=msvcrt-os*:-D__MSVCRT_VERSION__=0x700} " \ "%{mcrtdll=msvcr70*:-D__MSVCRT_VERSION__=0x700} " \ "%{mcrtdll=msvcr71*:-D__MSVCRT_VERSION__=0x701} " \ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 67220051a5be..f82f7d2817bb 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -36325,13 +36325,14 @@ enabled by default on those targets. @opindex mcrtdll @item -mcrtdll=@var{library} Preprocess, compile or link with specified C RunTime DLL @var{library}. -This option adjust predefined macros @code{__CRTDLL__}, @code{__MSVCRT__} -and @code{__MSVCRT_VERSION__} for specified CRT @var{library}, choose -start file for CRT @var{library} and link with CRT @var{library}. +This option adjust predefined macros @code{__CRTDLL__}, @code{__MSVCRT__}, +@code{_UCRT} and @code{__MSVCRT_VERSION__} for specified CRT @var{library}, +choose start file for CRT @var{library} and link with CRT @var{library}. Recognized CRT library names for proprocessor are: -@code{crtdll}, @code{msvcrt10}, @code{msvcrt20}, @code{msvcrt40}, -@code{msvcrt-os}, @code{msvcr70}, @code{msvcr80}, @code{msvcr90}, -@code{msvcr100}, @code{msvcr110}, @code{msvcr120} and @code{ucrt}. +@code{crtdll*}, @code{msvcrt10*}, @code{msvcrt20*}, @code{msvcrt40*}, +@code{msvcr40*}, @code{msvcrtd*}, @code{msvcrt-os*}, +@code{msvcr70*}, @code{msvcr71*}, @code{msvcr80*}, @code{msvcr90*}, +@code{msvcr100*}, @code{msvcr110*}, @code{msvcr120*} and @code{ucrt*}. If this options is not specified then the default MinGW import library @code{msvcrt} is used for linking and no other adjustment for preprocessor is done. MinGW import library @code{msvcrt} is just a
[gcc r15-1888] x86: Update branch hint for Redwood Cove.
https://gcc.gnu.org/g:a910c30c7c27cd0f6d2d2694544a09fb11d611b9 commit r15-1888-ga910c30c7c27cd0f6d2d2694544a09fb11d611b9 Author: H.J. Lu Date: Tue Apr 26 11:08:55 2022 -0700 x86: Update branch hint for Redwood Cove. According to Intel® 64 and IA-32 Architectures Optimization Reference Manual[1], Branch Hint is updated for Redwood Cove. cut from [1]- Starting with the Redwood Cove microarchitecture, if the predictor has no stored information about a branch, the branch has the Intel® SSE2 branch taken hint (i.e., instruction prefix 3EH), When the codec decodes the branch, it flips the branch’s prediction from not-taken to taken. It then flushes the pipeline in front of it and steers this pipeline to fetch the taken path of the branch. cut end - Split tune branch_prediction_hints into branch_prediction_hints_taken and branch_prediction_hints_not_taken, always generate branch hint for conditional branches, both tunes are disabled by default. [1] https://www.intel.com/content/www/us/en/content-details/821612/intel-64-and-ia-32-architectures-optimization-reference-manual-volume-1.html gcc/ * config/i386/i386.cc (ix86_print_operand): Always generate branch hint for conditional branches. * config/i386/i386.h (TARGET_BRANCH_PREDICTION_HINTS): Split into .. (TARGET_BRANCH_PREDICTION_HINTS_TAKEN): .. this, and .. (TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN): .. this. * config/i386/x86-tune.def (X86_TUNE_BRANCH_PREDICTION_HINTS): Split into .. (X86_TUNE_BRANCH_PREDICTION_HINTS_TAKEN): .. this, and .. (X86_TUNE_BRANCH_PREDICTION_HINTS_NOT_TAKEN): .. this. Diff: --- gcc/config/i386/i386.cc | 29 + gcc/config/i386/i386.h | 6 -- gcc/config/i386/x86-tune.def | 13 +++-- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index f75250f79de4..17d23bbcbc27 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -14057,7 +14057,8 @@ ix86_print_operand (FILE *file, rtx x, int code) if (!optimize || optimize_function_for_size_p (cfun) - || !TARGET_BRANCH_PREDICTION_HINTS) + || (!TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN + && !TARGET_BRANCH_PREDICTION_HINTS_TAKEN)) return; x = find_reg_note (current_output_insn, REG_BR_PROB, 0); @@ -14066,25 +14067,13 @@ ix86_print_operand (FILE *file, rtx x, int code) int pred_val = profile_probability::from_reg_br_prob_note (XINT (x, 0)).to_reg_br_prob_base (); - if (pred_val < REG_BR_PROB_BASE * 45 / 100 - || pred_val > REG_BR_PROB_BASE * 55 / 100) - { - bool taken = pred_val > REG_BR_PROB_BASE / 2; - bool cputaken - = final_forward_branch_p (current_output_insn) == 0; - - /* Emit hints only in the case default branch prediction - heuristics would fail. */ - if (taken != cputaken) - { - /* We use 3e (DS) prefix for taken branches and - 2e (CS) prefix for not taken branches. */ - if (taken) - fputs ("ds ; ", file); - else - fputs ("cs ; ", file); - } - } + bool taken = pred_val > REG_BR_PROB_BASE / 2; + /* We use 3e (DS) prefix for taken branches and + 2e (CS) prefix for not taken branches. */ + if (taken && TARGET_BRANCH_PREDICTION_HINTS_TAKEN) + fputs ("ds ; ", file); + else if (!taken && TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN) + fputs ("cs ; ", file); } return; } diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 0c5292e1d646..eabb3248ea00 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -309,8 +309,10 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST]; #define TARGET_ZERO_EXTEND_WITH_AND \ ix86_tune_features[X86_TUNE_ZERO_EXTEND_WITH_AND] #define TARGET_UNROLL_STRLEN ix86_tune_features[X86_TUNE_UNROLL_STRLEN] -#define TARGET_BRANCH_PREDICTION_HINTS \ - ix86_tune_features[X86_TUNE_BRANCH_PREDICTION_HINTS] +#define TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN \ + ix86_tune_features[X86_TUNE_BRANCH_PREDICTION_HINTS_NOT_TAKEN] +#define TARGET_BRANCH_PREDICTION_HINTS_TAKEN \ + ix86_tune_features[X86_TUNE_BRANCH_PREDICTION_HINTS_TAKEN] #define TARGET_DOUBLE_WITH_ADD ix86_tune
[gcc r15-1889] rs6000: Consider explicit VSX when masking off ALTIVEC [PR115688]
https://gcc.gnu.org/g:f90ca62566c1d20da585d95ced99f6a1903fc2cc commit r15-1889-gf90ca62566c1d20da585d95ced99f6a1903fc2cc Author: Kewen Lin Date: Sun Jul 7 22:38:34 2024 -0500 rs6000: Consider explicit VSX when masking off ALTIVEC [PR115688] PR115688 exposes an inconsistent state in which we have VSX enabled but ALTIVEC disabled. There is one hunk: if (main_target_opt && !main_target_opt->x_rs6000_altivec_abi) rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC) & ~rs6000_isa_flags_explicit); which disables both VSX and ALTIVEC together only considering them explicitly set or not. For the given case, VSX is explicitly specified, altivec is implicitly enabled as it's part of set ISA_2_6_MASKS_SERVER. When falling into the above hunk, vsx is kept as it's explicitly enabled but altivec gets masked off, it's unexpected. This patch is to consider explicit VSX when masking off ALTIVEC, not mask off it if TARGET_VSX and it's explicitly set. PR target/115688 gcc/ChangeLog: * config/rs6000/rs6000.cc (rs6000_option_override_internal): Consider explicit VSX when masking off ALTIVEC. gcc/testsuite/ChangeLog: * gcc.target/powerpc/pr115688.c: New test. Diff: --- gcc/config/rs6000/rs6000.cc | 8 ++-- gcc/testsuite/gcc.target/powerpc/pr115688.c | 14 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 58553ff66f46..2cbea6ea2d7c 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -3933,8 +3933,12 @@ rs6000_option_override_internal (bool global_init_p) not for 32-bit. Don't move this before the above code using ignore_masks, since it can reset the cleared VSX/ALTIVEC flag again. */ if (main_target_opt && !main_target_opt->x_rs6000_altivec_abi) -rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC) - & ~rs6000_isa_flags_explicit); +{ + rs6000_isa_flags &= ~(OPTION_MASK_VSX & ~rs6000_isa_flags_explicit); + /* Don't mask off ALTIVEC if it is enabled by an explicit VSX. */ + if (!TARGET_VSX) + rs6000_isa_flags &= ~(OPTION_MASK_ALTIVEC & ~rs6000_isa_flags_explicit); +} if (TARGET_CRYPTO && !TARGET_ALTIVEC) { diff --git a/gcc/testsuite/gcc.target/powerpc/pr115688.c b/gcc/testsuite/gcc.target/powerpc/pr115688.c new file mode 100644 index ..5222e66ef170 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr115688.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target powerpc*-*-linux* } } */ +/* { dg-options "-mdejagnu-cpu=power5 -O2" } */ + +/* Ignore some error messages on "target attribute or + pragma changes AltiVec ABI". */ +/* { dg-excess-errors "pr115688" { target ilp32 } } */ + +/* Verify there is no ICE under 32 bit env. */ + +__attribute__((target("vsx"))) +int test (void) +{ + return 0; +}
[gcc r15-1890] isel: Fold more in gimple_expand_vec_cond_expr with andc and iorc [PR115659]
https://gcc.gnu.org/g:f379596e0ba99df249d6e8b3f2e66edfcea916fe commit r15-1890-gf379596e0ba99df249d6e8b3f2e66edfcea916fe Author: Kewen Lin Date: Mon Jul 8 00:14:59 2024 -0500 isel: Fold more in gimple_expand_vec_cond_expr with andc and iorc [PR115659] As PR115659 shows, assuming c = x CMP y, there are some folding chances for patterns r = c ? 0/z : z/-1: - for r = c ? 0 : z, it can be folded into r = ~c & z. - for r = c ? z : -1, it can be folded into r = ~c | z. But BIT_AND/BIT_IOR applied on one BIT_NOT operand is a compound operation, it's arguable to consider it beats vector selection. So this patch is to introduce new optabs andc, iorc and its corresponding internal functions BIT_{ANDC,IORC}, and if targets defines such optabs for vector modes, it means targets support these hardware insns and should be not worse than vector selection. PR tree-optimization/115659 gcc/ChangeLog: * doc/md.texi: Document andcm3 and iorcm3. * gimple-isel.cc (gimple_expand_vec_cond_expr): Add more foldings for patterns x CMP y ? 0 : z and x CMP y ? z : -1. * internal-fn.def (BIT_ANDC): New internal function. (BIT_IORC): Likewise. * optabs.def (andc, iorc): New optab. Diff: --- gcc/doc/md.texi | 10 ++ gcc/gimple-isel.cc | 26 ++ gcc/internal-fn.def | 4 gcc/optabs.def | 2 ++ 4 files changed, 42 insertions(+) diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 4fd7da095feb..7f4335e0aac1 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5543,6 +5543,16 @@ means of constraints requiring operands 1 and 0 to be the same location. @itemx @samp{and@var{m}3}, @samp{ior@var{m}3}, @samp{xor@var{m}3} Similar, for other arithmetic operations. +@cindex @code{andc@var{m}3} instruction pattern +@item @samp{andc@var{m}3} +Like @code{and@var{m}3}, but it uses bitwise-complement of operand 2 +rather than operand 2 itself. + +@cindex @code{iorc@var{m}3} instruction pattern +@item @samp{iorc@var{m}3} +Like @code{ior@var{m}3}, but it uses bitwise-complement of operand 2 +rather than operand 2 itself. + @cindex @code{addv@var{m}4} instruction pattern @item @samp{addv@var{m}4} Like @code{add@var{m}3} but takes a @code{code_label} as operand 3 and diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc index 60719eafc651..e4ab42ad05ba 100644 --- a/gcc/gimple-isel.cc +++ b/gcc/gimple-isel.cc @@ -284,6 +284,32 @@ gimple_expand_vec_cond_expr (struct function *fun, gimple_stmt_iterator *gsi, /* r = c ? z : c */ op2 = new_op2; } + bool op1_zerop = integer_zerop (op1); + bool op2_minus_onep = integer_minus_onep (op2); + /* Try to fold r = c ? 0 : z to r = .BIT_ANDC (z, c). */ + if (op1_zerop + && (direct_internal_fn_supported_p (IFN_BIT_ANDC, vtype, + OPTIMIZE_FOR_BOTH))) + { + tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0); + tree new_op = make_ssa_name (vtype); + gassign *new_stmt = gimple_build_assign (new_op, conv_op); + gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT); + return gimple_build_call_internal (IFN_BIT_ANDC, 2, op2, +new_op); + } + /* Try to fold r = c ? z : -1 to r = .BIT_IORC (z, c). */ + else if (op2_minus_onep + && (direct_internal_fn_supported_p (IFN_BIT_IORC, vtype, + OPTIMIZE_FOR_BOTH))) + { + tree conv_op = build1 (VIEW_CONVERT_EXPR, vtype, op0); + tree new_op = make_ssa_name (vtype); + gassign *new_stmt = gimple_build_assign (new_op, conv_op); + gsi_insert_seq_before (gsi, new_stmt, GSI_SAME_STMT); + return gimple_build_call_internal (IFN_BIT_IORC, 2, op1, +new_op); + } } /* When the compare has EH we do not want to forward it when diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index 915d329c05a0..0b45f322f0db 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -595,6 +595,10 @@ DEF_INTERNAL_FN (DIVMODBITINT, ECF_LEAF, ". O . O . R . R . ") DEF_INTERNAL_FN (FLOATTOBITINT, ECF_LEAF | ECF_NOTHROW, ". O . . ") DEF_INTERNAL_FN (BITINTTOFLOAT, ECF_PURE | ECF_LEAF, ". R . ") +/* Bitwise functions. */ +DEF_INTERNAL_OPTAB_FN (BIT_ANDC, ECF_CONST, andc, binary) +DEF_INTERNAL_OPTAB_FN (BIT_IORC, ECF_CONST, iorc, binary) + #undef DEF_INTERNAL_WIDENING_OPTAB_FN #undef DEF_INTERNAL_SIGNED_COND_FN #undef DEF_INTERNAL_COND_FN diff --git a/gcc/optabs.def b/gcc/optabs.de
[gcc r15-1891] rs6000: Replace orc with iorc [PR115659]
https://gcc.gnu.org/g:6425dae07aa4be58abade03455c2d9744f73d4e1 commit r15-1891-g6425dae07aa4be58abade03455c2d9744f73d4e1 Author: Kewen Lin Date: Mon Jul 8 00:15:00 2024 -0500 rs6000: Replace orc with iorc [PR115659] Since iorc optab is introduced, this patch is to update the expander names and all the related uses like bif expanders, gen functions accordingly. PR tree-optimization/115659 gcc/ChangeLog: * config/rs6000/rs6000-builtins.def: Update some bif expanders by replacing orc3 with iorc3. * config/rs6000/rs6000-string.cc (expand_cmp_vec_sequence): Update gen function by replacing orc3 with iorc3. * config/rs6000/rs6000.md (orc3): Rename to ... (iorc3): ... this. Diff: --- gcc/config/rs6000/rs6000-builtins.def | 24 gcc/config/rs6000/rs6000-string.cc| 2 +- gcc/config/rs6000/rs6000.md | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def index 3bc7fed69568..736890fe6cb8 100644 --- a/gcc/config/rs6000/rs6000-builtins.def +++ b/gcc/config/rs6000/rs6000-builtins.def @@ -2147,40 +2147,40 @@ NEG_V2DI negv2di2 {} const vsc __builtin_altivec_orc_v16qi (vsc, vsc); -ORC_V16QI orcv16qi3 {} +ORC_V16QI iorcv16qi3 {} const vuc __builtin_altivec_orc_v16qi_uns (vuc, vuc); -ORC_V16QI_UNS orcv16qi3 {} +ORC_V16QI_UNS iorcv16qi3 {} const vsq __builtin_altivec_orc_v1ti (vsq, vsq); -ORC_V1TI orcv1ti3 {} +ORC_V1TI iorcv1ti3 {} const vuq __builtin_altivec_orc_v1ti_uns (vuq, vuq); -ORC_V1TI_UNS orcv1ti3 {} +ORC_V1TI_UNS iorcv1ti3 {} const vd __builtin_altivec_orc_v2df (vd, vd); -ORC_V2DF orcv2df3 {} +ORC_V2DF iorcv2df3 {} const vsll __builtin_altivec_orc_v2di (vsll, vsll); -ORC_V2DI orcv2di3 {} +ORC_V2DI iorcv2di3 {} const vull __builtin_altivec_orc_v2di_uns (vull, vull); -ORC_V2DI_UNS orcv2di3 {} +ORC_V2DI_UNS iorcv2di3 {} const vf __builtin_altivec_orc_v4sf (vf, vf); -ORC_V4SF orcv4sf3 {} +ORC_V4SF iorcv4sf3 {} const vsi __builtin_altivec_orc_v4si (vsi, vsi); -ORC_V4SI orcv4si3 {} +ORC_V4SI iorcv4si3 {} const vui __builtin_altivec_orc_v4si_uns (vui, vui); -ORC_V4SI_UNS orcv4si3 {} +ORC_V4SI_UNS iorcv4si3 {} const vss __builtin_altivec_orc_v8hi (vss, vss); -ORC_V8HI orcv8hi3 {} +ORC_V8HI iorcv8hi3 {} const vus __builtin_altivec_orc_v8hi_uns (vus, vus); -ORC_V8HI_UNS orcv8hi3 {} +ORC_V8HI_UNS iorcv8hi3 {} const vsc __builtin_altivec_vclzb (vsc); VCLZB clzv16qi2 {} diff --git a/gcc/config/rs6000/rs6000-string.cc b/gcc/config/rs6000/rs6000-string.cc index 917f5572a6d3..c4c62e8e2f94 100644 --- a/gcc/config/rs6000/rs6000-string.cc +++ b/gcc/config/rs6000/rs6000-string.cc @@ -743,7 +743,7 @@ expand_cmp_vec_sequence (unsigned HOST_WIDE_INT bytes_to_compare, rtx cmp_combined = gen_reg_rtx (load_mode); emit_insn (gen_altivec_eqv16qi (cmp_res, s1data, s2data)); emit_insn (gen_altivec_eqv16qi (cmp_zero, s1data, zero_reg)); - emit_insn (gen_orcv16qi3 (vec_result, cmp_zero, cmp_res)); + emit_insn (gen_iorcv16qi3 (vec_result, cmp_zero, cmp_res)); emit_insn (gen_altivec_vcmpequb_p (cmp_combined, vec_result, zero_reg)); } } diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a5d205947895..276a5c9cf2d3 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -7324,7 +7324,7 @@ ;; The canonical form is to have the negated element first, so we need to ;; reverse arguments. -(define_expand "orc3" +(define_expand "iorc3" [(set (match_operand:BOOL_128 0 "vlogical_operand") (ior:BOOL_128 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
[gcc r15-1892] [RISC-V] add implied extension repeatly until stable
https://gcc.gnu.org/g:682731d11f9c02b24358d1af1e2bf6fca0221ee7 commit r15-1892-g682731d11f9c02b24358d1af1e2bf6fca0221ee7 Author: Fei Gao Date: Fri Jul 5 09:56:30 2024 + [RISC-V] add implied extension repeatly until stable Call handle_implied_ext repeatly until there's no new subset added into the subset list. gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_subset_list::riscv_subset_list): init m_subset_num to 0. (riscv_subset_list::add): increase m_subset_num once a subset added. (riscv_subset_list::finalize): call handle_implied_ext repeatly until no change in m_subset_num. * config/riscv/riscv-subset.h: add m_subset_num member. Signed-off-by: Fei Gao Diff: --- gcc/common/config/riscv/riscv-common.cc | 14 +++--- gcc/config/riscv/riscv-subset.h | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 16bdb3fd2259..b9bda3e110a2 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -569,7 +569,8 @@ riscv_subset_t::riscv_subset_t () } riscv_subset_list::riscv_subset_list (const char *arch, location_t loc) - : m_arch (arch), m_loc (loc), m_head (NULL), m_tail (NULL), m_xlen (0) + : m_arch (arch), m_loc (loc), m_head (NULL), m_tail (NULL), m_xlen (0), +m_subset_num (0) { } @@ -815,6 +816,7 @@ riscv_subset_list::add (const char *subset, int major_version, return; } + m_subset_num++; riscv_subset_t *s = new riscv_subset_t (); riscv_subset_t *itr; @@ -1597,9 +1599,15 @@ void riscv_subset_list::finalize () { riscv_subset_t *subset; + unsigned pre_subset_num; - for (subset = m_head; subset != NULL; subset = subset->next) -handle_implied_ext (subset->name.c_str ()); + do +{ + pre_subset_num = m_subset_num; + for (subset = m_head; subset != NULL; subset = subset->next) + handle_implied_ext (subset->name.c_str ()); +} + while (pre_subset_num != m_subset_num); gcc_assert (check_implied_ext ()); diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h index fe7f54d8bc57..7dc196a20074 100644 --- a/gcc/config/riscv/riscv-subset.h +++ b/gcc/config/riscv/riscv-subset.h @@ -62,6 +62,9 @@ private: /* X-len of m_arch. */ unsigned m_xlen; + /* Number of subsets. */ + unsigned m_subset_num; + riscv_subset_list (const char *, location_t); const char *parsing_subset_version (const char *, const char *, unsigned *,
[gcc r14-10390] Fortran: Unlimited polymorphic intrinsic function arguments [PR84006]
https://gcc.gnu.org/g:c36acfea1aea17ff8df8994657c8bf9e3ccde6ca commit r14-10390-gc36acfea1aea17ff8df8994657c8bf9e3ccde6ca Author: Paul Thomas Date: Sun May 12 06:59:45 2024 +0100 Fortran: Unlimited polymorphic intrinsic function arguments [PR84006] 2024-05-12 Paul Thomas gcc/fortran PR fortran/84006 PR fortran/100027 PR fortran/98534 * iresolve.cc (gfc_resolve_transfer): Emit a TODO error for unlimited polymorphic mold. * trans-expr.cc (gfc_resize_class_size_with_len): Use the fold even if a block is not available in which to fix the result. (trans_class_assignment): Enable correct assignment of character expressions to unlimited polymorphic variables using lhs _len field and rse string_length. * trans-intrinsic.cc (gfc_conv_intrinsic_storage_size): Extract the class expression so that the unlimited polymorphic class expression can be used in gfc_resize_class_size_with_len to obtain the storage size for character payloads. Guard the use of GFC_DECL_SAVED_DESCRIPTOR by testing for DECL_LANG_SPECIFIC to prevent the ICE. Also, invert the order to use the class expression extracted from the argument. (gfc_conv_intrinsic_transfer): In same way as 'storage_size', use the _len field to obtaining the correct length for arg 1. Add a branch for the element size in bytes of class expressions with provision to make use of the unlimited polymorphic _len field. Again, the class references are explicitly identified. 'mold_expr' was already declared. Use it instead of 'arg'. Do not fix 'dest_word_len' for deferred character sources because reallocation on assign makes use of it before it is assigned. gcc/testsuite/ PR fortran/84006 PR fortran/100027 * gfortran.dg/storage_size_7.f90: New test. PR fortran/98534 * gfortran.dg/transfer_class_4.f90: New test. (cherry picked from commit b9294757f82aae8de6d98c122cd4e3b98f685217) Diff: --- gcc/fortran/iresolve.cc| 4 ++ gcc/fortran/trans-expr.cc | 15 - gcc/fortran/trans-intrinsic.cc | 80 +- gcc/testsuite/gfortran.dg/storage_size_7.f90 | 91 ++ gcc/testsuite/gfortran.dg/transfer_class_4.f90 | 87 5 files changed, 257 insertions(+), 20 deletions(-) diff --git a/gcc/fortran/iresolve.cc b/gcc/fortran/iresolve.cc index c961cdbc2df4..c63a4a8d38cd 100644 --- a/gcc/fortran/iresolve.cc +++ b/gcc/fortran/iresolve.cc @@ -3025,6 +3025,10 @@ gfc_resolve_transfer (gfc_expr *f, gfc_expr *source ATTRIBUTE_UNUSED, } } + if (UNLIMITED_POLY (mold)) +gfc_error ("TODO: unlimited polymorphic MOLD in TRANSFER intrinsic at %L", + &mold->where); + f->ts = mold->ts; if (size == NULL && mold->rank == 0) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index d5fd6e399965..114e7629182a 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -317,6 +317,8 @@ gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size) size = gfc_evaluate_now (size, block); tmp = gfc_evaluate_now (fold_convert (type , tmp), block); } + else + tmp = fold_convert (type , tmp); tmp2 = fold_build2_loc (input_location, MULT_EXPR, type, size, tmp); tmp = fold_build2_loc (input_location, GT_EXPR, @@ -11998,15 +12000,24 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs, /* Take into account _len of unlimited polymorphic entities. TODO: handle class(*) allocatable function results on rhs. */ - if (UNLIMITED_POLY (rhs) && rhs->expr_type == EXPR_VARIABLE) + if (UNLIMITED_POLY (rhs)) { - tree len = trans_get_upoly_len (block, rhs); + tree len; + if (rhs->expr_type == EXPR_VARIABLE) + len = trans_get_upoly_len (block, rhs); + else + len = gfc_class_len_get (tmp); len = fold_build2_loc (input_location, MAX_EXPR, size_type_node, fold_convert (size_type_node, len), size_one_node); size = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (size), size, fold_convert (TREE_TYPE (size), len)); } + else if (rhs->ts.type == BT_CHARACTER && rse->string_length) + size = fold_build2_loc (input_location, MULT_EXPR, + gfc_charlen_type_node, size, + rse->string_length); + tmp = lse->expr; class_han = GFC
[gcc r13-8897] Fortran: Unlimited polymorphic intrinsic function arguments [PR84006]
https://gcc.gnu.org/g:b1429ddd7f20a5c88b65d8de38d64c98c4820782 commit r13-8897-gb1429ddd7f20a5c88b65d8de38d64c98c4820782 Author: Paul Thomas Date: Sun May 12 06:59:45 2024 +0100 Fortran: Unlimited polymorphic intrinsic function arguments [PR84006] 2024-05-12 Paul Thomas gcc/fortran PR fortran/84006 PR fortran/100027 PR fortran/98534 * iresolve.cc (gfc_resolve_transfer): Emit a TODO error for unlimited polymorphic mold. * trans-expr.cc (gfc_resize_class_size_with_len): Use the fold even if a block is not available in which to fix the result. (trans_class_assignment): Enable correct assignment of character expressions to unlimited polymorphic variables using lhs _len field and rse string_length. * trans-intrinsic.cc (gfc_conv_intrinsic_storage_size): Extract the class expression so that the unlimited polymorphic class expression can be used in gfc_resize_class_size_with_len to obtain the storage size for character payloads. Guard the use of GFC_DECL_SAVED_DESCRIPTOR by testing for DECL_LANG_SPECIFIC to prevent the ICE. Also, invert the order to use the class expression extracted from the argument. (gfc_conv_intrinsic_transfer): In same way as 'storage_size', use the _len field to obtaining the correct length for arg 1. Add a branch for the element size in bytes of class expressions with provision to make use of the unlimited polymorphic _len field. Again, the class references are explicitly identified. 'mold_expr' was already declared. Use it instead of 'arg'. Do not fix 'dest_word_len' for deferred character sources because reallocation on assign makes use of it before it is assigned. gcc/testsuite/ PR fortran/84006 PR fortran/100027 * gfortran.dg/storage_size_7.f90: New test. PR fortran/98534 * gfortran.dg/transfer_class_4.f90: New test. (cherry picked from commit b9294757f82aae8de6d98c122cd4e3b98f685217) Diff: --- gcc/fortran/iresolve.cc| 4 ++ gcc/fortran/trans-expr.cc | 15 - gcc/fortran/trans-intrinsic.cc | 80 +- gcc/testsuite/gfortran.dg/storage_size_7.f90 | 91 ++ gcc/testsuite/gfortran.dg/transfer_class_4.f90 | 87 5 files changed, 257 insertions(+), 20 deletions(-) diff --git a/gcc/fortran/iresolve.cc b/gcc/fortran/iresolve.cc index 8acad60a02be..108c9a35949d 100644 --- a/gcc/fortran/iresolve.cc +++ b/gcc/fortran/iresolve.cc @@ -3017,6 +3017,10 @@ gfc_resolve_transfer (gfc_expr *f, gfc_expr *source ATTRIBUTE_UNUSED, } } + if (UNLIMITED_POLY (mold)) +gfc_error ("TODO: unlimited polymorphic MOLD in TRANSFER intrinsic at %L", + &mold->where); + f->ts = mold->ts; if (size == NULL && mold->rank == 0) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 5946aa813917..6b75c147a350 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -317,6 +317,8 @@ gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size) size = gfc_evaluate_now (size, block); tmp = gfc_evaluate_now (fold_convert (type , tmp), block); } + else + tmp = fold_convert (type , tmp); tmp2 = fold_build2_loc (input_location, MULT_EXPR, type, size, tmp); tmp = fold_build2_loc (input_location, GT_EXPR, @@ -11671,15 +11673,24 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs, /* Take into account _len of unlimited polymorphic entities. TODO: handle class(*) allocatable function results on rhs. */ - if (UNLIMITED_POLY (rhs) && rhs->expr_type == EXPR_VARIABLE) + if (UNLIMITED_POLY (rhs)) { - tree len = trans_get_upoly_len (block, rhs); + tree len; + if (rhs->expr_type == EXPR_VARIABLE) + len = trans_get_upoly_len (block, rhs); + else + len = gfc_class_len_get (tmp); len = fold_build2_loc (input_location, MAX_EXPR, size_type_node, fold_convert (size_type_node, len), size_one_node); size = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (size), size, fold_convert (TREE_TYPE (size), len)); } + else if (rhs->ts.type == BT_CHARACTER && rse->string_length) + size = fold_build2_loc (input_location, MULT_EXPR, + gfc_charlen_type_node, size, + rse->string_length); + tmp = lse->expr; class_han = GFC_