rs6000 geu/ltu patterns
Alan Modra
amodra@bigpond.net.au
Mon Mar 8 13:16:00 GMT 2004
All of the rs6000 insns using reg_or_neg_short_operand suffer from a
problem when the reg_or_neg_short_operand is a zero. All or these
patterns use "addic r1,r2,-constant" to set a carry when r2 is greater
or equal to "constant". That of course doesn't work for zero.
I was a little surprised to find that these comparisons against zero
were not optimized away, but the testcase demonstrates they still
exist. Perhaps something needs fixing in the machine independent parts
of gcc? Regardless, I think the rs6000 back-end needs this patch (or
perhaps a simpler one that modifies reg_or_neg_short_operand to exclude
zero).
PR target/14478
* config/rs6000/rs6000.md: Give all reg_or_neg_short_operand
constraints a zero alternative.
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.221.4.15
diff -u -p -r1.221.4.15 rs6000.md
--- gcc/config/rs6000/rs6000.md 8 Mar 2004 08:09:09 -0000 1.221.4.15
+++ gcc/config/rs6000/rs6000.md 8 Mar 2004 12:38:45 -0000
@@ -12355,31 +12357,34 @@
[(set_attr "length" "12")])
(define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
+ (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P")))]
"TARGET_32BIT"
"@
+ {cal %0,0(0)|li %0,0}
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
- [(set_attr "length" "12")])
+ [(set_attr "length" "4,12,12")])
(define_insn ""
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
- (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
+ (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
(ltu:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT"
"@
+ andc. %0,%0,%0
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "12,12,16,16")])
+ (set_attr "length" "4,12,12,8,16,16")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
@@ -12398,32 +12403,36 @@
"")
(define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
- (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
- (match_operand:SI 3 "reg_or_short_operand" "rI,rI")))]
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,&r,&r")
+ (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,O,r,P"))
+ (match_operand:SI 3 "reg_or_short_operand" "r,I,rI,rI")))]
"TARGET_32BIT"
"@
- {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3
- {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3"
- [(set_attr "length" "12")])
+ mr %0,%3
+ {cal %0,%3(0)|li %0,%3}
+ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3
+ {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3"
+ [(set_attr "length" "4,4,12,12")])
(define_insn ""
- [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
- (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
- (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+ (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P"))
+ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
+ (clobber (match_scratch:SI 4 "=X,&r,&r,&r,&r,&r"))]
"TARGET_32BIT"
"@
+ {cmpi|cmpwi} %0,%3,0
{sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
{ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "12,12,16,16")])
+ (set_attr "length" "4,12,12,8,16,16")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
@@ -12443,22 +12452,24 @@
"")
(define_insn ""
- [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
- (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
- (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+ (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P"))
+ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,&r,r,&r,&r")
(plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"TARGET_32BIT"
"@
+ mr. %0,%3
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "12,12,16,16")])
+ (set_attr "length" "4,12,12,8,16,16")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
@@ -12478,14 +12489,15 @@
"")
(define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
+ (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P"))))]
"TARGET_32BIT"
"@
+ {cal %0,0(0)|li %0,0}
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
- [(set_attr "length" "8")])
+ [(set_attr "length" "4,8,8")])
(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -12613,41 +12625,45 @@
[(set_attr "length" "12")])
(define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
+ (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P")))]
"TARGET_32BIT"
"@
+ {cal %0,1(0)|li %0,1}
{sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
{ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
- [(set_attr "length" "12")])
+ [(set_attr "length" "4,12,12")])
(define_insn ""
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
- (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
- (match_operand:DI 2 "reg_or_neg_short_operand" "r,P")))]
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
+ (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r")
+ (match_operand:DI 2 "reg_or_neg_short_operand" "O,r,P")))]
"TARGET_64BIT"
"@
+ li %0,1
subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0
addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0"
- [(set_attr "length" "12")])
+ [(set_attr "length" "4,12,12")])
(define_insn ""
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
- (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
+ (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
(geu:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT"
"@
+ {cal %0,1(0)|li %0,1}\n;{cmpi|cmpwi} %3,%0,0
{sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
{ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "12,12,16,16")])
+ (set_attr "length" "8,12,12,8,16,16")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
@@ -12666,21 +12682,23 @@
"")
(define_insn ""
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
- (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:DI 2 "reg_or_neg_short_operand" "r,P,r,P"))
+ (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:DI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P"))
(const_int 0)))
- (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
(geu:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT"
"@
+ li %0,1\n;cmpdi %3,%0,0
subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0
addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "12,12,16,16")])
+ (set_attr "length" "8,12,12,8,16,16")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
@@ -12699,32 +12717,36 @@
"")
(define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
- (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
- (match_operand:SI 3 "gpc_reg_operand" "r,r")))]
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,&r,&r")
+ (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,O,r,P"))
+ (match_operand:SI 3 "gpc_reg_operand" "b,r,r,r")))]
"TARGET_32BIT"
"@
+ {cal %0,1(%3)|addi %0,%3,1}
+ {ai|addic} %0,%3,1
{sf|subfc} %0,%2,%1\;{aze|addze} %0,%3
{ai|addic} %0,%1,%n2\;{aze|addze} %0,%3"
- [(set_attr "length" "8")])
+ [(set_attr "length" "4,4,8,8")])
(define_insn ""
- [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
- (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
- (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+ (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P"))
+ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
+ (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r"))]
"TARGET_32BIT"
"@
+ {ai.|addic.} %4,%3,1
{sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
{ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "8,8,12,12")])
+ (set_attr "length" "4,8,8,8,12,12")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
@@ -12744,22 +12766,24 @@
"")
(define_insn ""
- [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
- (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
- (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+ (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P"))
+ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,&r,r,&r,&r")
(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"TARGET_32BIT"
"@
+ {ai.|addic.} %0,%3,1
{sf|subfc} %0,%2,%1\;{aze.|addze.} %0,%3
{ai|addic} %0,%1,%n2\;{aze.|addze.} %0,%3
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "8,8,12,12")])
+ (set_attr "length" "4,8,8,8,12,12")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
@@ -12789,34 +12813,37 @@
[(set_attr "length" "12")])
(define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,&r")
(and:SI (neg:SI
- (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
- (match_operand:SI 3 "gpc_reg_operand" "r,r")))]
+ (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P")))
+ (match_operand:SI 3 "gpc_reg_operand" "r,r,r")))]
"TARGET_32BIT"
"@
+ mr %0,%3
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0"
- [(set_attr "length" "12")])
+ [(set_attr "length" "4,12,12")])
(define_insn ""
- [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
(and:SI (neg:SI
- (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
- (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+ (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P")))
+ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
+ (clobber (match_scratch:SI 4 "=X,&r,&r,&r,&r,&r"))]
"TARGET_32BIT"
"@
+ {cmpi|cmpwi} %0,%3,0
{sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
{ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "12,12,16,16")])
+ (set_attr "length" "4,12,12,8,16,16")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
@@ -12837,23 +12864,25 @@
"")
(define_insn ""
- [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
+ [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC
(and:SI (neg:SI
- (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
- (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+ (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "O,r,P,O,r,P")))
+ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,&r,r,&r,&r")
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
"TARGET_32BIT"
"@
+ mr. %0,%3
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
#
+ #
#"
[(set_attr "type" "compare")
- (set_attr "length" "12,12,16,16")])
+ (set_attr "length" "4,12,12,8,16,16")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
--
Alan Modra
IBM OzLabs - Linux Technology Centre
More information about the Gcc-patches
mailing list