[gcc(refs/vendors/ARM/heads/morello)] match.pd: Fix ICE caused by invalid transformation on capabilities

Alex Coplan acoplan@gcc.gnu.org
Mon Dec 11 13:15:10 GMT 2023


https://gcc.gnu.org/g:5d3776f5063baa2ddea94c595a4a8bf538016aea

commit 5d3776f5063baa2ddea94c595a4a8bf538016aea
Author: Alex Coplan <alex.coplan@arm.com>
Date:   Fri Dec 8 10:43:13 2023 +0000

    match.pd: Fix ICE caused by invalid transformation on capabilities
    
    With the testcase added in the patch, we make the following match.pd
    transformation:
    
      p + (long)q - (long)p --> q
    
    for p,q capabilities.  That is clearly wrong, as the resulting
    capability should be derived from p, regardless of the address value.
    
    This patch disables the offending match.pd pattern for capability types.
    We could instead fold this to .REPLACE_ADDRESS_VALUE (p, (long)q), but
    for now to keep things simple we just punt in this case.

Diff:
---
 gcc/match.pd                                       | 12 ++++++++---
 .../gcc.target/aarch64/morello/wrong-fold-2.c      | 25 ++++++++++++++++++++++
 .../gcc.target/aarch64/morello/wrong-fold.c        | 10 +++++++++
 3 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 734e19fab0a..eac281cf094 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1895,16 +1895,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      tem4 = (unsigned long) tem3;
      tem5 = ptr1 + tem4;
    and produce
-     tem5 = ptr2;  */
+     tem5 = ptr2;
+
+  N.B. this transformation isn't safe for capabilities, as we'd change
+  provenance from @0 to @1.  We could instead transform to
+  REPLACE_ADDRESS_VALUE (@0, (convert @1)), but for now we just punt
+  in the capability case.  */
 (simplify
   (pointer_plus @0 (convert?@2 (minus@3 (convert @1) (convert @0))))
   /* Conditionally look through a sign-changing conversion.  */
   (if (TYPE_PRECISION (TREE_TYPE (@2)) == TYPE_PRECISION (TREE_TYPE (@3))
+       && !capability_type_p (type)
        && ((GIMPLE && useless_type_conversion_p (type, TREE_TYPE (@1)))
 	    || (GENERIC && type == TREE_TYPE (@1))))
    @1))
-/* MORELLO Can not just convert @1 since we would then be using the metadata
-   from @1 rather than from @0.  */
+/* Likewise, we can't just convert @1 since we would then be using the
+   metadata from @1 rather than from @0.  */
 (simplify
   (pointer_plus @0 (convert?@2 (pointer_diff@3 @1 @@0)))
   (if (TYPE_PRECISION (TREE_TYPE (@2)) >= TYPE_PRECISION (TREE_TYPE (@3))
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/wrong-fold-2.c b/gcc/testsuite/gcc.target/aarch64/morello/wrong-fold-2.c
new file mode 100644
index 00000000000..0bd4c579481
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/wrong-fold-2.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-require-effective-target cheri_capability_pure } */
+
+/* This was ICEing at expand time due to a wrong match.pd transformation.
+
+   This test further adds an execution test that should fail if the
+   transformation were to fire.  */
+
+char *q;
+void f() {}
+
+__attribute__((noipa))
+void g()
+{
+  char *p = __builtin_cheri_offset_set(0, 2);
+  q = p + (long)f - (long)p;
+  q = __builtin_cheri_address_set(q, 0);
+}
+
+int main(void)
+{
+  g();
+  if (!__builtin_cheri_equal_exact (q, (char *)0))
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/wrong-fold.c b/gcc/testsuite/gcc.target/aarch64/morello/wrong-fold.c
new file mode 100644
index 00000000000..560f30c09b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/wrong-fold.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* This was ICEing at expand time due to a wrong match.pd transform.  */
+char * __capability q;
+void f();
+void g()
+{
+  char * __capability p = __builtin_cheri_offset_set(0, 2);
+  q = p + (long)f - (long)p;
+  q = __builtin_cheri_address_set(q, 0);
+}


More information about the Gcc-cvs mailing list