Make nowrap_type_p honor -fwrapv-pointer
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap |
success
|
Build passed
|
Commit Message
nowrap_type_p guards several transforms in IVOPTs and niter
analysis but it incorrectly considers POINTER_TYPE_P as always
not wrapping.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
* tree-ssa-loop-niter.cc (nowrap_type_p): Honor
-fwrapv-pointer.
* gcc.dg/torture/pr113703-3.c: New test.
* gcc.dg/torture/pr113703-4.c: Likewise.
---
gcc/testsuite/gcc.dg/torture/pr113703-3.c | 34 +++++++++++++++++++++++
gcc/testsuite/gcc.dg/torture/pr113703-4.c | 32 +++++++++++++++++++++
gcc/tree-ssa-loop-niter.cc | 5 +---
3 files changed, 67 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr113703-3.c
create mode 100644 gcc/testsuite/gcc.dg/torture/pr113703-4.c
new file mode 100644
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fwrapv-pointer -fno-tree-vectorize -fno-tree-loop-distribute-patterns" } */
+
+#include <stdint.h>
+
+uintptr_t sum = 0;
+
+__attribute__((noipa)) void
+f (char *p, unsigned int i, unsigned int n)
+{
+ p -= i;
+ do
+ {
+ sum += (uintptr_t)p;
+ p -= 1;
+ i++;
+ }
+ while (i < n);
+}
+
+int
+main ()
+{
+ /* I is 2 and N is 8, so the loop iterates 6 times and P walks past the
+ start of the address space, which is well defined here. Its values
+ are therefore not ordered like those of I and the counter cannot be
+ eliminated in favour of it, but IVOPTs used to do it nevertheless and
+ the loop exited at the first test. */
+ f ((char *)4, 2, 8);
+ /* SUM is 2 + 1 + 0 - 1 - 2 - 3. */
+ if (sum != (uintptr_t)-3)
+ __builtin_abort ();
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fwrapv-pointer -fno-tree-vectorize -fno-tree-loop-distribute-patterns" } */
+
+#include <stdint.h>
+
+uintptr_t sum = 0;
+
+__attribute__((noipa)) void
+f (char *p, unsigned int i, unsigned int n)
+{
+ p += i;
+ do
+ {
+ sum += (uintptr_t)p;
+ p += 1;
+ i++;
+ }
+ while (i < n);
+}
+
+int
+main ()
+{
+ /* Mirror image of gcc.dg/torture/ivopts-lt-3.c with an increasing pointer:
+ the loop iterates 6 times and P walks past the end of the address space
+ instead of its start. */
+ f ((char *)-4, 2, 8);
+ /* SUM is -2 - 1 + 0 + 1 + 2 + 3. */
+ if (sum != 3)
+ __builtin_abort ();
+ return 0;
+}
@@ -5347,13 +5347,10 @@ n_of_executions_at_most (gimple *stmt,
bool
nowrap_type_p (tree type)
{
- if (ANY_INTEGRAL_TYPE_P (type)
+ if ((ANY_INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
&& TYPE_OVERFLOW_UNDEFINED (type))
return true;
- if (POINTER_TYPE_P (type))
- return true;
-
return false;
}