This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

x86_64 leas and RSP


Hi,
The testcase gcc.c-torture/unsorted/opout.c shows interesting problem on x86_64 compilation.
Combine creates instruction (set (reg) (ashift (reg frame) (const_int 4)))
that is perfectly valid if it wasnt turned into (set (reg eax) (ashift (reg rsp) (const_int 4)))
by reload and in turn converted into lea that does not allow RSP in the index.

I've reviewed the i386 patterns and found few other places where rsp should not
happen.  I believe I can go without extra register class for INDEX_REG just by
using index_register_operand that rules out everything that eventually reduces
to rsp.

Honza
Tue Aug 27 21:22:11 CEST 2002  Jan Hubicka  <jh@suse.cz>
	* i386.c (index_register_operand): New.
	* i386.h (predicate_codes): Add new predicate.
	* i386.md (lea_general_*): Use index_regsiter_operand
	(ashift to lea splitter): Do not produce invalid leas
	(ashift to mov+ashift split): New.

Index: i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.449
diff -c -3 -p -r1.449 i386.c
*** i386.c	27 Aug 2002 17:19:45 -0000	1.449
--- i386.c	27 Aug 2002 19:18:19 -0000
*************** nonmemory_no_elim_operand (op, mode)
*** 3211,3216 ****
--- 3219,3248 ----
      return 0;
  
    return GET_CODE (op) == CONST_INT || register_operand (op, mode);
+ }
+ 
+ /* Return false if this is any eliminable register or stack register,
+    otherwise work like register_operand.  */
+ 
+ int
+ index_register_operand (op, mode)
+      register rtx op;
+      enum machine_mode mode;
+ {
+   rtx t = op;
+   if (GET_CODE (t) == SUBREG)
+     t = SUBREG_REG (t);
+   if (!REG_P (t))
+     return 0;
+   if (t == arg_pointer_rtx
+       || t == frame_pointer_rtx
+       || t == virtual_incoming_args_rtx
+       || t == virtual_stack_vars_rtx
+       || t == virtual_stack_dynamic_rtx
+       || REGNO (t) == STACK_POINTER_REGNUM)
+     return 0;
+ 
+   return general_operand (op, mode);
  }
  
  /* Return true if op is a Q_REGS class register.  */
Index: i386.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.280
diff -c -3 -p -r1.280 i386.h
*** i386.h	31 Jul 2002 23:18:43 -0000	1.280
--- i386.h	27 Aug 2002 19:18:20 -0000
*************** do {						\
*** 3157,3162 ****
--- 3165,3171 ----
    {"general_no_elim_operand", {CONST_INT, CONST_DOUBLE, CONST,		\
  			SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}},	\
    {"nonmemory_no_elim_operand", {CONST_INT, REG, SUBREG}},		\
+   {"index_register_operand", {SUBREG, REG}},				\
    {"q_regs_operand", {SUBREG, REG}},					\
    {"non_q_regs_operand", {SUBREG, REG}},				\
    {"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU, UNORDERED, \
Index: i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.380
diff -c -3 -p -r1.380 i386.md
*** i386.md	12 Aug 2002 10:50:02 -0000	1.380
--- i386.md	27 Aug 2002 19:18:25 -0000
***************
*** 4845,4851 ****
  
  (define_insn_and_split "*lea_general_1"
    [(set (match_operand 0 "register_operand" "=r")
! 	(plus (plus (match_operand 1 "register_operand" "r")
  		    (match_operand 2 "register_operand" "r"))
  	      (match_operand 3 "immediate_operand" "i")))]
    "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
--- 4854,4860 ----
  
  (define_insn_and_split "*lea_general_1"
    [(set (match_operand 0 "register_operand" "=r")
! 	(plus (plus (match_operand 1 "index_register_operand" "r")
  		    (match_operand 2 "register_operand" "r"))
  	      (match_operand 3 "immediate_operand" "i")))]
    "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
***************
*** 4877,4883 ****
  (define_insn_and_split "*lea_general_1_zext"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(zero_extend:DI
! 	  (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
  			    (match_operand:SI 2 "register_operand" "r"))
  		   (match_operand:SI 3 "immediate_operand" "i"))))]
    "TARGET_64BIT"
--- 4886,4892 ----
  (define_insn_and_split "*lea_general_1_zext"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(zero_extend:DI
! 	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
  			    (match_operand:SI 2 "register_operand" "r"))
  		   (match_operand:SI 3 "immediate_operand" "i"))))]
    "TARGET_64BIT"
