re PR c++/54988 (fpmath=sse target pragma causes inlining failure because of target specific option mismatch)

PR target/54988
	* config/sh/sh.md (tstqi_t_zero): Rename to *tstqi_t_zero.
	(*tst<mode>_t_zero): New insns.
	* config/sh/iterators.md (lowpart_be, lowpart_le): New mode attributes.

	PR target/54988
	* gcc.target/sh/pr53988.c: New.

From-SVN: r192982
This commit is contained in:
Oleg Endo 2012-10-30 09:07:08 +00:00
parent 3a8ebb9268
commit 197ddd06a0
5 changed files with 117 additions and 2 deletions

View file

@ -1,3 +1,10 @@
2012-10-30 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54988
* config/sh/sh.md (tstqi_t_zero): Rename to *tstqi_t_zero.
(*tst<mode>_t_zero): New insns.
* config/sh/iterators.md (lowpart_be, lowpart_le): New mode attributes.
2012-10-30 H.J. Lu <hongjiu.lu@intel.com>
* gimple-pretty-print.c (dump_gimple_bb_header): Avoid alloca.

View file

@ -38,3 +38,6 @@
;; Return codes.
(define_code_iterator any_return [return simple_return])
;; Lowpart subreg byte position code attributes for big and little endian.
(define_mode_attr lowpart_be [(QI "3") (HI "2")])
(define_mode_attr lowpart_le [(QI "0") (HI "0")])

View file

@ -633,13 +633,39 @@
;; Test low QI subreg against zero.
;; This avoids unnecessary zero extension before the test.
(define_insn "tstqi_t_zero"
(define_insn "*tstqi_t_zero"
[(set (reg:SI T_REG)
(eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
"TARGET_SH1"
"tst #255,%0"
[(set_attr "type" "mt_group")])
;; This pattern might be risky because it also tests the upper bits and not
;; only the subreg. However, it seems that combine will get to this only
;; when testing sign/zero extended values. In this case the extended upper
;; bits do not matter.
(define_insn "*tst<mode>_t_zero"
[(set (reg:SI T_REG)
(eq:SI
(subreg:QIHI
(and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
(match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_le>)
(const_int 0)))]
"TARGET_SH1 && TARGET_LITTLE_ENDIAN"
"tst %0,%1"
[(set_attr "type" "mt_group")])
(define_insn "*tst<mode>_t_zero"
[(set (reg:SI T_REG)
(eq:SI
(subreg:QIHI
(and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
(match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_be>)
(const_int 0)))]
"TARGET_SH1 && !TARGET_LITTLE_ENDIAN"
"tst %0,%1"
[(set_attr "type" "mt_group")])
;; Extract LSB, negate and store in T bit.
(define_insn "tstsi_t_and_not"
@ -3514,7 +3540,7 @@ label:
/* If it is possible to turn the and insn into a zero extension
already, redundant zero extensions will be folded, which results
in better code.
Ideally the splitter of *andsi_compact would be enough, if reundant
Ideally the splitter of *andsi_compact would be enough, if redundant
zero extensions were detected after the combine pass, which does not
happen at the moment. */
if (TARGET_SH1)

View file

@ -1,3 +1,8 @@
2012-10-30 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54988
* gcc.target/sh/pr53988.c: New.
2012-10-30 Bin Cheng <bin.cheng@arm.com>
PR target/54989

View file

@ -0,0 +1,74 @@
/* Check that the tst Rm,Rn instruction is generated for QImode and HImode
values loaded from memory. If everything goes as expected we won't see
any sign/zero extensions or and ops. On SH2A we don't expect to see the
movu insn. */
/* { dg-do compile { target "sh*-*-*" } } */
/* { dg-options "-O1" } */
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
/* { dg-final { scan-assembler-times "tst\tr" 8 } } */
/* { dg-final { scan-assembler-not "tst\t#255" } } */
/* { dg-final { scan-assembler-not "exts|extu|and|movu" } } */
int
test00 (char* a, char* b, int c, int d)
{
if (*a & *b)
return c;
return d;
}
int
test01 (unsigned char* a, unsigned char* b, int c, int d)
{
if (*a & *b)
return c;
return d;
}
int
test02 (short* a, short* b, int c, int d)
{
if (*a & *b)
return c;
return d;
}
int
test03 (unsigned short* a, unsigned short* b, int c, int d)
{
if (*a & *b)
return c;
return d;
}
int
test04 (char* a, short* b, int c, int d)
{
if (*a & *b)
return c;
return d;
}
int
test05 (short* a, char* b, int c, int d)
{
if (*a & *b)
return c;
return d;
}
int
test06 (int* a, char* b, int c, int d)
{
if (*a & *b)
return c;
return d;
}
int
test07 (int* a, short* b, int c, int d)
{
if (*a & *b)
return c;
return d;
}