diff options
author | Eric Botcazou <ebotcazou@libertysurf.fr> | 2004-05-31 23:34:26 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2004-05-31 21:34:26 +0000 |
commit | a4a90b847aac34b2cbede88ffeef45343214d066 (patch) | |
tree | d91d56afe424dca67642ecfc22d5d221aeaf7799 /gcc | |
parent | c8b2e872a83dd3869ffc4443201a1f3096bc3a6c (diff) | |
download | gcc-a4a90b847aac34b2cbede88ffeef45343214d066.zip gcc-a4a90b847aac34b2cbede88ffeef45343214d066.tar.gz gcc-a4a90b847aac34b2cbede88ffeef45343214d066.tar.bz2 |
re PR target/15693 (ICE - unrecognizable insn)
PR target/15693
* config/sparc/sparc.c (compare_operand): New predicate.
* config/sparc/sparc.h (PREDICATE_CODES): Add it.
* config/sparc/sparc.md (cmpsi expander): Use it. If the first
operand is a ZERO_EXTRACT and the second operand is not zero,
force the former to a register.
(cmpdi expander): Likewise.
From-SVN: r82500
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 26 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 1 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/sparc-trap-1.c | 20 |
6 files changed, 69 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 14b1c41..318d3bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-05-31 Eric Botcazou <ebotcazou@libertysurf.fr> + + PR target/15693 + * config/sparc/sparc.c (compare_operand): New predicate. + * config/sparc/sparc.h (PREDICATE_CODES): Add it. + * config/sparc/sparc.md (cmpsi expander): Use it. If the first + operand is a ZERO_EXTRACT and the second operand is not zero, + force the former to a register. + (cmpdi expander): Likewise. + 2004-05-31 Geoffrey Keating <geoffk@apple.com> * gengtype-lex.l: Catch stray GTY markers in the files gengtype diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 278ca9a..30fbb87 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -1348,6 +1348,32 @@ input_operand (rtx op, enum machine_mode mode) return 0; } +/* Return 1 if OP is valid for the lhs of a compare insn. */ + +int +compare_operand (rtx op, enum machine_mode mode) +{ + if (GET_CODE (op) == ZERO_EXTRACT) + return (register_operand (XEXP (op, 0), mode) + && small_int_or_double (XEXP (op, 1), mode) + && small_int_or_double (XEXP (op, 2), mode) + /* This matches cmp_zero_extract. */ + && ((mode == SImode + && ((GET_CODE (XEXP (op, 2)) == CONST_INT + && INTVAL (XEXP (op, 2)) > 19) + || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE + && CONST_DOUBLE_LOW (XEXP (op, 2)) > 19))) + /* This matches cmp_zero_extract_sp64. */ + || (mode == DImode + && TARGET_ARCH64 + && ((GET_CODE (XEXP (op, 2)) == CONST_INT + && INTVAL (XEXP (op, 2)) > 51) + || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE + && CONST_DOUBLE_LOW (XEXP (op, 2)) > 51))))); + else + return register_operand (op, mode); +} + /* We know it can't be done in one insn when we get here, the movsi expander guarantees this. */ diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 33c1256..3e0b1c9 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -2612,6 +2612,7 @@ do { \ {"uns_arith_operand", {SUBREG, REG, CONST_INT}}, \ {"clobbered_register", {REG}}, \ {"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}}, \ +{"compare_operand", {SUBREG, REG, ZERO_EXTRACT}}, \ {"const64_operand", {CONST_INT, CONST_DOUBLE}}, \ {"const64_high_operand", {CONST_INT, CONST_DOUBLE}}, \ {"tgd_symbolic_operand", {SYMBOL_REF}}, \ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 130d58c..b6e45e8 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -299,10 +299,13 @@ (define_expand "cmpsi" [(set (reg:CC 100) - (compare:CC (match_operand:SI 0 "register_operand" "") + (compare:CC (match_operand:SI 0 "compare_operand" "") (match_operand:SI 1 "arith_operand" "")))] "" { + if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx) + operands[0] = force_reg (SImode, operands[0]); + sparc_compare_op0 = operands[0]; sparc_compare_op1 = operands[1]; DONE; @@ -310,10 +313,13 @@ (define_expand "cmpdi" [(set (reg:CCX 100) - (compare:CCX (match_operand:DI 0 "register_operand" "") + (compare:CCX (match_operand:DI 0 "compare_operand" "") (match_operand:DI 1 "arith_double_operand" "")))] "TARGET_ARCH64" { + if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx) + operands[0] = force_reg (DImode, operands[0]); + sparc_compare_op0 = operands[0]; sparc_compare_op1 = operands[1]; DONE; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 47ed126..19d8b06 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-05-31 Eric Botcazou <ebotcazou@libertysurf.fr> + + * gcc.dg/sparc-trap-1.c: New test. + 2004-05-31 Roger Sayle <roger@eyesopen.com> PR middle-end/15069 diff --git a/gcc/testsuite/gcc.dg/sparc-trap-1.c b/gcc/testsuite/gcc.dg/sparc-trap-1.c new file mode 100644 index 0000000..a516a88 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sparc-trap-1.c @@ -0,0 +1,20 @@ +/* PR target/15693 */ +/* { dg-do compile { target sparc*-*-* } } */ +/* { dg-options "-O2" } */ + +/* This used to fail on SPARC at -O2 because the combiner + produces a compare insn that was not rematched by the + compare expander. */ + +static __inline__ __attribute__ ((always_inline)) +int page_mapping (unsigned flags) +{ + if (1u & (flags >> 16)) + return 1; + return 0; +} +void install_page (unsigned flags) +{ + if (__builtin_expect (!page_mapping (flags), 0)) + __builtin_trap (); +} |