***************
*** 4897,4903 ****
  
  (define_insn_and_split "*lea_general_2"
    [(set (match_operand 0 "register_operand" "=r")
! 	(plus (mult (match_operand 1 "register_operand" "r")
  		    (match_operand 2 "const248_operand" "i"))
  	      (match_operand 3 "nonmemory_operand" "ri")))]
    "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
--- 4906,4912 ----
  
  (define_insn_and_split "*lea_general_2"
    [(set (match_operand 0 "register_operand" "=r")
! 	(plus (mult (match_operand 1 "index_register_operand" "r")
  		    (match_operand 2 "const248_operand" "i"))
  	      (match_operand 3 "nonmemory_operand" "ri")))]
    "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
***************
*** 4927,4933 ****
  (define_insn_and_split "*lea_general_2_zext"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(zero_extend:DI
! 	  (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
  			    (match_operand:SI 2 "const248_operand" "n"))
  		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
    "TARGET_64BIT"
--- 4936,4942 ----
  (define_insn_and_split "*lea_general_2_zext"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(zero_extend:DI
! 	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
  			    (match_operand:SI 2 "const248_operand" "n"))
  		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
    "TARGET_64BIT"
***************
*** 4946,4952 ****
  
  (define_insn_and_split "*lea_general_3"
    [(set (match_operand 0 "register_operand" "=r")
! 	(plus (plus (mult (match_operand 1 "register_operand" "r")
  			  (match_operand 2 "const248_operand" "i"))
  		    (match_operand 3 "register_operand" "r"))
  	      (match_operand 4 "immediate_operand" "i")))]
--- 4955,4961 ----
  
  (define_insn_and_split "*lea_general_3"
    [(set (match_operand 0 "register_operand" "=r")
! 	(plus (plus (mult (match_operand 1 "index_register_operand" "r")
  			  (match_operand 2 "const248_operand" "i"))
  		    (match_operand 3 "register_operand" "r"))
  	      (match_operand 4 "immediate_operand" "i")))]
***************
*** 4980,4986 ****
  (define_insn_and_split "*lea_general_3_zext"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(zero_extend:DI
! 	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
  				     (match_operand:SI 2 "const248_operand" "n"))
  			    (match_operand:SI 3 "register_operand" "r"))
  		   (match_operand:SI 4 "immediate_operand" "i"))))]
--- 4989,4995 ----
  (define_insn_and_split "*lea_general_3_zext"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(zero_extend:DI
! 	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
  				     (match_operand:SI 2 "const248_operand" "n"))
  			    (match_operand:SI 3 "register_operand" "r"))
  		   (match_operand:SI 4 "immediate_operand" "i"))))]
***************
*** 10615,10621 ****
  ;; Convert lea to the lea pattern to avoid flags dependency.
  (define_split
    [(set (match_operand 0 "register_operand" "")
! 	(ashift (match_operand 1 "register_operand" "")
                  (match_operand:QI 2 "const_int_operand" "")))
     (clobber (reg:CC 17))]
    "reload_completed
--- 10624,10630 ----
  ;; Convert lea to the lea pattern to avoid flags dependency.
  (define_split
    [(set (match_operand 0 "register_operand" "")
! 	(ashift (match_operand 1 "index_register_operand" "")
                  (match_operand:QI 2 "const_int_operand" "")))
     (clobber (reg:CC 17))]
    "reload_completed
***************
*** 10630,10635 ****
--- 10639,10664 ----
    if (Pmode != SImode)
      pat = gen_rtx_SUBREG (SImode, pat, 0);
    emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
+   DONE;
+ })
+ 
+ ;; Rare case of shifting RSP is handled by generating move and shift
+ (define_split
+   [(set (match_operand 0 "register_operand" "")
+ 	(ashift (match_operand 1 "register_operand" "")
+                 (match_operand:QI 2 "const_int_operand" "")))
+    (clobber (reg:CC 17))]
+   "reload_completed
+    && true_regnum (operands[0]) != true_regnum (operands[1])"
+   [(const_int 0)]
+ {
+   rtx pat, clob;
+   emit_move_insn (operands[1], operands[0]);
+   pat = gen_rtx_SET (VOIDmode, operands[0],
+ 		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
+ 				     operands[0], operands[2]));
+   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
+   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
    DONE;
  })
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]