--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options { -fdump-tree-ifcvt-all } } */
+
+static void __attribute__((noipa)) f(int n) {
+ int i, j;
+ struct S { char d[n]; int a; int b : 17; int c : 12; };
+ struct S A[100][1111];
+ for (i = 0; i < 100; i++) {
+ asm volatile("" : : "g"(&A[0][0]) : "memory");
+ for (j = 0; j < 1111; j++) A[i][j].b = 2;
+ }
+}
+void g(void) { f(1); }
+
+/* { dg-final { scan-tree-dump-not "Bitfield OK to lower" "ifcvt" } } */
: gimple_assign_rhs1 (stmt);
tree field_decl = TREE_OPERAND (comp_ref, 1);
+ tree ref_offset = component_ref_field_offset (comp_ref);
tree rep_decl = DECL_BIT_FIELD_REPRESENTATIVE (field_decl);
/* Bail out if the representative is not a suitable type for a scalar
if (compare_tree_int (DECL_SIZE (field_decl), bf_prec) != 0)
return NULL_TREE;
+ if (TREE_CODE (DECL_FIELD_OFFSET (rep_decl)) != INTEGER_CST
+ || TREE_CODE (ref_offset) != INTEGER_CST)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\t Bitfield NOT OK to lower,"
+ " offset is non-constant.\n");
+ return NULL_TREE;
+ }
+
if (struct_expr)
*struct_expr = TREE_OPERAND (comp_ref, 0);
the structure and the container from the number of bits from the start
of the structure and the actual bitfield member. */
tree bf_pos = fold_build2 (MULT_EXPR, bitsizetype,
- DECL_FIELD_OFFSET (field_decl),
+ ref_offset,
build_int_cst (bitsizetype, BITS_PER_UNIT));
bf_pos = fold_build2 (PLUS_EXPR, bitsizetype, bf_pos,
DECL_FIELD_BIT_OFFSET (field_decl));