1 |
commit: 9b342fdeb8588681bb106e072cefd481a045fb21 |
2 |
Author: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Dec 1 19:16:33 2020 +0000 |
4 |
Commit: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Dec 1 19:16:33 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=9b342fde |
7 |
|
8 |
10.2.0: backport strncmp() folding |
9 |
|
10 |
Reported-by: Matt Whitlock |
11 |
Bug: https://bugs.gentoo.org/757792 |
12 |
Bug: https://gcc.gnu.org/PR96758 |
13 |
Signed-off-by: Sergei Trofimovich <slyfox <AT> gentoo.org> |
14 |
|
15 |
10.2.0/gentoo/41_all_strlen-PR96758.patch | 95 +++++++++++++++++++++++++++++++ |
16 |
10.2.0/gentoo/README.history | 3 + |
17 |
2 files changed, 98 insertions(+) |
18 |
|
19 |
diff --git a/10.2.0/gentoo/41_all_strlen-PR96758.patch b/10.2.0/gentoo/41_all_strlen-PR96758.patch |
20 |
new file mode 100644 |
21 |
index 0000000..fccf2de |
22 |
--- /dev/null |
23 |
+++ b/10.2.0/gentoo/41_all_strlen-PR96758.patch |
24 |
@@ -0,0 +1,95 @@ |
25 |
+https://bugs.gentoo.org/757792 |
26 |
+ |
27 |
+From 0dbfa88edafbe913a7a9099246041e0190aa3948 Mon Sep 17 00:00:00 2001 |
28 |
+From: Jakub Jelinek <jakub@××××××.com> |
29 |
+Date: Tue, 25 Aug 2020 13:47:10 +0200 |
30 |
+Subject: [PATCH] strlen: Fix handle_builtin_string_cmp [PR96758] |
31 |
+ |
32 |
+The following testcase is miscompiled, because handle_builtin_string_cmp |
33 |
+sees a strncmp call with constant last argument 4, where one of the strings |
34 |
+has an upper bound of 5 bytes (due to it being an array of that size) and |
35 |
+the other has a known string length of 1 and the result is used only in |
36 |
+equality comparison. |
37 |
+It is folded into __builtin_strncmp_eq (str1, str2, 4), which is |
38 |
+incorrect, because that means reading 4 bytes from both strings and |
39 |
+comparing that. When one of the strings has known strlen of 1, we want to |
40 |
+compare just 2 bytes, not 4, as strncmp shouldn't compare any bytes beyond |
41 |
+the null. |
42 |
+So, the last argument to __builtin_strncmp_eq should be the minimum of the |
43 |
+provided strncmp last argument and the known string length + 1 (assuming |
44 |
+the other string has only a known upper bound due to array size). |
45 |
+ |
46 |
+Besides that, I've noticed the code has been written with the intent to also |
47 |
+support the case where we know exact string length of both strings (but not |
48 |
+the string content, so we can't compute it at compile time). In that case, |
49 |
+both cstlen1 and cstlen2 are non-negative and both arysiz1 and arysiz2 are |
50 |
+negative. We wouldn't optimize that, cmpsiz would be either the strncmp |
51 |
+last argument, or for strcmp the first string length, but varsiz would be |
52 |
+-1 and thus cmpsiz would be never < varsiz. The patch fixes it by using the |
53 |
+correct length, in that case using the minimum of the two and for strncmp |
54 |
+also the last argument. |
55 |
+ |
56 |
+2020-08-25 Jakub Jelinek <jakub@××××××.com> |
57 |
+ |
58 |
+ PR tree-optimization/96758 |
59 |
+ * tree-ssa-strlen.c (handle_builtin_string_cmp): If both cstlen1 |
60 |
+ and cstlen2 are set, set cmpsiz to their minimum, otherwise use the |
61 |
+ one that is set. If bound is used and smaller than cmpsiz, set cmpsiz |
62 |
+ to bound. If both cstlen1 and cstlen2 are set, perform the optimization. |
63 |
+ |
64 |
+ * gcc.dg/strcmpopt_12.c: New test. |
65 |
+ |
66 |
+(cherry picked from commit f982a6ec9b6d98f5f37114b1d7455c54ce5056b8) |
67 |
+--- |
68 |
+ gcc/testsuite/gcc.dg/strcmpopt_12.c | 17 +++++++++++++++++ |
69 |
+ gcc/tree-ssa-strlen.c | 10 +++++++++- |
70 |
+ 2 files changed, 26 insertions(+), 1 deletion(-) |
71 |
+ create mode 100644 gcc/testsuite/gcc.dg/strcmpopt_12.c |
72 |
+ |
73 |
+diff --git a/gcc/testsuite/gcc.dg/strcmpopt_12.c b/gcc/testsuite/gcc.dg/strcmpopt_12.c |
74 |
+new file mode 100644 |
75 |
+index 00000000000..d8077b62f7f |
76 |
+--- /dev/null |
77 |
++++ b/gcc/testsuite/gcc.dg/strcmpopt_12.c |
78 |
+@@ -0,0 +1,17 @@ |
79 |
++/* PR tree-optimization/96758 */ |
80 |
++/* { dg-do run } */ |
81 |
++/* { dg-options "-O2" } */ |
82 |
++ |
83 |
++int v = 1; |
84 |
++ |
85 |
++int |
86 |
++main () |
87 |
++{ |
88 |
++ const char *s = v ? "a" : "b"; |
89 |
++ char x[5]; |
90 |
++ char y[5] = "a\0a"; |
91 |
++ __builtin_memcpy (x, y, sizeof (y)); |
92 |
++ if (__builtin_strncmp (x, s, 4) != 0) |
93 |
++ __builtin_abort (); |
94 |
++ return 0; |
95 |
++} |
96 |
+diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c |
97 |
+index 93d095e1896..b0874da5d1e 100644 |
98 |
+--- a/gcc/tree-ssa-strlen.c |
99 |
++++ b/gcc/tree-ssa-strlen.c |
100 |
+@@ -4485,7 +4485,15 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi, const vr_values *rvals) |
101 |
+ ++cstlen2; |
102 |
+ |
103 |
+ /* The exact number of characters to compare. */ |
104 |
+- HOST_WIDE_INT cmpsiz = bound < 0 ? cstlen1 < 0 ? cstlen2 : cstlen1 : bound; |
105 |
++ HOST_WIDE_INT cmpsiz; |
106 |
++ if (cstlen1 >= 0 && cstlen2 >= 0) |
107 |
++ cmpsiz = MIN (cstlen1, cstlen2); |
108 |
++ else if (cstlen1 >= 0) |
109 |
++ cmpsiz = cstlen1; |
110 |
++ else |
111 |
++ cmpsiz = cstlen2; |
112 |
++ if (bound >= 0) |
113 |
++ cmpsiz = MIN (cmpsiz, bound); |
114 |
+ /* The size of the array in which the unknown string is stored. */ |
115 |
+ HOST_WIDE_INT varsiz = arysiz1 < 0 ? arysiz2 : arysiz1; |
116 |
+ |
117 |
+-- |
118 |
+2.29.2 |
119 |
+ |
120 |
|
121 |
diff --git a/10.2.0/gentoo/README.history b/10.2.0/gentoo/README.history |
122 |
index e0207e7..8b8c475 100644 |
123 |
--- a/10.2.0/gentoo/README.history |
124 |
+++ b/10.2.0/gentoo/README.history |
125 |
@@ -1,3 +1,6 @@ |
126 |
+5 TODO |
127 |
+ + 41_all_strlen-PR96758.patch |
128 |
+ |
129 |
4 04 Nov 2020 |
130 |
+ 40_all_ipa-to_frequency.patch |