Patchwork PATCH: PR rtl-optimization/54157: [x32] -maddress-mode=long failures

login
register
mail settings
Submitter H.J. Lu
Date Aug. 1, 2012, 6:41 p.m.
Message ID <20120801184138.GA3787@intel.com>
Download mbox | patch
Permalink /patch/174573/
State New
Headers show

Comments

H.J. Lu - Aug. 1, 2012, 6:41 p.m.
Hi,

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") <var_decl 0x7ffff0f06140 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
#4  0x0000000000ae4beb in simplify_plus_minus (code=PLUS, mode=DImode, 
    op0=0x7ffff1071d80, op1=0x7ffff1072440)
    at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:4083
#5  0x0000000000adcd81 in simplify_binary_operation_1 (code=PLUS,
mode=DImode, 
    op0=0x7ffff1071d80, op1=0x7ffff1072440, trueop0=0x7ffff1071d80, 
    trueop1=0x7ffff1072440)
    at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:2079
#6  0x0000000000adc221 in simplify_binary_operation (code=PLUS,
mode=DImode, 
    op0=0x7ffff1071d80, op1=0x7ffff1072440)
    at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:1904
#7  0x0000000000ad6f55 in simplify_gen_binary (code=PLUS, mode=DImode, 
---Type <return> to continue, or q <return> to quit---
    op0=0x7ffff1071d80, op1=0x7ffff1072440)
    at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:173
#8  0x000000000111b868 in force_to_mode (x=0x7ffff1071cd8, mode=DImode, 
    mask=15, just_select=0) at
/export/gnu/import/git/gcc/gcc/combine.c:8392
#9  0x0000000001118ed6 in make_extraction (mode=SImode,
inner=0x7ffff1071cd8, 
    pos=2, pos_rtx=0x0, len=2, unsignedp=1, in_dest=0, in_compare=0)
    at /export/gnu/import/git/gcc/gcc/combine.c:7474
#10 0x0000000001119981 in make_compound_operation (x=0x7ffff1071d68, 
    in_code=SET) at /export/gnu/import/git/gcc/gcc/combine.c:7721
#11 0x0000000001116cc5 in simplify_set (x=0x7ffff1066c78)
    at /export/gnu/import/git/gcc/gcc/combine.c:6539
#12 0x0000000001114e91 in combine_simplify_rtx (x=0x7ffff1066c78, 
    op0_mode=VOIDmode, in_dest=0, in_cond=0)
    at /export/gnu/import/git/gcc/gcc/combine.c:5971
#13 0x0000000001113250 in subst (x=0x7ffff1066c78, from=0x7ffff106a860, 
    to=0x7ffff1071cd8, in_dest=0, in_cond=0, unique_copy=0)
    at /export/gnu/import/git/gcc/gcc/combine.c:5301
#14 0x0000000001112d30 in subst (x=0x7ffff1059870, from=0x7ffff106a860, 
    to=0x7ffff1071cd8, in_dest=0, in_cond=0, unique_copy=0)
    at /export/gnu/import/git/gcc/gcc/combine.c:5164
#15 0x000000000110d1e3 in try_combine (i3=0x7ffff106c5a0,
i2=0x7ffff106c558, 
    i1=0x7ffff106c510, i0=0x0, new_direct_jump_p=0x7fffffffd974, 
    last_combined_insn=0x7ffff106c5a0)
---Type <return> to continue, or q <return> to quit---
    at /export/gnu/import/git/gcc/gcc/combine.c:3259
#16 0x00000000011083ad in combine_instructions (f=0x7ffff102ba40,
nregs=162)
    at /export/gnu/import/git/gcc/gcc/combine.c:1265
#17 0x00000000011284fd in rest_of_handle_combine ()
    at /export/gnu/import/git/gcc/gcc/combine.c:13948
#18 0x0000000000a1bfce in execute_one_pass (pass=0x19141c0
<pass_combine>)
    at /export/gnu/import/git/gcc/gcc/passes.c:2158
#19 0x0000000000a1c1b4 in execute_pass_list (pass=0x19141c0
<pass_combine>)
    at /export/gnu/import/git/gcc/gcc/passes.c:2213
#20 0x0000000000a1c1d5 in execute_pass_list (
    pass=0x190ea80 <pass_rest_of_compilation>)
    at /export/gnu/import/git/gcc/gcc/passes.c:2214
#21 0x000000000068a9f6 in expand_function (node=0x7ffff0f04750)
    at /export/gnu/import/git/gcc/gcc/cgraphunit.c:1610
#22 0x000000000068b0dd in expand_all_functions ()
    at /export/gnu/import/git/gcc/gcc/cgraphunit.c:1715
#23 0x000000000068bc5c in compile ()
    at /export/gnu/import/git/gcc/gcc/cgraphunit.c:2013
#24 0x000000000068bdbf in finalize_compilation_unit ()
    at /export/gnu/import/git/gcc/gcc/cgraphunit.c:2090
#25 0x00000000004bbf89 in c_write_global_declarations ()
    at /export/gnu/import/git/gcc/gcc/c/c-decl.c:10116
#26 0x0000000000b10237 in compile_file ()
---Type <return> to continue, or q <return> to quit---
    at /export/gnu/import/git/gcc/gcc/toplev.c:560
#27 0x0000000000b12119 in do_compile ()
    at /export/gnu/import/git/gcc/gcc/toplev.c:1863
#28 0x0000000000b12284 in toplev_main (argc=17, argv=0x7fffffffdde8)
    at /export/gnu/import/git/gcc/gcc/toplev.c:1939
