This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: cc register usage on i386/2.96
- To: Andi Kleen <ak at suse dot de>, gcc-patches at gcc dot gnu dot org, rth at cygnus dot com
- Subject: Re: cc register usage on i386/2.96
- From: Jan Hubicka <jh at suse dot cz>
- Date: Mon, 28 Aug 2000 13:28:26 +0200
- Cc: Jan Hubicka <jh at suse dot cz>
- References: <20000828015105.C1077@atrey.karlin.mff.cuni.cz> <20000828020055.A29832@gruyere.muc.suse.de>
Hi
The problem with your testcase is, that the result of arithmetic operation is
not used. Gcc knows how to do arithmetic by itself and how to do arithmetic
together with comparison, but it don't know that comparison can be done w/o
the arithmetic. Modyfing it to:
int f(int a, int b)
{
int c=a+b;
if (c>=0)
f2();
return c;
}
Lets combine to do the trick.
Since such case is probably common enought, here is patch to add necesary
patterns to do comparisons alone. Not too many of them are needed, since AND
and shifts are converted to tests by combine and neg/not to comparisons. Only
remaining are PLUS, MINUS, OR and XOR. The PLUS case don't work always, since
combine sometimes manage it to convert into
(compare operands[1] (neg operands[2]))
and I can't match this with add instructions since these are equivalent only in
nonzero bit.
Comparing size of byte benchmark suggest roughly 20 matches on it. The
performance improvements are inmeasurable tought.
Honza
Mon Aug 28 13:26:42 CEST 2000 Jan Hubicka <jh@suse.cz>
* i386.md (add?i_4): Rename from add?i_3.
(add?i_3, add?i_4): New.
(sub?i_3, ior?i_3, xor?i_3): New.
*** i386.md.old Mon Aug 28 12:17:54 2000
--- i386.md Mon Aug 28 13:22:26 2000
***************
*** 3967,3972 ****
--- 3967,4020 ----
(set_attr "mode" "SI")])
(define_insn "*addsi_3"
+ [(set (reg 17)
+ (compare
+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
+ (match_operand:SI 2 "general_operand" "rmni"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
+ /* Current assemblers are broken and do not allow @GOTOFF in
+ ought but a memory context. */
+ && ! pic_symbolic_operand (operands[2], VOIDmode)"
+ "*
+ {
+ switch (get_attr_type (insn))
+ {
+ case TYPE_INCDEC:
+ if (! rtx_equal_p (operands[0], operands[1]))
+ abort ();
+ if (operands[2] == const1_rtx)
+ return \"inc{l}\\t%0\";
+ else if (operands[2] == constm1_rtx)
+ return \"dec{l}\\t%0\";
+ else
+ abort();
+
+ default:
+ if (! rtx_equal_p (operands[0], operands[1]))
+ abort ();
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ Exceptions: -128 encodes smaller than 128, so swap sign and op. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && (INTVAL (operands[2]) == 128
+ || (INTVAL (operands[2]) < 0
+ && INTVAL (operands[2]) != -128)))
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return \"sub{l}\\t{%2, %0|%0, %2}\";
+ }
+ return \"add{l}\\t{%2, %0|%0, %2}\";
+ }
+ }"
+ [(set (attr "type")
+ (if_then_else (match_operand:SI 2 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu")))
+ (set_attr "mode" "SI")])
+
+ (define_insn "*addsi_4"
[(set (reg:CC 17)
(compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
(match_operand:SI 2 "general_operand" "rmni,rni"))
***************
*** 3981,3986 ****
--- 4029,4048 ----
[(set_attr "type" "alu")
(set_attr "mode" "SI")])
+ (define_insn "*addsi_5"
+ [(set (reg:CC 17)
+ (compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
+ (match_operand:SI 2 "general_operand" "rmni"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=r"))]
+ "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
+ /* Current assemblers are broken and do not allow @GOTOFF in
+ ought but a memory context. */
+ && ! pic_symbolic_operand (operands[2], VOIDmode)"
+ "add{l}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "SI")])
+
(define_expand "addhi3"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
(plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
***************
*** 4121,4126 ****
--- 4183,4230 ----
(set_attr "mode" "HI")])
(define_insn "*addhi_3"
+ [(set (reg 17)
+ (compare
+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+ (match_operand:HI 2 "general_operand" "rmni"))
+ (const_int 0)))
+ (clobber (match_scratch:HI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "*
+ {
+ switch (get_attr_type (insn))
+ {
+ case TYPE_INCDEC:
+ if (operands[2] == const1_rtx)
+ return \"inc{w}\\t%0\";
+ else if (operands[2] == constm1_rtx
+ || (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) == 65535))
+ return \"dec{w}\\t%0\";
+ abort();
+
+ default:
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ Exceptions: -128 encodes smaller than 128, so swap sign and op. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && (INTVAL (operands[2]) == 128
+ || (INTVAL (operands[2]) < 0
+ && INTVAL (operands[2]) != -128)))
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return \"sub{w}\\t{%2, %0|%0, %2}\";
+ }
+ return \"add{w}\\t{%2, %0|%0, %2}\";
+ }
+ }"
+ [(set (attr "type")
+ (if_then_else (match_operand:HI 2 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu")))
+ (set_attr "mode" "HI")])
+
+ (define_insn "*addhi_4"
[(set (reg:CC 17)
(compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
(match_operand:HI 2 "general_operand" "rmni,rni"))
***************
*** 4132,4137 ****
--- 4236,4252 ----
[(set_attr "type" "alu")
(set_attr "mode" "HI")])
+ (define_insn "*addhi_5"
+ [(set (reg:CC 17)
+ (compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+ (match_operand:HI 2 "general_operand" "rmni"))
+ (const_int 0)))
+ (clobber (match_scratch:HI 0 "=r"))]
+ "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "add{w}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "HI")])
+
(define_expand "addqi3"
[(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
(plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
***************
*** 4280,4285 ****
--- 4395,4439 ----
(set_attr "mode" "QI")])
(define_insn "*addqi_3"
+ [(set (reg 17)
+ (compare
+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
+ (match_operand:QI 2 "general_operand" "qmni"))
+ (const_int 0)))
+ (clobber (match_scratch:QI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "*
+ {
+ switch (get_attr_type (insn))
+ {
+ case TYPE_INCDEC:
+ if (operands[2] == const1_rtx)
+ return \"inc{b}\\t%0\";
+ else if (operands[2] == constm1_rtx
+ || (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) == 255))
+ return \"dec{b}\\t%0\";
+ abort();
+
+ default:
+ /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
+ if (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) < 0)
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return \"sub{b}\\t{%2, %0|%0, %2}\";
+ }
+ return \"add{b}\\t{%2, %0|%0, %2}\";
+ }
+ }"
+ [(set (attr "type")
+ (if_then_else (match_operand:QI 2 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu")))
+ (set_attr "mode" "QI")])
+
+ (define_insn "*addqi_4"
[(set (reg:CC 17)
(compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
(match_operand:QI 2 "general_operand" "qmni,qni"))
***************
*** 4291,4296 ****
--- 4445,4461 ----
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
+ (define_insn "*addqi_5"
+ [(set (reg:CC 17)
+ (compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
+ (match_operand:QI 2 "general_operand" "qmni"))
+ (const_int 0)))
+ (clobber (match_scratch:QI 0 "=r"))]
+ "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "add{b}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "QI")])
+
(define_insn "addqi_ext_1"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
***************
*** 4454,4459 ****
--- 4619,4637 ----
[(set_attr "type" "alu")
(set_attr "mode" "SI")])
+ (define_insn "*subsi_3"
+ [(set (reg 17)
+ (compare
+ (minus:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "general_operand" "rim"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "sub{l}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "SI")])
+
(define_expand "subhi3"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
(minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
***************
*** 4486,4491 ****
--- 4664,4682 ----
[(set_attr "type" "alu")
(set_attr "mode" "HI")])
+ (define_insn "*subhi_3"
+ [(set (reg 17)
+ (compare
+ (minus:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:HI 2 "general_operand" "rim"))
+ (const_int 0)))
+ (clobber (match_scratch:HI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "sub{w}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "HI")])
+
(define_expand "subqi3"
[(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
(minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
***************
*** 4518,4523 ****
--- 4709,4727 ----
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
+ (define_insn "*subqi_3"
+ [(set (reg 17)
+ (compare
+ (minus:QI (match_operand:QI 1 "register_operand" "0")
+ (match_operand:QI 2 "general_operand" "qim"))
+ (const_int 0)))
+ (clobber (match_scratch:QI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "sub{b}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "QI")])
+
;; The patterns that match these are at the end of this file.
(define_expand "subxf3"
***************
*** 5414,5419 ****
--- 5618,5635 ----
[(set_attr "type" "alu")
(set_attr "mode" "SI")])
+ (define_insn "*iorsi_3"
+ [(set (reg 17)
+ (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
+ (match_operand:SI 2 "general_operand" "rim"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "or{l}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "SI")])
+
(define_expand "iorhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
***************
*** 5445,5450 ****
--- 5661,5678 ----
[(set_attr "type" "alu")
(set_attr "mode" "HI")])
+ (define_insn "*iorhi_3"
+ [(set (reg 17)
+ (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+ (match_operand:HI 2 "general_operand" "rim"))
+ (const_int 0)))
+ (clobber (match_scratch:HI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "or{w}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "HI")])
+
(define_expand "iorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "")
(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
***************
*** 5479,5484 ****
--- 5707,5725 ----
"or{b}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
+
+ (define_insn "*iorqi_3"
+ [(set (reg 17)
+ (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
+ (match_operand:QI 2 "general_operand" "qim"))
+ (const_int 0)))
+ (clobber (match_scratch:QI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "or{b}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "QI")])
+
;; Logical XOR instructions
***************
*** 5516,5521 ****
--- 5757,5774 ----
[(set_attr "type" "alu")
(set_attr "mode" "SI")])
+ (define_insn "*xorsi_3"
+ [(set (reg 17)
+ (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
+ (match_operand:SI 2 "general_operand" "rim"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "xor{l}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "SI")])
+
(define_expand "xorhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
***************
*** 5547,5552 ****
--- 5800,5817 ----
[(set_attr "type" "alu")
(set_attr "mode" "HI")])
+ (define_insn "*xorhi_3"
+ [(set (reg 17)
+ (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+ (match_operand:HI 2 "general_operand" "rim"))
+ (const_int 0)))
+ (clobber (match_scratch:HI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+ "xor{w}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "HI")])
+
(define_expand "xorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "")
(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
***************
*** 5597,5602 ****
--- 5862,5880 ----
(xor:QI (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCNOmode)
&& ix86_binary_operator_ok (XOR, QImode, operands)"
+ "xor{b}\\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "QI")])
+
+ (define_insn "*xorqi_cc_2"
+ [(set (reg 17)
+ (compare
+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
+ (match_operand:QI 2 "general_operand" "qim"))
+ (const_int 0)))
+ (clobber (match_scratch:QI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"xor{b}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
(set_attr "mode" "QI")])