In some cases (different address space and/or function pointers) pointers are 
considered
non-compatible. This means creating a phi with non-compatible pointers will 
fail.
This takes the easy way out and rejecting this case. This could be refined to 
support
the only case where address spaces are different but that case will show up 
much less
than the address space being different so it is not worth the trouble right now.

Pushed as obvious after bootstrap/test on x86_64-linux-gnu.

        PR tree-optimization/126571

gcc/ChangeLog:

        * tree-ssa-phiopt.cc (factor_out_conditional_load): Reject
        when the pointer types are not compatible when creating a phi.

gcc/testsuite/ChangeLog:

        * gcc.dg/torture/pr126571-1.c: New test.
        * gcc.target/i386/pr126571-1.c: New test.

Signed-off-by: Andrea Pinski <[email protected]>
---
 gcc/testsuite/gcc.dg/torture/pr126571-1.c  | 14 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr126571-1.c | 16 ++++++++++++++++
 gcc/tree-ssa-phiopt.cc                     |  3 +++
 3 files changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr126571-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr126571-1.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr126571-1.c 
b/gcc/testsuite/gcc.dg/torture/pr126571-1.c
new file mode 100644
index 00000000000..573972d88ba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr126571-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* PR tree-optimization/126571 */
+typedef void (*FP) (void);
+
+int
+f (int c, FP fp, int *q)
+{
+  int r;
+  if (c)
+    r = *(int *) fp;
+  else
+    r = *q;
+  return r + 1;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126571-1.c 
b/gcc/testsuite/gcc.target/i386/pr126571-1.c
new file mode 100644
index 00000000000..7139a9a6f81
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126571-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* PR tree-optimization/126571 */
+
+typedef __seg_fs  int *type1;
+
+int
+f (int c, type1 fp, int *q)
+{
+  int r;
+  if (c)
+    r = *fp;
+  else
+    r = *q;
+  return r + 1;
+}
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index f6e407c0aad..2ff26bfab73 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -4287,6 +4287,9 @@ factor_out_conditional_load (edge e0, edge e1, 
basic_block merge, gphi *phi,
         FIXME: Refine to check ADDRESSABLE bit.  */
       if (TREE_CODE (p0) != SSA_NAME || TREE_CODE (p1) != SSA_NAME)
        return false;
+      // Incompatible address spaces or differnt function pointers could show 
up here.
+      if (!types_compatible_p (TREE_TYPE (p0), TREE_TYPE (p1)))
+       return false;
       /* Build P' = PHI <P, Q> and the single load result = *P'.  */
       newptr = make_ssa_name (TREE_TYPE (p0));
       gphi *pphi = create_phi_node (newptr, merge);
-- 
2.43.0

Reply via email to