Bug 49497 - Incorrect lea peephole
Summary: Incorrect lea peephole
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: 4.7.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-21 23:12 UTC by H.J. Lu
Modified: 2011-06-23 13:12 UTC (History)
1 user (show)

See Also:
Host:
Target: x86
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
A patch (574 bytes, patch)
2011-06-21 23:20 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2011-06-21 23:12:39 UTC
i386.md has

;; Convert imul by three, five and nine into lea
(define_peephole2
  [(parallel
    [(set (match_operand:SWI48 0 "register_operand" "")
          (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
                      (match_operand:SWI48 2 "const_int_operand" ""))) 
     (clobber (reg:CC FLAGS_REG))])]
  "INTVAL (operands[2]) == 3
   || INTVAL (operands[2]) == 5
   || INTVAL (operands[2]) == 9"
  [(set (match_dup 0)
        (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
                    (match_dup 1)))] 
  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")

(define_peephole2
  [(parallel
    [(set (match_operand:SWI48 0 "register_operand" "")
          (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
                      (match_operand:SWI48 2 "const_int_operand" ""))) 
     (clobber (reg:CC FLAGS_REG))])]
  "optimize_insn_for_speed_p ()
   && (INTVAL (operands[2]) == 3
       || INTVAL (operands[2]) == 5
       || INTVAL (operands[2]) == 9)"
  [(set (match_dup 0) (match_dup 1))
   (set (match_dup 0)
        (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
                    (match_dup 0)))]
  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")


But lea split has

&& (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))

When TARGET_PARTIAL_REG_STALL is true, get got

[hjl@gnu-33 1036]$ cat x.i
 char *progName;
 int *tt;
 unsigned char *ll8;
 extern void foo (const char *);
 void cleanUpAndFail ( int ec ) {
    __builtin_exit ( ec );
 }
 void uncompressOutOfMemory ( int draw, int blockSize ) {
    foo ( "\tand failing that, find a machine with more memory.\n");
    cleanUpAndFail(1);
 }
 void setDecompressStructureSizes ( int newSize100k ) {
       int n = 100000 * newSize100k;
       ll8 = __builtin_malloc ( n * sizeof(unsigned char) );
       if (ll8 == ((void *)0) || tt == ((void *)0)) {
          int totalDraw             = n * sizeof(unsigned char) + n * sizeof(unsigned int);
          uncompressOutOfMemory ( totalDraw, n );
       }
 }
[hjl@gnu-33 1036]$ make x.s
/export/build/gnu/gcc/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc/build-x86_64-linux/gcc/ -O2  -S x.i
x.i: In function ‘setDecompressStructureSizes’:
x.i:19:2: error: unrecognizable insn:
(insn 43 19 21 4 (set (reg:SI 5 di [69])
        (plus:SI (mult:SI (reg/v:SI 3 bx [orig:59 n ] [59])
                (const_int 4 [0x4]))
            (reg/v:SI 3 bx [orig:59 n ] [59]))) x.i:16 -1
     (nil))
x.i:19:2: internal compiler error: in extract_insn, at recog.c:2113
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make: *** [x.s] Error 1
[hjl@gnu-33 1036]$
Comment 1 H.J. Lu 2011-06-21 23:20:18 UTC
Created attachment 24578 [details]
A patch

There is no partial register stall for SImode.
Comment 2 Uroš Bizjak 2011-06-22 06:14:27 UTC
(In reply to comment #1)
> Created attachment 24578 [details]
> A patch
> 
> There is no partial register stall for SImode.

Looks good to me, maybe we should introduce const359_operand predicate (similar to const248_operand) to move operand checks from insn constraint.
Comment 3 hjl@gcc.gnu.org 2011-06-22 15:29:48 UTC
Author: hjl
Date: Wed Jun 22 15:29:43 2011
New Revision: 175295

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175295
Log:
Check TARGET_PARTIAL_REG_STALL in imul to lea peepholes.

2011-06-22  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/49497
	* config/i386/i386.md (*lea_general_2): Always allow SImode.
	(*lea_general_2_zext): Likewise.
	(imul to lea peepholes): Use const359_operand and check
	TARGET_PARTIAL_REG_STALL.

	* config/i386/predicates.md (const359_operand): New.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.md
    trunk/gcc/config/i386/predicates.md
Comment 4 H.J. Lu 2011-06-23 13:12:01 UTC
Fixed.