aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2009-04-07 12:39:37 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2009-04-07 12:39:37 +0000
commitc3c64f5002375ee8e8c6264b633abdfbb866184f (patch)
treeddb1a455292b8f52dd722c3a8f9f3746a1f9c3d9
parent9a53bc17c486a122b5eb3570f2e1b374b5c35460 (diff)
downloadgcc-c3c64f5002375ee8e8c6264b633abdfbb866184f.zip
gcc-c3c64f5002375ee8e8c6264b633abdfbb866184f.tar.gz
gcc-c3c64f5002375ee8e8c6264b633abdfbb866184f.tar.bz2
optabs.c (can_compare_p): Test the predicate of a cbranch and cstore pattern.
2009-04-07 Paolo Bonzini <bonzini@gnu.org> * optabs.c (can_compare_p): Test the predicate of a cbranch and cstore pattern. From-SVN: r145667
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/optabs.c18
2 files changed, 18 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8c946eb..120dfc1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2009-04-07 Paolo Bonzini <bonzini@gnu.org>
+ * optabs.c (can_compare_p): Test the predicate of a
+ cbranch and cstore pattern.
+
+2009-04-07 Paolo Bonzini <bonzini@gnu.org>
+
* expr.c (convert_move): Use emit_store_flag instead of
"emulating" it.
diff --git a/gcc/optabs.c b/gcc/optabs.c
index f7e44db..7057d9f 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3980,8 +3980,12 @@ int
can_compare_p (enum rtx_code code, enum machine_mode mode,
enum can_compare_purpose purpose)
{
+ rtx test;
+ test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
do
{
+ int icode;
+
if (optab_handler (cmp_optab, mode)->insn_code != CODE_FOR_nothing)
{
if (purpose == ccp_jump)
@@ -3993,15 +3997,19 @@ can_compare_p (enum rtx_code code, enum machine_mode mode,
return 1;
}
if (purpose == ccp_jump
- && optab_handler (cbranch_optab, mode)->insn_code != CODE_FOR_nothing)
- return 1;
+ && (icode = optab_handler (cbranch_optab, mode)->insn_code) != CODE_FOR_nothing
+ && insn_data[icode].operand[0].predicate (test, mode))
+ return 1;
+ if (purpose == ccp_store_flag
+ && (icode = optab_handler (cstore_optab, mode)->insn_code) != CODE_FOR_nothing
+ && insn_data[icode].operand[1].predicate (test, mode))
+ return 1;
if (purpose == ccp_cmov
&& optab_handler (cmov_optab, mode)->insn_code != CODE_FOR_nothing)
return 1;
- if (purpose == ccp_store_flag
- && optab_handler (cstore_optab, mode)->insn_code != CODE_FOR_nothing)
- return 1;
+
mode = GET_MODE_WIDER_MODE (mode);
+ PUT_MODE (test, mode);
}
while (mode != VOIDmode);