From: "H.J. Lu" <hjl.tools@gmail.com>
To: gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com,
Uros Bizjak <ubizjak@gmail.com>
Subject: Re: PATCH: PR rtl-optimization/54157: [x32] -maddress-mode=long failures
Date: Thu, 02 Aug 2012 18:21:00 -0000 [thread overview]
Message-ID: <CAMe9rOqRVkpQykyfqODMuCcnUADoaL=pZqbXF3-Y-AaKCD_j2g@mail.gmail.com> (raw)
In-Reply-To: <CAMe9rOrTKQ1RCAvKg1kFn_XbP2=_wUx6hnRMeMGodwt9A8wP0Q@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5529 bytes --]
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.
--
H.J.
----
gcc/
2012-08-02 H.J. Lu <hongjiu.lu@intel.com>
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 <hongjiu.lu@intel.com>
PR rtl-optimization/54157
* gcc.target/i386/pr54157.c: New file.
[-- Attachment #2: gcc-pr54157.patch --]
[-- Type: application/octet-stream, Size: 8565 bytes --]
gcc/
2012-08-02 H.J. Lu <hongjiu.lu@intel.com>
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 <hongjiu.lu@intel.com>
PR rtl-optimization/54157
* gcc.target/i386/pr54157.c: New file.
diff --git a/gcc/combine.c b/gcc/combine.c
index a07c046..035aeb9 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7332,27 +7332,30 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
/* Get the mode to use should INNER not be a MEM, the mode for the position,
and the mode for the result. */
- if (in_dest && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE)
+ if (in_dest
+ && mode_for_extraction (EP_insv, -1, VOIDmode) != MAX_MACHINE_MODE)
{
- wanted_inner_reg_mode = mode_for_extraction (EP_insv, 0);
- pos_mode = mode_for_extraction (EP_insv, 2);
- extraction_mode = mode_for_extraction (EP_insv, 3);
+ wanted_inner_reg_mode = mode_for_extraction (EP_insv, 0, VOIDmode);
+ pos_mode = mode_for_extraction (EP_insv, 2, VOIDmode);
+ extraction_mode = mode_for_extraction (EP_insv, 3, VOIDmode);
}
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);
}
if (! in_dest && ! unsignedp
- && mode_for_extraction (EP_extv, -1) != MAX_MACHINE_MODE)
+ && mode_for_extraction (EP_extv, -1, VOIDmode) != MAX_MACHINE_MODE)
{
- wanted_inner_reg_mode = mode_for_extraction (EP_extv, 1);
- pos_mode = mode_for_extraction (EP_extv, 3);
- extraction_mode = mode_for_extraction (EP_extv, 0);
+ wanted_inner_reg_mode = mode_for_extraction (EP_extv, 1,
+ inner_mode);
+ pos_mode = mode_for_extraction (EP_extv, 3, VOIDmode);
+ extraction_mode = mode_for_extraction (EP_extv, 0, VOIDmode);
}
/* Never narrow an object, since that might not be safe. */
@@ -11294,7 +11297,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
if (BITS_BIG_ENDIAN)
{
enum machine_mode new_mode
- = mode_for_extraction (EP_extzv, 1);
+ = mode_for_extraction (EP_extzv, 1, VOIDmode);
if (new_mode == MAX_MACHINE_MODE)
i = BITS_PER_WORD - 1 - i;
else
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index ace3b6e..6835d31 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -11065,6 +11065,39 @@
(pc)))]
"PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
+(define_insn_and_split "*jcc_btsi_mask_2"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "bt_comparison_operator"
+ [(zero_extract:SI
+ (match_operand:SI 1 "register_operand" "r")
+ (const_int 1)
+ (zero_extend:SI
+ (subreg:QI
+ (and:SI
+ (match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "const_int_operand" "n")) 0)))
+ (const_int 0)])
+ (label_ref (match_operand 4))
+ (pc)))
+ (clobber (reg:CC FLAGS_REG))]
+ "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
+ && (INTVAL (operands[3]) & 0x1f) == 0x1f"
+ "#"
+ "&& 1"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (zero_extract:SI
+ (match_dup 1)
+ (const_int 1)
+ (match_dup 2))
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
+ (label_ref (match_dup 4))
+ (pc)))]
+ "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
+
;; Define combination compare-and-branch fp compare instructions to help
;; combine.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 1fe0034..367f94d 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -338,9 +338,12 @@ negate_rtx (enum machine_mode mode, rtx x)
/* Report on the availability of insv/extv/extzv and the desired mode
of each of their operands. Returns MAX_MACHINE_MODE if HAVE_foo
is false; else the mode of the specified operand. If OPNO is -1,
- all the caller cares about is whether the insn is available. */
+ all the caller cares about is whether the insn is available. Return
+ MODE instead of word_mode if it isn't VOIDmode. */
+
enum machine_mode
-mode_for_extraction (enum extraction_pattern pattern, int opno)
+mode_for_extraction (enum extraction_pattern pattern, int opno,
+ enum machine_mode mode)
{
const struct insn_data_d *data;
@@ -380,7 +383,7 @@ mode_for_extraction (enum extraction_pattern pattern, int opno)
/* Everyone who uses this function used to follow it with
if (result == VOIDmode) result = word_mode; */
if (data->operand[opno].mode == VOIDmode)
- return word_mode;
+ return mode != VOIDmode ? mode : word_mode;
return data->operand[opno].mode;
}
\f
@@ -406,7 +409,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
int byte_offset;
rtx orig_value;
- enum machine_mode op_mode = mode_for_extraction (EP_insv, 3);
+ enum machine_mode op_mode = mode_for_extraction (EP_insv, 3, VOIDmode);
while (GET_CODE (op0) == SUBREG)
{
@@ -894,7 +897,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
enum machine_mode op_mode;
unsigned HOST_WIDE_INT offset;
- op_mode = mode_for_extraction (EP_insv, 3);
+ op_mode = mode_for_extraction (EP_insv, 3, VOIDmode);
if (op_mode == MAX_MACHINE_MODE)
op_mode = VOIDmode;
@@ -1592,7 +1595,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
}
/* Now OFFSET is nonzero only for memory operands. */
- ext_mode = mode_for_extraction (unsignedp ? EP_extzv : EP_extv, 0);
+ ext_mode = mode_for_extraction (unsignedp ? EP_extzv : EP_extv, 0,
+ VOIDmode);
if (ext_mode != MAX_MACHINE_MODE
&& bitsize > 0
&& GET_MODE_BITSIZE (ext_mode) >= bitsize
diff --git a/gcc/expr.h b/gcc/expr.h
index 68cdb8d..588299c 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -687,7 +687,7 @@ extern rtx hard_libcall_value (enum machine_mode, rtx);
enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
extern enum machine_mode
-mode_for_extraction (enum extraction_pattern, int);
+mode_for_extraction (enum extraction_pattern, int, enum machine_mode);
extern void store_bit_field (rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT,
diff --git a/gcc/recog.c b/gcc/recog.c
index a05e8c6..2d1e4db 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -639,14 +639,14 @@ simplify_while_replacing (rtx *loc, rtx to, rtx object,
if (GET_CODE (x) == ZERO_EXTRACT)
{
enum machine_mode new_mode
- = mode_for_extraction (EP_extzv, 1);
+ = mode_for_extraction (EP_extzv, 1, is_mode);
if (new_mode != MAX_MACHINE_MODE)
wanted_mode = new_mode;
}
else if (GET_CODE (x) == SIGN_EXTRACT)
{
enum machine_mode new_mode
- = mode_for_extraction (EP_extv, 1);
+ = mode_for_extraction (EP_extv, 1, is_mode);
if (new_mode != MAX_MACHINE_MODE)
wanted_mode = new_mode;
}
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;
+}
next prev parent reply other threads:[~2012-08-02 18:21 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-01 18:41 H.J. Lu
2012-08-01 18:59 ` Richard Sandiford
2012-08-01 19:14 ` H.J. Lu
2012-08-02 18:21 ` H.J. Lu [this message]
2012-08-05 7:47 ` Richard Sandiford
2012-08-07 19:28 ` H.J. Lu
2012-08-08 8:09 ` Richard Sandiford
2012-08-08 13:40 ` H.J. Lu
2012-08-08 13:43 ` Uros Bizjak
2012-08-08 13:50 ` H.J. Lu
2012-08-08 15:11 ` Richard Sandiford
2012-08-09 14:51 ` H.J. Lu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAMe9rOqRVkpQykyfqODMuCcnUADoaL=pZqbXF3-Y-AaKCD_j2g@mail.gmail.com' \
--to=hjl.tools@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=rdsandiford@googlemail.com \
--cc=ubizjak@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).