public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
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;
+}

  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).