On Wed, Aug 1, 2012 at 12:14 PM, H.J. Lu wrote: > On Wed, Aug 1, 2012 at 11:58 AM, Richard Sandiford > wrote: >> "H.J. Lu" writes: >>> We have >>> >>> (gdb) r -fpreprocessed x.i -quiet -dumpbase x.i -mx32 >>> -maddress-mode=long -mtune=generic -march=x86-64 -auxbase x -O2 -version >>> -ftree-vectorize -o x.s >>> Starting program: /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/cc1 >>> -fpreprocessed x.i -quiet -dumpbase x.i -mx32 -maddress-mode=long >>> -mtune=generic -march=x86-64 -auxbase x -O2 -version -ftree-vectorize -o >>> x.s >>> GNU C (GCC) version 4.8.0 20120801 (experimental) >>> (x86_64-unknown-linux-gnu) >>> compiled by GNU C version 4.7.1 20120629 (Red Hat 4.7.1-1), GMP >>> version 5.0.2, MPFR version 3.1.0, MPC version 0.9 >>> GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 >>> GNU C (GCC) version 4.8.0 20120801 (experimental) >>> (x86_64-unknown-linux-gnu) >>> compiled by GNU C version 4.7.1 20120629 (Red Hat 4.7.1-1), GMP >>> version 5.0.2, MPFR version 3.1.0, MPC version 0.9 >>> GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 >>> Compiler executable checksum: 07a4e516c4e8fe4abfdafa83737d8f4a >>> >>> Breakpoint 1, fancy_abort ( >>> file=0x130fe68 "/export/gnu/import/git/gcc/gcc/explow.c", line=88, >>> function=0x131032e <__FUNCTION__.39220> "plus_constant") >>> at /export/gnu/import/git/gcc/gcc/diagnostic.c:1011 >>> 1011 internal_error ("in %s, at %s:%d", function, trim_filename >>> (file), line); >>> (gdb) f 1 >>> #1 0x0000000000743e07 in plus_constant (mode=DImode, x=0x7ffff106a7e0, >>> c=99452) at /export/gnu/import/git/gcc/gcc/explow.c:88 >>> 88 gcc_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode); >>> (gdb) f 2 >>> #2 0x0000000000adc4b1 in simplify_binary_operation_1 (code=PLUS, >>> mode=DImode, >>> op0=0x7ffff106a7e0, op1=0x7ffff1010e80, trueop0=0x7ffff106a7e0, >>> trueop1=0x7ffff1010e80) >>> at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:1956 >>> 1956 return plus_constant (mode, op0, INTVAL (op1)); >>> (gdb) call debug_rtx (op0) >>> (symbol_ref:SI ("tmp2") ) >>> (gdb) call debug_rtx (op1) >>> (const_int 99452 [0x1847c]) >>> (gdb) bt >>> #0 fancy_abort (file=0x130fe68 >>> "/export/gnu/import/git/gcc/gcc/explow.c", >>> line=88, function=0x131032e <__FUNCTION__.39220> "plus_constant") >>> at /export/gnu/import/git/gcc/gcc/diagnostic.c:1011 >>> #1 0x0000000000743e07 in plus_constant (mode=DImode, x=0x7ffff106a7e0, >>> c=99452) at /export/gnu/import/git/gcc/gcc/explow.c:88 >>> #2 0x0000000000adc4b1 in simplify_binary_operation_1 (code=PLUS, >>> mode=DImode, >>> op0=0x7ffff106a7e0, op1=0x7ffff1010e80, trueop0=0x7ffff106a7e0, >>> trueop1=0x7ffff1010e80) >>> at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:1956 >>> #3 0x0000000000adc221 in simplify_binary_operation (code=PLUS, >>> mode=DImode, >>> op0=0x7ffff106a7e0, op1=0x7ffff1010e80) >>> at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:1904 >> >> Things have already gone wrong by this frame: we have a DImode >> addition of an SImode value, which isn't allowed. Where does >> that mismatch get introduced? >> > > make_extraction in combine generates: > > 7474 inner = force_to_mode (inner, wanted_inner_mode, > 7475 pos_rtx > 7476 || len + orig_pos >= HOST_BITS_PER_WIDE_INT > 7477 ? ~(unsigned HOST_WIDE_INT) 0 > 7478 : ((((unsigned HOST_WIDE_INT) 1 << len) - 1) > (gdb) call debug_rtx (inner) > (plus:SI (reg:SI 109 [ D.1765 ]) > (const:SI (plus:SI (symbol_ref:SI ("tmp2") ) > (const_int 99452 [0x1847c])))) > (gdb) p wanted_inner_mode > $2 = DImode > (gdb) > i386,md has (define_expand "extzv" [(set (match_operand:SI 0 "register_operand") (zero_extract:SI (match_operand 1 "ext_register_operand") (match_operand:SI 2 "const8_operand") (match_operand:SI 3 "const8_operand")))] "" and mode_for_extraction picks word_mode for operand 1 since its mode is VOIDmode. This patch changes mode_for_extraction to return the mode of operand 1 if the pattern accepts any mode. I added *jcc_btsi_mask_2 since combine now tries a different pattern, which leads to test failures on gcc.target/i386/bt-mask-1.c and gcc.target/i386/bt-mask-2. I didn't update *jcc_btsi_mask_1 instead since I am not sure if it is used elsewhere. Tested on Linux/x86-64 and Linux/x32. OK for trunk? Thanks. -- H.J. ---- gcc/ 2012-08-02 H.J. Lu PR rtl-optimization/54157 * combine.c (make_extraction): Pass inner_mode to mode_for_extraction for operand 1, otherwise pass VOIDmode. (simplify_comparison): Pass VOIDmode to mode_for_extraction. * expmed.c (mode_for_extraction): Add a machine_mode argument and use it instead of word_mode if it isn't VOIDmode. (store_bit_field_1): Pass VOIDmode to mode_for_extraction. (store_bit_field): Likewise. * expr.h (mode_for_extraction): Add a machine_mode argument. * config/i386/i386.md (*jcc_btsi_mask_2): New insn_and_split pattern. * recog.c (simplify_while_replacing): Pass is_mode to mode_for_extraction. gcc/testsuite/ 2012-08-02 H.J. Lu PR rtl-optimization/54157 * gcc.target/i386/pr54157.c: New file.