re PR middle-end/54685 ([SH] Improve unsigned int comparison with 0x7FFFFFFF)
PR target/54685 * config/sh/sh.md (one_cmplsi2): Make insn_and_split. Add manual combine matching for an insn sequence where a ge:SI pattern can be used. PR target/54685 * gcc.target/sh/pr54685.c: New. From-SVN: r192200
This commit is contained in:
parent
e28d52cffb
commit
f429813df1
4 changed files with 120 additions and 1 deletions
|
@ -1,3 +1,9 @@
|
|||
2012-10-08 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/54685
|
||||
* config/sh/sh.md (one_cmplsi2): Make insn_and_split. Add manual
|
||||
combine matching for an insn sequence where a ge:SI pattern can be used.
|
||||
|
||||
2012-10-08 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
PR c++/53528 C++11 attribute support
|
||||
|
|
|
@ -5189,11 +5189,61 @@ label:
|
|||
"neg %1,%0"
|
||||
[(set_attr "type" "arith")])
|
||||
|
||||
(define_insn "one_cmplsi2"
|
||||
(define_insn_and_split "one_cmplsi2"
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
|
||||
(not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
|
||||
"TARGET_SH1"
|
||||
"not %1,%0"
|
||||
"&& can_create_pseudo_p ()"
|
||||
[(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0)))
|
||||
(set (match_dup 0) (reg:SI T_REG))]
|
||||
{
|
||||
/* PR 54685
|
||||
If the result of 'unsigned int <= 0x7FFFFFFF' ends up as the following
|
||||
sequence:
|
||||
|
||||
(set (reg0) (not:SI (reg0) (reg1)))
|
||||
(parallel [(set (reg2) (lshiftrt:SI (reg0) (const_int 31)))
|
||||
(clobber (reg:SI T_REG))])
|
||||
|
||||
... match and combine the sequence manually in the split pass after the
|
||||
combine pass. Notice that combine does try the target pattern of this
|
||||
split, but if the pattern is added it interferes with other patterns, in
|
||||
particular with the div0s comparisons.
|
||||
This could also be done with a peephole but doing it here before register
|
||||
allocation can save one temporary.
|
||||
When we're here, the not:SI pattern obviously has been matched already
|
||||
and we only have to see whether the following insn is the left shift. */
|
||||
|
||||
rtx i = next_nonnote_insn_bb (curr_insn);
|
||||
if (i == NULL_RTX || !NONJUMP_INSN_P (i))
|
||||
FAIL;
|
||||
|
||||
rtx p = PATTERN (i);
|
||||
if (GET_CODE (p) != PARALLEL || XVECLEN (p, 0) != 2)
|
||||
FAIL;
|
||||
|
||||
rtx p0 = XVECEXP (p, 0, 0);
|
||||
rtx p1 = XVECEXP (p, 0, 1);
|
||||
|
||||
if (/* (set (reg2) (lshiftrt:SI (reg0) (const_int 31))) */
|
||||
GET_CODE (p0) == SET
|
||||
&& GET_CODE (XEXP (p0, 1)) == LSHIFTRT
|
||||
&& REG_P (XEXP (XEXP (p0, 1), 0))
|
||||
&& REGNO (XEXP (XEXP (p0, 1), 0)) == REGNO (operands[0])
|
||||
&& CONST_INT_P (XEXP (XEXP (p0, 1), 1))
|
||||
&& INTVAL (XEXP (XEXP (p0, 1), 1)) == 31
|
||||
|
||||
/* (clobber (reg:SI T_REG)) */
|
||||
&& GET_CODE (p1) == CLOBBER && REG_P (XEXP (p1, 0))
|
||||
&& REGNO (XEXP (p1, 0)) == T_REG)
|
||||
{
|
||||
operands[0] = XEXP (p0, 0);
|
||||
set_insn_deleted (i);
|
||||
}
|
||||
else
|
||||
FAIL;
|
||||
}
|
||||
[(set_attr "type" "arith")])
|
||||
|
||||
(define_expand "one_cmpldi2"
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2012-10-08 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/54685
|
||||
* gcc.target/sh/pr54685.c: New.
|
||||
|
||||
2012-10-08 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
PR c++/53528 C++11 attribute support
|
||||
|
|
58
gcc/testsuite/gcc.target/sh/pr54685.c
Normal file
58
gcc/testsuite/gcc.target/sh/pr54685.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* Check that a comparison 'unsigned int <= 0x7FFFFFFF' results in code
|
||||
utilizing the cmp/pz instruction. */
|
||||
/* { dg-do compile { target "sh*-*-*" } } */
|
||||
/* { dg-options "-O1" } */
|
||||
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
||||
/* { dg-final { scan-assembler-not "not" } } */
|
||||
/* { dg-final { scan-assembler-times "cmp/pz" 7 } } */
|
||||
/* { dg-final { scan-assembler-times "shll" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "movt" 4 } } */
|
||||
|
||||
int
|
||||
test_00 (unsigned int a)
|
||||
{
|
||||
return !(a > 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
int
|
||||
test_01 (unsigned int a)
|
||||
{
|
||||
return !(a > 0x7FFFFFFF) ? -5 : 10;
|
||||
}
|
||||
|
||||
int
|
||||
test_02 (unsigned int a)
|
||||
{
|
||||
/* 1x shll, 1x movt */
|
||||
return a >= 0x80000000;
|
||||
}
|
||||
|
||||
int
|
||||
test_03 (unsigned int a)
|
||||
{
|
||||
return a >= 0x80000000 ? -5 : 10;
|
||||
}
|
||||
|
||||
int
|
||||
test_04 (unsigned int a)
|
||||
{
|
||||
return a <= 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
int
|
||||
test_05 (unsigned int a)
|
||||
{
|
||||
return a <= 0x7FFFFFFF ? -5 : 10;
|
||||
}
|
||||
|
||||
int
|
||||
test_06 (unsigned int a)
|
||||
{
|
||||
return a < 0x80000000;
|
||||
}
|
||||
|
||||
int
|
||||
test_07 (unsigned int a)
|
||||
{
|
||||
return a < 0x80000000 ? -5 : 10;
|
||||
}
|
Loading…
Add table
Reference in a new issue