Fix the shift patterns, and add test
Firstly, it adds back the split conditions that I accidentally removed. Without it the dot insns are never generated, or rather, always split back to a separate compare instruction. Secondly, the shift amount should be SI always, not GPR, or GCC will insert a zero-extend at expand time that it cannot get rid of later. The test tests whether dot-form instructions are generated for both "dot" and "dot2" cases, that is, with just a CC output or also a GPR output; for all four basic shifts, with a register amount or an immediate amount. It also tests for superfluous zero-extends. This also tests if combine "simplifies" the rotates to right-rotates, which it shouldn't do anymore. From-SVN: r212267
This commit is contained in:
parent
07b6c04483
commit
9e5f78f114
|
@ -1,3 +1,11 @@
|
|||
2014-07-03 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
* config/rs6000/rs6000.md (rotl<mode>3, ashl<mode>3, lshr<mode>3,
|
||||
ashr<mode>3): Correct mode of operands[2].
|
||||
(rotl<mode>3_dot, rotl<mode>3_dot2, ashl<mode>3_dot, ashl<mode>3_dot2,
|
||||
lshr<mode>3_dot, lshr<mode>3_dot2, ashr<mode>3_dot, ashr<mode>3_dot2):
|
||||
Correct mode of operands[2]. Fix split condition.
|
||||
|
||||
2014-07-03 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm.md (arch): Add armv6_or_vfpv3.
|
||||
|
|
|
@ -3874,7 +3874,7 @@
|
|||
(define_insn "rotl<mode>3"
|
||||
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||||
(rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn")))]
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn")))]
|
||||
""
|
||||
"rotl<wd>%I2 %0,%1,%<hH>2"
|
||||
[(set_attr "type" "shift")
|
||||
|
@ -3893,14 +3893,14 @@
|
|||
(define_insn_and_split "*rotl<mode>3_dot"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(const_int 0)))
|
||||
(clobber (match_scratch:GPR 0 "=r,r"))]
|
||||
"<MODE>mode == Pmode && rs6000_gen_cell_microcode"
|
||||
"@
|
||||
rotl<wd>%I2. %0,%1,%<hH>2
|
||||
#"
|
||||
"&& reload_completed"
|
||||
"&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
|
||||
[(set (match_dup 0)
|
||||
(rotate:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
|
@ -3916,7 +3916,7 @@
|
|||
(define_insn_and_split "*rotl<mode>3_dot2"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
|
||||
(rotate:GPR (match_dup 1)
|
||||
|
@ -3925,7 +3925,7 @@
|
|||
"@
|
||||
rotl<wd>%I2. %0,%1,%<hH>2
|
||||
#"
|
||||
"&& reload_completed"
|
||||
"&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
|
||||
[(set (match_dup 0)
|
||||
(rotate:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
|
@ -4353,7 +4353,7 @@
|
|||
(define_insn "ashl<mode>3"
|
||||
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||||
(ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn")))]
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn")))]
|
||||
""
|
||||
"sl<wd>%I2 %0,%1,%<hH>2"
|
||||
[(set_attr "type" "shift")
|
||||
|
@ -4372,14 +4372,14 @@
|
|||
(define_insn_and_split "*ashl<mode>3_dot"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(const_int 0)))
|
||||
(clobber (match_scratch:GPR 0 "=r,r"))]
|
||||
"<MODE>mode == Pmode && rs6000_gen_cell_microcode"
|
||||
"@
|
||||
sl<wd>%I2. %0,%1,%<hH>2
|
||||
#"
|
||||
"&& reload_completed"
|
||||
"&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
|
||||
[(set (match_dup 0)
|
||||
(ashift:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
|
@ -4395,7 +4395,7 @@
|
|||
(define_insn_and_split "*ashl<mode>3_dot2"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
|
||||
(ashift:GPR (match_dup 1)
|
||||
|
@ -4404,7 +4404,7 @@
|
|||
"@
|
||||
sl<wd>%I2. %0,%1,%<hH>2
|
||||
#"
|
||||
"&& reload_completed"
|
||||
"&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
|
||||
[(set (match_dup 0)
|
||||
(ashift:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
|
@ -4498,7 +4498,7 @@
|
|||
(define_insn "lshr<mode>3"
|
||||
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||||
(lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn")))]
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn")))]
|
||||
""
|
||||
"sr<wd>%I2 %0,%1,%<hH>2"
|
||||
[(set_attr "type" "shift")
|
||||
|
@ -4517,14 +4517,14 @@
|
|||
(define_insn_and_split "*lshr<mode>3_dot"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(const_int 0)))
|
||||
(clobber (match_scratch:GPR 0 "=r,r"))]
|
||||
"<MODE>mode == Pmode && rs6000_gen_cell_microcode"
|
||||
"@
|
||||
sr<wd>%I2. %0,%1,%<hH>2
|
||||
#"
|
||||
"&& reload_completed"
|
||||
"&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
|
||||
[(set (match_dup 0)
|
||||
(lshiftrt:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
|
@ -4540,7 +4540,7 @@
|
|||
(define_insn_and_split "*lshr<mode>3_dot2"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
|
||||
(lshiftrt:GPR (match_dup 1)
|
||||
|
@ -4549,7 +4549,7 @@
|
|||
"@
|
||||
sr<wd>%I2. %0,%1,%<hH>2
|
||||
#"
|
||||
"&& reload_completed"
|
||||
"&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
|
||||
[(set (match_dup 0)
|
||||
(lshiftrt:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
|
@ -4971,7 +4971,7 @@
|
|||
(define_expand "ashr<mode>3"
|
||||
[(set (match_operand:GPR 0 "gpc_reg_operand" "")
|
||||
(ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "")))]
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "")))]
|
||||
""
|
||||
{
|
||||
/* The generic code does not generate optimal code for the low word
|
||||
|
@ -4993,7 +4993,7 @@
|
|||
(define_insn "*ashr<mode>3"
|
||||
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||||
(ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn")))]
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn")))]
|
||||
""
|
||||
"sra<wd>%I2 %0,%1,%<hH>2"
|
||||
[(set_attr "type" "shift")
|
||||
|
@ -5012,14 +5012,14 @@
|
|||
(define_insn_and_split "*ashr<mode>3_dot"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(const_int 0)))
|
||||
(clobber (match_scratch:GPR 0 "=r,r"))]
|
||||
"<MODE>mode == Pmode && rs6000_gen_cell_microcode"
|
||||
"@
|
||||
sra<wd>%I2. %0,%1,%<hH>2
|
||||
#"
|
||||
"&& reload_completed"
|
||||
"&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
|
||||
[(set (match_dup 0)
|
||||
(ashiftrt:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
|
@ -5035,7 +5035,7 @@
|
|||
(define_insn_and_split "*ashr<mode>3_dot2"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:GPR 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
|
||||
(ashiftrt:GPR (match_dup 1)
|
||||
|
@ -5044,7 +5044,7 @@
|
|||
"@
|
||||
sra<wd>%I2. %0,%1,%<hH>2
|
||||
#"
|
||||
"&& reload_completed"
|
||||
"&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
|
||||
[(set (match_dup 0)
|
||||
(ashiftrt:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2014-07-03 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
* gcc.target/powerpc/shift-dot.c: New test.
|
||||
|
||||
2014-07-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||
|
||||
* gfortran.dg/ieee/ieee_1.F90: Mark variables as volatile to
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* Check that record-form instructions are used. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -mgen-cell-microcode" } */
|
||||
|
||||
/* { dg-final { scan-assembler-times {\mrotl[wd]\.} 2 } } */
|
||||
/* { dg-final { scan-assembler-times {\msl[wd]\.} 2 } } */
|
||||
/* { dg-final { scan-assembler-times {\msr[wd]\.} 2 } } */
|
||||
/* { dg-final { scan-assembler-times {\msra[wd]\.} 2 } } */
|
||||
|
||||
/* { dg-final { scan-assembler-times {\mrotl[wd]i\.} 2 } } */
|
||||
/* { dg-final { scan-assembler-times {\msl[wd]i\.} 2 } } */
|
||||
/* { dg-final { scan-assembler-times {\msr[wd]i\.} 2 } } */
|
||||
/* Combine converts the arith shift right compares to a (more expensive)
|
||||
direct compare. Luckily not the other shifts. XFAIL for now. */
|
||||
/* { dg-final { scan-assembler-times {\msra[wd]i\.} 2 { xfail *-*-* } } } */
|
||||
|
||||
/* There should not be any extends of the shift amount (or anything else). */
|
||||
/* { dg-final { scan-assembler-not {\mextsw\M} } } */
|
||||
/* { dg-final { scan-assembler-not {\mrldicl\M} } } */
|
||||
/* { dg-final { scan-assembler-not {\mclrldi\M} } } */
|
||||
/* { dg-final { scan-assembler-not {\mrlwinm\M} } } */
|
||||
|
||||
|
||||
typedef unsigned long u;
|
||||
typedef long s;
|
||||
#define M(n) (8 * sizeof(long) - (n))
|
||||
#define T1 if ((s)x > 0) g();
|
||||
#define T2 if ((s)x > 0) g(); return x;
|
||||
|
||||
void g(void);
|
||||
|
||||
void rot1(u x, u n) { x = (x << M(n)) | (x >> n); T1 }
|
||||
u rot2(u x, u n) { x = (x << M(n)) | (x >> n); T2 }
|
||||
void shl1(u x, u n) { x <<= n; T1 }
|
||||
u shl2(u x, u n) { x <<= n; T2 }
|
||||
void shr1(u x, u n) { x >>= n; T1 }
|
||||
u shr2(u x, u n) { x >>= n; T2 }
|
||||
void asr1(s x, u n) { x >>= n; T1 }
|
||||
s asr2(s x, u n) { x >>= n; T2 }
|
||||
|
||||
void rot1i(u x) { x = (x << M(23)) | (x >> 23); T1 }
|
||||
u rot2i(u x) { x = (x << M(23)) | (x >> 23); T2 }
|
||||
void shl1i(u x) { x <<= 23; T1 }
|
||||
u shl2i(u x) { x <<= 23; T2 }
|
||||
void shr1i(u x) { x >>= 23; T1 }
|
||||
u shr2i(u x) { x >>= 23; T2 }
|
||||
void asr1i(s x) { x >>= 23; T1 }
|
||||
s asr2i(s x) { x >>= 23; T2 }
|
Loading…
Reference in New Issue