Hi! The recent change to get_mode_bounds for partial mode, where GET_MODE_PRECISION instead of GET_MODE_SIZE is now used, has broken ia64 bootstrap. The problem is that BImode is special cased in various places, e.g. trunc_int_for_mode, so the two values of the mode are 0 and STORE_FLAG_VALUE (which is sometimes -1, sometimes (ia64 case) 1).
Now, two of the 3 get_mode_bounds callers use the same mode == target_mode and when called with BImode, true, BImode, ... min_val is -1 and max_val is 0, but given the weirdo trunc_int_for_mode behavior which returns STORE_FLAG_VALUE for value with low bit set and 0 otherwise, get_mode_bounds actually returns min_rtx (const_int 1) and max_rtx (const_int 0). This confuses the callers (in this case simplify-rtx.c) which then compares the trueop1 value against the bounds to miscompile the code. This patch fixes this by special casing BImode, so that we get the bounds in the right order for BImode, ?, BImode and even for the case where target_mode is wider ignores sign and returns 0, STORE_FLAG_VALUE or vice versa in the right order. Eric has kindly tested this on ia64. Ok for trunk? 2014-01-08 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/59649 * stor-layout.c (get_mode_bounds): For BImode return 0 and STORE_FLAG_VALUE. --- gcc/stor-layout.c.jj 2014-01-03 11:40:57.000000000 +0100 +++ gcc/stor-layout.c 2014-01-07 18:59:39.056846684 +0100 @@ -2821,7 +2821,21 @@ get_mode_bounds (enum machine_mode mode, gcc_assert (size <= HOST_BITS_PER_WIDE_INT); - if (sign) + /* Special case BImode, which has values 0 and STORE_FLAG_VALUE. */ + if (mode == BImode) + { + if (STORE_FLAG_VALUE < 0) + { + min_val = STORE_FLAG_VALUE; + max_val = 0; + } + else + { + min_val = 0; + max_val = STORE_FLAG_VALUE; + } + } + else if (sign) { min_val = -((unsigned HOST_WIDE_INT) 1 << (size - 1)); max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1; Jakub