aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '13.2.0/gentoo/77_all_all_PR109609_13_tail-call-fnspec.patch')
-rw-r--r--13.2.0/gentoo/77_all_all_PR109609_13_tail-call-fnspec.patch105
1 files changed, 105 insertions, 0 deletions
diff --git a/13.2.0/gentoo/77_all_all_PR109609_13_tail-call-fnspec.patch b/13.2.0/gentoo/77_all_all_PR109609_13_tail-call-fnspec.patch
new file mode 100644
index 0000000..9871b81
--- /dev/null
+++ b/13.2.0/gentoo/77_all_all_PR109609_13_tail-call-fnspec.patch
@@ -0,0 +1,105 @@
+https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=df49e4602882eabe0642699fb71a70f6e120e263
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109609
+
+From df49e4602882eabe0642699fb71a70f6e120e263 Mon Sep 17 00:00:00 2001
+From: Richard Biener <rguenther@suse.de>
+Date: Tue, 25 Apr 2023 14:56:44 +0200
+Subject: [PATCH] tree-optimization/109609 - correctly interpret arg size in
+ fnspec
+
+By majority vote and a hint from the API name which is
+arg_max_access_size_given_by_arg_p this interprets a memory access
+size specified as given as other argument such as for strncpy
+in the testcase which has "1cO313" as specifying the _maximum_
+size read/written rather than the exact size. There are two
+uses interpreting it that way already and one differing. The
+following adjusts the differing and clarifies the documentation.
+
+ PR tree-optimization/109609
+ * attr-fnspec.h (arg_max_access_size_given_by_arg_p):
+ Clarify semantics.
+ * tree-ssa-alias.cc (check_fnspec): Correctly interpret
+ the size given by arg_max_access_size_given_by_arg_p as
+ maximum, not exact, size.
+
+ * gcc.dg/torture/pr109609.c: New testcase.
+
+(cherry picked from commit e8d00353017f895d03a9eabae3506fd126ce1a2d)
+--- a/gcc/attr-fnspec.h
++++ b/gcc/attr-fnspec.h
+@@ -54,7 +54,7 @@
+ ' ' nothing is known
+ 't' the size of value written/read corresponds to the size of
+ of the pointed-to type of the argument type
+- '1'...'9' specifies the size of value written/read is given by the
++ '1'...'9' specifies the size of value written/read is bound by the
+ specified argument
+ */
+
+@@ -169,7 +169,7 @@ public:
+ && str[idx] != 'x' && str[idx] != 'X';
+ }
+
+- /* Return true if load of memory pointed to by argument I is specified
++ /* Return true if load of memory pointed to by argument I is bound
+ by another argument. In this case set ARG. */
+ bool
+ arg_max_access_size_given_by_arg_p (unsigned int i, unsigned int *arg)
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/torture/pr109609.c
+@@ -0,0 +1,26 @@
++/* { dg-do run } */
++
++#define N 23
++#define MAX_LEN 13
++char dst[N + 1];
++
++void __attribute__((noipa))
++invert(const char *id)
++{
++ char buf[MAX_LEN];
++ char *ptr = buf + sizeof(buf); // start from the end of buf
++ *(--ptr) = '\0'; // terminate string
++ while (*id && ptr > buf) {
++ *(--ptr) = *(id++); // copy id backwards
++ }
++ __builtin_strncpy(dst, ptr, N); // copy ptr/buf to dst
++}
++
++
++int main()
++{
++ invert("abcde");
++ if (__builtin_strcmp(dst, "edcba"))
++ __builtin_abort();
++ return 0;
++}
+--- a/gcc/tree-ssa-alias.cc
++++ b/gcc/tree-ssa-alias.cc
+@@ -2726,9 +2726,21 @@ check_fnspec (gcall *call, ao_ref *ref, bool clobber)
+ t = TREE_CHAIN (t);
+ size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_VALUE (t)));
+ }
+- ao_ref_init_from_ptr_and_size (&dref,
+- gimple_call_arg (call, i),
+- size);
++ poly_int64 size_hwi;
++ if (size
++ && poly_int_tree_p (size, &size_hwi)
++ && coeffs_in_range_p (size_hwi, 0,
++ HOST_WIDE_INT_MAX / BITS_PER_UNIT))
++ {
++ size_hwi = size_hwi * BITS_PER_UNIT;
++ ao_ref_init_from_ptr_and_range (&dref,
++ gimple_call_arg (call, i),
++ true, 0, -1, size_hwi);
++ }
++ else
++ ao_ref_init_from_ptr_and_range (&dref,
++ gimple_call_arg (call, i),
++ false, 0, -1, -1);
+ if (refs_may_alias_p_1 (&dref, ref, false))
+ return 1;
+ }
+--
+2.31.1