#29 0x000000000123dcc8 in main (argc=17, argv=0x7fffffffdde8)
    at /export/gnu/import/git/gcc/gcc/main.c:36
(gdb) 

This patch calls convert_memory_address to convert address before
plus_constant.  OK for trunk?

Thanks.


H.J.
---
gcc/

2012-08-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/54157
	* gcc/simplify-rtx.c (simplify_binary_operation_1): Call
	convert_memory_address to convert address before plus_constant.

gcc/testsuite/

2012-08-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/54157
	* gcc.target/i386/pr54157.c: New file.
Richard Sandiford - Aug. 1, 2012, 6:58 p.m.
"H.J. Lu" <hongjiu.lu@intel.com> 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") <var_decl 0x7ffff0f06140 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?

Richard
H.J. Lu - Aug. 1, 2012, 7:14 p.m.
On Wed, Aug 1, 2012 at 11:58 AM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> "H.J. Lu" <hongjiu.lu@intel.com> 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") <var_decl 0x7ffff0f06140 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") <var_decl 0x7ffff0f06140 tmp2>)
            (const_int 99452 [0x1847c]))))
(gdb) p wanted_inner_mode
$2 = DImode
(gdb)
H.J. Lu - Aug. 2, 2012, 6:20 p.m.
On Wed, Aug 1, 2012 at 12:14 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Aug 1, 2012 at 11:58 AM, Richard Sandiford
> <rdsandiford@googlemail.com> wrote:
>> "H.J. Lu" <hongjiu.lu@intel.com> 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") <var_decl 0x7ffff0f06140 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") <var_decl 0x7ffff0f06140 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.
Richard Sandiford - Aug. 5, 2012, 7:47 a.m.
For the record, I can't approve this, but...

"H.J. Lu" <hjl.tools@gmail.com> writes:
> 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?

the mode of the extraction operand is defined to be word_mode
for registers (see md.texi), so that at least would need to
be updated.  But I'm not convinced that the wanted_inner_mode here:

   if (! in_dest && unsignedp
-      && mode_for_extraction (EP_extzv, -1) != MAX_MACHINE_MODE)
+      && mode_for_extraction (EP_extzv, -1, VOIDmode) != MAX_MACHINE_MODE)
     {
-      wanted_inner_reg_mode = mode_for_extraction (EP_extzv, 1);
-      pos_mode = mode_for_extraction (EP_extzv, 3);
-      extraction_mode = mode_for_extraction (EP_extzv, 0);
+      wanted_inner_reg_mode = mode_for_extraction (EP_extzv, 1,
+						   inner_mode);
+      pos_mode = mode_for_extraction (EP_extzv, 3, VOIDmode);
+      extraction_mode = mode_for_extraction (EP_extzv, 0, VOIDmode);
     }

is right.  inner_mode is the mode of the thing we're extracting,
which doesn't ncessarily have anything to do with what the ext*
patterns support.

FWIW, in reply to your force_to_mode message, gen_lowpart_for_combine
looks a bit odd:

  if (omode == imode)
    return x;

  /* Return identity if this is a CONST or symbolic reference.  */
  if (omode == Pmode
      && (GET_CODE (x) == CONST
	  || GET_CODE (x) == SYMBOL_REF
	  || GET_CODE (x) == LABEL_REF))
    return x;

So if we know the modes are different, we nevertheless return the
original mode for CONST, SYMBOL_REF or LABEL_REF.  Surely the caller
isn't going to be expecting that?  If we're not prepared to change
the mode to the one that the caller asked for then I think we should
goto fail instead.

I don't know if you're hitting that or not.

Richard

Patch

diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index e1bd3cf..5d4ec89 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1953,12 +1953,26 @@  simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
 	   || GET_CODE (op0) == SYMBOL_REF
 	   || GET_CODE (op0) == LABEL_REF)
 	  && CONST_INT_P (op1))
-	return plus_constant (mode, op0, INTVAL (op1));
+	{
+	  if (GET_CODE (op0) == CONST)
+	    return plus_constant (mode, op0, INTVAL (op1));
+	  else
+	    return plus_constant (mode,
+				  convert_memory_address (mode, op0),
+				  INTVAL (op1));
+	}
       else if ((GET_CODE (op1) == CONST
 		|| GET_CODE (op1) == SYMBOL_REF
 		|| GET_CODE (op1) == LABEL_REF)
 	       && CONST_INT_P (op0))
-	return plus_constant (mode, op1, INTVAL (op0));
+	{
+	  if (GET_CODE (op1) == CONST)
+	    return plus_constant (mode, op1, INTVAL (op0));
+	  else
+	    return plus_constant (mode,
+				  convert_memory_address (mode, op1),
+				  INTVAL (op0));
+	}
 
       /* See if this is something like X * C - X or vice versa or
 	 if the multiplication is written as a shift.  If so, we can
diff --git a/gcc/testsuite/gcc.target/i386/pr54157.c b/gcc/testsuite/gcc.target/i386/pr54157.c
new file mode 100644
index 0000000..b5c4528
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr54157.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-options "-O2 -mx32 -maddress-mode=long -ftree-vectorize" } */
+
+struct s2{
+  int n[24 -1][24 -1][24 -1];
+};
+
+struct test2{
+  struct s2 e;
+};
+
+struct test2 tmp2[4];
+
+void main1 ()
+{
+  int i,j;
+
+  for (i = 0; i < 24 -4; i++)
+      for (j = 0; j < 24 -4; j++)
+          tmp2[2].e.n[1][i][j] = 8;
+}