This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH, middle-end: fix semantic bug in dse.c
- From: Ben Elliston <bje at au1 dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: sfr at canb dot auug dot org dot au
- Date: Wed, 06 May 2009 08:47:30 +1000
- Subject: PATCH, middle-end: fix semantic bug in dse.c
This bug (manifested as an ICE) was found when building an x86_64 Linux
kernel using a powerpc64-x-x86_64 cross-compiler.
The function all_positions_needed_p can receive a width argument of -1,
when check_mem_read_rtx is called on a BLKmode mem.
all_positions_needed_p calls lowpart_bitmask with a value of -1.
lowpart_bitmask does this:
return mask >> (HOST_BITS_PER_WIDE_INT - n);
We shift right by HOST_BITS_PER_WIDE_INT + 1, which relies on undefined
behaviour. On a native x86_64 configuration, this works by chance
(returning 0). On a powerpc64 cross x86_64 configuration, it does not,
because `anything & 0 == 0' is always true:
(gdb) p/x lowpart_bitmask (65) # x86_64 native
$214 = 0x1
(gdb) p/x lowpart_bitmask (65) # powerpc64-x-x86_64
$230 = 0x0
I believe this patch is the right fix. Tested with a bootstrap on
x86_64-linux (with BOOT_CFLAGS=-O2 and -Os), a regression test run on
x86_64-linux and powerpc64-linux, and a complete comparison of all Linux
kernel objects built with the cross compiler.
I have a regression test case which I will also commit if this patch is
okay. Okay for mainline?
2009-05-05 Ben Elliston <bje@au.ibm.com>
* dse.c (all_positions_needed_p): Return 0 when width == -1.
Index: dse.c
===================================================================
--- dse.c (revision 147137)
+++ dse.c (working copy)
@@ -1269,8 +1269,14 @@
}
else
{
- unsigned HOST_WIDE_INT mask = lowpart_bitmask (width) << start;
- return (s_info->positions_needed.small_bitmask & mask) == mask;
+ unsigned HOST_WIDE_INT mask;
+ if (width == -1)
+ return 0;
+ else
+ {
+ mask = lowpart_bitmask (width) << start;
+ return (s_info->positions_needed.small_bitmask & mask) == mask;
+ }
}
}