[PATCH, PR 43164, PR 43191] Do not scalarize structures with zero-size bit-fields as their last field
Martin Jambor
mjambor@suse.cz
Thu Mar 4 11:23:00 GMT 2010
Hi,
the patch below fixes both PR 43164 and PR 43191, which are both
caused by a zero-sized bit-field at the end of a record. The
solution is rather crude, I simply disabled total scalarization
(attempts to turn all scalar components into separate variables so
that the original aggregate disappears) of aggregates containing such
things which means - this is the only way of how accesses to such
fields get created.
I have tried not doing this and change build_ref_for_offset so that it
could cope with them but this would have to involve trying (usually in
vain) to look into sub-records preceeding the one into which one would
normally look, doing the same thing even in arrays of records while
being careful not to get out-of bounds and who knows what else. These
weird zero-sized bit-fields simply violate too many properties that
normal fields have and make build_ref_for_offset overly complicated
and not for too much gain, I assume. Therefore I have given this up
and will attempt it again only if I am persuaded it is a good idea.
Bootstrapped and tested on x86_64-linux. OK for trunk?
Thanks,
Martin
2010-03-03 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/43164
PR tree-optimization/43191
* tree-sra.c (type_consists_of_records_p): Reject records with
zero-size bit-fields at the end.
* testsuite/gcc.c-torture/compile/pr43164.c: New test.
* testsuite/gcc.c-torture/compile/pr43191.c: Likewise.
Index: mine/gcc/testsuite/gcc.c-torture/compile/pr43164.c
===================================================================
--- /dev/null
+++ mine/gcc/testsuite/gcc.c-torture/compile/pr43164.c
@@ -0,0 +1,16 @@
+struct S0
+{
+ unsigned char f0;
+ int:0;
+};
+
+struct S1
+{
+ struct S0 f0;
+};
+
+struct S1 func_34 (void)
+{
+ struct S1 l_221 = { { 1 } };
+ return l_221;
+}
Index: mine/gcc/testsuite/gcc.c-torture/compile/pr43191.c
===================================================================
--- /dev/null
+++ mine/gcc/testsuite/gcc.c-torture/compile/pr43191.c
@@ -0,0 +1,46 @@
+struct S0
+{
+};
+
+struct S1
+{
+ unsigned f0:27;
+ const unsigned:0;
+};
+
+struct S2
+{
+ unsigned f2:1;
+};
+
+unsigned char g_4[1][8][3][1][1][1];
+unsigned char *g_17;
+unsigned char **g_16[1][10][7];
+
+struct S2 g_35 = {
+ 0
+};
+
+struct S2 *g_34 = &g_35;
+
+struct S1 func_86 (unsigned char p_87, struct S2 **p_89)
+{
+ struct S1 l_92[6][8][1][1] = {
+ 16143586
+ }
+ ;
+ return l_92[0][0][0][0];
+}
+
+void func_28 (struct S1 p_30, const struct S1 p_32)
+{
+}
+
+void func_70 (unsigned char p_72)
+{
+ unsigned char *const *l_93 = &g_17;
+ struct S2 **l_94;
+ unsigned char *const *l_97 = &g_17;
+ func_28 (func_86 (p_72, 0),
+ func_86 (p_72, &g_34));
+}
Index: mine/gcc/tree-sra.c
===================================================================
--- mine.orig/gcc/tree-sra.c
+++ mine/gcc/tree-sra.c
@@ -802,13 +802,15 @@ create_access (tree expr, gimple stmt, b
/* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
- register types or (recursively) records with only these two kinds of
- fields. */
+ register types or (recursively) records with only these two kinds of fields.
+ It also returns false if any of these records has a zero-size field as its
+ last field. */
static bool
type_consists_of_records_p (tree type)
{
tree fld;
+ bool last_fld_has_zero_size = false;
if (TREE_CODE (type) != RECORD_TYPE)
return false;
@@ -821,7 +823,13 @@ type_consists_of_records_p (tree type)
if (!is_gimple_reg_type (ft)
&& !type_consists_of_records_p (ft))
return false;
+
+ last_fld_has_zero_size = tree_low_cst (DECL_SIZE (fld), 1) == 0;
}
+
+ if (last_fld_has_zero_size)
+ return false;
+
return true;
}
More information about the Gcc-patches
mailing list