https://gcc.gnu.org/g:cadbc011b9cf61738b3bbf409a285689c91d2223
commit r16-5147-gcadbc011b9cf61738b3bbf409a285689c91d2223 Author: Andrew Pinski <[email protected]> Date: Mon Nov 10 12:22:28 2025 -0800 ifcvt: Fix factor_out_operators for BIT_FIELD_REF and BIT_INSERT_EXPR [PR122629] 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]> Diff: --- 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(+) 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 000000000000..47936e7896e6 --- /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 000000000000..1ade7b9f7421 --- /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 000000000000..a80d4a1990b1 --- /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 0bb3de9b1376..bb30c4fb35fa 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);
