]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ifcvt: Fix factor_out_operators for BIT_FIELD_REF and BIT_INSERT_EXPR [PR122629]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Mon, 10 Nov 2025 20:22:28 +0000 (12:22 -0800)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Tue, 11 Nov 2025 07:31:17 +0000 (23:31 -0800)
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 <andrew.pinski@oss.qualcomm.com>
gcc/testsuite/gcc.dg/torture/pr122629-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr122629-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr122629-1.c [new file with mode: 0644]
gcc/tree-if-conv.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr122629-1.c b/gcc/testsuite/gcc.dg/torture/pr122629-1.c
new file mode 100644 (file)
index 0000000..47936e7
--- /dev/null
@@ -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 (file)
index 0000000..1ade7b9
--- /dev/null
@@ -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 (file)
index 0000000..a80d4a1
--- /dev/null
@@ -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" } } */
index 0bb3de9b13762d0424456616d18f56427d2fd1f4..bb30c4fb35facf3289a7239af0d39d2d1b8e47c6 100644 (file)
@@ -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);