So factor_out_operators will factor out some expressions but in the case
of BIT_FIELD_REF and BIT_INSERT_EXPR, this only allowed for operand 0 as the
other operands need to be constant.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/122629

gcc/ChangeLog:

        * tree-if-conv.cc (factor_out_operators): Reject
        BIT_FIELD_REF and BIT_INSERT_EXPR if operand other
        than 0 is different.

gcc/testsuite/ChangeLog:

        * gcc.dg/torture/pr122629-1.c: New test.
        * gcc.dg/torture/pr122629-2.c: New test.
        * gcc.dg/tree-ssa/pr122629-1.c: New test.

Signed-off-by: Andrew Pinski <[email protected]>
---
 gcc/testsuite/gcc.dg/torture/pr122629-1.c  | 28 +++++++++++++++++
 gcc/testsuite/gcc.dg/torture/pr122629-2.c  | 32 +++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr122629-1.c | 36 ++++++++++++++++++++++
 gcc/tree-if-conv.cc                        |  8 +++++
 4 files changed, 104 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr122629-1.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr122629-2.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr122629-1.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr122629-1.c 
b/gcc/testsuite/gcc.dg/torture/pr122629-1.c
new file mode 100644
index 00000000000..47936e7896e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr122629-1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* PR tree-optimization/122629 */
+
+/* factor_out_operators was factoring out BIT_FIELD_REF and BIT_INSERT_EXPR,
+   both which requires constant operands so it would not valid to factor.  */
+
+typedef int ix4 __attribute__((vector_size(4*sizeof(int))));
+
+int f(ix4 *a, int l, int *b)
+{
+  for (int i =0 ;i < l; i++)
+  {
+    int t;
+    ix4 tt = a[i];
+    if(*b) t = tt[1]; else t = tt[0];
+    *b = t;
+  }
+}
+
+int g(ix4 *a, int l, int *b)
+{
+  for (int i =0 ;i < l; i++)
+  {
+    ix4 tt = a[i];
+    if(*b) tt[1] = 1; else tt[0] = 1;
+    *a = tt;
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr122629-2.c 
b/gcc/testsuite/gcc.dg/torture/pr122629-2.c
new file mode 100644
index 00000000000..1ade7b9f742
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr122629-2.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* PR tree-optimization/122629 */
+
+typedef int ix4 __attribute__((vector_size(4*sizeof(int))));
+
+int f(ix4 *a, int l, int *b, ix4 *c)
+{
+  for (int i =0 ;i < l; i++)
+  {
+    int t;
+    ix4 tt = a[i];
+    ix4 tt1 = c[i];
+    if(*b) t = tt1[0]; else t = tt[0];
+    *b = t;
+  }
+}
+
+int g(ix4 *a, int l, int *b, ix4 *c)
+{
+  for (int i =0 ;i < l; i++)
+  {
+    ix4 tt = a[i];
+    ix4 tt1 = c[i];
+    if(*b) {
+        tt = tt1;
+        tt[0] = 1;
+    } else {
+      tt[0] = 1;
+    }
+    a[i] = tt;
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr122629-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr122629-1.c
new file mode 100644
index 00000000000..a80d4a1990b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr122629-1.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcvt-details" } */
+/* PR tree-optimization/122629 */
+
+typedef int ix4 __attribute__((vector_size(4*sizeof(int))));
+
+int f(ix4 *a, int l, int *b, ix4 *c)
+{
+  for (int i =0 ;i < l; i++)
+  {
+    int t;
+    ix4 tt = a[i];
+    ix4 tt1 = c[i];
+    if(*b) t = tt1[0]; else t = tt[0];
+    *b = t;
+  }
+}
+
+int g(ix4 *a, int l, int *b, ix4 *c)
+{
+  for (int i =0 ;i < l; i++)
+  {
+    ix4 tt = a[i];
+    ix4 tt1 = c[i];
+    if(*b) {
+        tt = tt1;
+        tt[0] = 1;
+    } else {
+      tt[0] = 1;
+    }
+    a[i] = tt;
+  }
+}
+
+/* Make sure BIT_INSERT_EXPR/BIT_FIELD_REF is still factored out for the case 
if operand 0 is different. */
+/* { dg-final { scan-tree-dump-times "changed to factor operation out from" 2 
"ifcvt" } } */
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index 0bb3de9b137..bb30c4fb35f 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -2245,6 +2245,14 @@ again:
   if (opnum == -1)
     return;
 
+  /* BIT_FIELD_REF and BIT_INSERT_EXPR can't be factored out for non-0 operands
+     as the other operands require constants. */
+  if ((arg1_op.code == BIT_FIELD_REF
+       || arg1_op.code == BIT_INSERT_EXPR)
+      && opnum != 0)
+    return;
+
+
   if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1)))
     return;
   tree new_res = make_ssa_name (TREE_TYPE (new_arg0), NULL);
-- 
2.43.0

Reply via email to