[PATCH 2/2] phiopt: Fix up factoring out loads for REF_REVERSE_STORAGE_ORDER [PR126729]

Andrea Pinski <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
REF_REVERSE_STORAGE_ORDER is forgotten about when factor_out_conditional_load
was written up so if REF_REVERSE_STORAGE_ORDER was set, it would be lost.
If REF_REVERSE_STORAGE_ORDER was mismatched then it would mess up too.
This fixes that oversight.

Bootstrapped and tested on x86_64-linux-gnu.

	PR tree-optimization/126729

gcc/ChangeLog:

	* tree-ssa-phiopt.cc (factor_out_conditional_load): Handle
	REF_REVERSE_STORAGE_ORDER being set correctly.

gcc/testsuite/ChangeLog:

	* gcc.dg/sso/factor_load-1.c: New test.

Signed-off-by: Andrea Pinski <[email protected]>
---
 gcc/testsuite/gcc.dg/sso/factor_load-1.c | 61 ++++++++++++++++++++++++
 gcc/tree-ssa-phiopt.cc                   | 14 +++++-
 2 files changed, 73 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/sso/factor_load-1.c

diff --git a/gcc/testsuite/gcc.dg/sso/factor_load-1.c b/gcc/testsuite/gcc.dg/sso/factor_load-1.c
new file mode 100644
index 00000000000..f5db8b44fba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sso/factor_load-1.c
@@ -0,0 +1,61 @@
+/* PR tree-optimization/126729 */
+/* { dg-do run } */
+
+struct S0 { int a; int v; } __attribute__((scalar_storage_order("little-endian")));
+union U0 { struct S0 s; int i[2]; } __attribute__((scalar_storage_order("little-endian")));
+struct S1 { int a; int v; } __attribute__((scalar_storage_order("big-endian")));
+union U1 { struct S1 s; int i[2]; } __attribute__((scalar_storage_order("big-endian")));
+
+
+__attribute__((noinline))
+int f(void *a, bool b, bool bb)
+{
+  if (b)
+  {
+    union U0 t = *((union U0*)a);
+    if (bb)
+      return t.i[0];
+    return t.s.a;
+  }
+  {
+    union U1 t = *((union U1*)a);
+    if (bb)
+      return t.i[0];
+    return t.s.a;
+  }
+}
+
+__attribute__((noinline))
+int f2(void *a, bool b, bool bb)
+{
+  if (b)
+  {
+    union U1 t = *((union U1*)a);
+    if (bb)
+      return t.i[0];
+    return t.s.a;
+  }
+  {
+    union U1 t = *((union U1*)a);
+    if (bb)
+      return t.i[0];
+    return t.s.a;
+  }
+}
+
+int main()
+{
+  union U1 a;
+  union U0 b;
+  int t = 0xabcd;
+  a.s.a = t;
+  b.s.a = t;
+  if (f((void*)&a, 0, 0) != t)
+    __builtin_abort();
+  if (f((void*)&b, 1, 0) != t)
+    __builtin_abort();
+  if (f2((void*)&a, 1, 0) != t)
+    __builtin_abort();
+  if (f2((void*)&a, 0, 0) != t)
+    __builtin_abort();
+}
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 129a25abffb..784221c83b3 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -4177,11 +4177,14 @@ factor_out_conditional_load (edge e0, edge e1, basic_block merge, gphi *phi,
   tree index = nullptr;
   tree step = nullptr;
   tree index2 = nullptr;
+  bool rev_order = false;
 
   /* Both must be *P loads of a compatible value type.  The
      TBAA alias-ptr type carried by MEM_REF operand 1 need not match; it is
      merged the way get_alias_type_for_stmts does when the load is built.  */
-  if (TREE_CODE (ref0) != MEM_REF)
+  if (TREE_CODE (ref0) == MEM_REF)
+    rev_order = REF_REVERSE_STORAGE_ORDER (ref0);
+  else
     {
       if (TREE_CODE (ref0) != TARGET_MEM_REF)
 	return false;
@@ -4193,11 +4196,15 @@ factor_out_conditional_load (edge e0, edge e1, basic_block merge, gphi *phi,
     {
       if (index || step || index2)
 	return false;
+      if (rev_order != REF_REVERSE_STORAGE_ORDER (ref1))
+	return false;
     }
   else
     {
       if (TREE_CODE (ref1) != TARGET_MEM_REF)
 	return false;
+      if (rev_order)
+	return false;
       if (!safe_operand_equal_p (index, TMR_INDEX (ref1)))
 	return false;
       if (!safe_operand_equal_p (step, TMR_STEP (ref1)))
@@ -4335,7 +4342,10 @@ factor_out_conditional_load (edge e0, edge e1, basic_block merge, gphi *phi,
     nref = build5 (TARGET_MEM_REF, TREE_TYPE (ref0), newptr,
 		   newindex, index, step, index2);
   else
-    nref = build2 (MEM_REF, TREE_TYPE (ref0), newptr, newindex);
+    {
+      nref = build2 (MEM_REF, TREE_TYPE (ref0), newptr, newindex);
+      REF_REVERSE_STORAGE_ORDER (nref) = rev_order;
+    }
   MR_DEPENDENCE_CLIQUE (nref) = clique;
   MR_DEPENDENCE_BASE (nref) = base;
   tree res = gimple_phi_result (phi);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.