This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/54031] [4.8 Regression] Revision 189607 miscompiles Linux kernel
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 20 Jul 2012 09:27:48 +0000
- Subject: [Bug tree-optimization/54031] [4.8 Regression] Revision 189607 miscompiles Linux kernel
- Auto-submitted: auto-generated
- References: <bug-54031-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54031
--- Comment #7 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-07-20 09:27:48 UTC ---
There are several issues in CCP exposed. First, we compute
bit_value_binop_1 (NE_EXPR, ...,
{low = 0x38, high = 0x0}, {low = 0xffffffffffffffc0, high = 0x0},
{low = 0x0, high = 0x0}, {low = 0xfffffffffffffff0, high = 0x0})
as false because in
D.16870_8 = &tmp_3->list;
if (D.16870_8 != &clocksource_list)
we see that clocksource_list is aligned to 128 and &tmp_3->list refers
to the type clocksource via tmp_3 which has a user alignment of 512,
so the resulting pointer is misaligned by 448 bits (the offset of the
list member). That makes the equality test never true unless the
types involved do not have their specified alignment.
Which makes this an invalid source. I didn't investigate in detail
but certainly the code uses the aligned type for pointers that are
not suitably aligned.
Now, we didn't want to extract this elaborated alignment information
from addresses (only from actual accesses), which is the real bug fixed
as follows:
Index: gcc/tree-ssa-ccp.c
===================================================================
--- gcc/tree-ssa-ccp.c (revision 189704)
+++ gcc/tree-ssa-ccp.c (working copy)
@@ -510,7 +510,7 @@ get_value_from_alignment (tree expr)
gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
- get_object_alignment_1 (TREE_OPERAND (expr, 0), &align, &bitpos);
+ get_pointer_alignment_1 (expr, &align, &bitpos);
val.mask
= double_int_and_not (POINTER_TYPE_P (type) || TYPE_UNSIGNED (type)
? double_int_mask (TYPE_PRECISION (type))