diff options
author | Alan Modra <amodra@bigpond.net.au> | 2005-11-28 03:52:01 +0000 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2005-11-28 14:22:01 +1030 |
commit | bf00cc0f1bcec18d171b241839ba13889c180e6f (patch) | |
tree | d889bface62f769703ebcef97eebe29b0a3db9a0 | |
parent | 24a62419d9fac12ffc4700d0a370fdf0922c718a (diff) | |
download | gcc-bf00cc0f1bcec18d171b241839ba13889c180e6f.zip gcc-bf00cc0f1bcec18d171b241839ba13889c180e6f.tar.gz gcc-bf00cc0f1bcec18d171b241839ba13889c180e6f.tar.bz2 |
re PR target/24997 (ICE with -ftree-vectorize)
PR target/24997
* config/rs6000/rs6000.c (legitimate_indexed_address_p): Allow pattern
generated by reload.
* config/rs6000/predicates.md (indexed_or_indirect_operand): Use
indexed_or_indirect_address.
(indexed_or_indirect_address): Don't test for base reg. Call
address_operand last. Make it a special predicate.
From-SVN: r107591
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 44 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 24 |
3 files changed, 47 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea11951..f4c260b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-11-28 Alan Modra <amodra@bigpond.net.au> + + PR target/24997 + * config/rs6000/rs6000.c (legitimate_indexed_address_p): Allow pattern + generated by reload. + * config/rs6000/predicates.md (indexed_or_indirect_operand): Use + indexed_or_indirect_address. + (indexed_or_indirect_address): Don't test for base reg. Call + address_operand last. Make it a special predicate. + 2005-11-27 Kazu Hirata <kazu@codesourcery.com> * config/m68k/m68k.c (notice_update_cc): Remove useless code. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 2b0716e..26f46a0 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -353,25 +353,6 @@ || reload_in_progress, mode, XEXP (op, 0))"))) -;; Return 1 if the operand is an indexed or indirect memory operand. -(define_predicate "indexed_or_indirect_operand" - (match_operand 0 "memory_operand") -{ - rtx tmp = XEXP (op, 0); - - if (TARGET_ALTIVEC - && ALTIVEC_VECTOR_MODE (mode) - && GET_CODE (tmp) == AND - && GET_CODE (XEXP (tmp, 1)) == CONST_INT - && INTVAL (XEXP (tmp, 1)) == -16) - tmp = XEXP (tmp, 0); - - return REG_P (tmp) - || (GET_CODE (tmp) == PLUS - && REG_P (XEXP (tmp, 0)) - && REG_P (XEXP (tmp, 1))); -}) - ;; Return 1 if the operand is a memory operand with an address divisible by 4 (define_predicate "word_offset_memref_operand" (and (match_operand 0 "memory_operand") @@ -380,13 +361,28 @@ || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT || INTVAL (XEXP (XEXP (op, 0), 1)) % 4 == 0"))) +;; Return 1 if the operand is an indexed or indirect memory operand. +(define_predicate "indexed_or_indirect_operand" + (match_code "mem") +{ + op = XEXP (op, 0); + if (TARGET_ALTIVEC + && ALTIVEC_VECTOR_MODE (mode) + && GET_CODE (op) == AND + && GET_CODE (XEXP (op, 1)) == CONST_INT + && INTVAL (XEXP (op, 1)) == -16) + op = XEXP (op, 0); + + return indexed_or_indirect_address (op, mode); +}) + ;; Return 1 if the operand is an indexed or indirect address. -(define_predicate "indexed_or_indirect_address" - (and (match_operand 0 "address_operand") - (match_test "REG_P (op) +(define_special_predicate "indexed_or_indirect_address" + (and (match_test "REG_P (op) || (GET_CODE (op) == PLUS - && REG_P (XEXP (op, 0)) - && REG_P (XEXP (op, 1)))"))) + /* Omit testing REG_P (XEXP (op, 0)). */ + && REG_P (XEXP (op, 1)))") + (match_operand 0 "address_operand"))) ;; Used for the destination of the fix_truncdfsi2 expander. ;; If stfiwx will be used, the result goes to memory; otherwise, diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d8d00a5..d013916 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2731,13 +2731,23 @@ legitimate_indexed_address_p (rtx x, int strict) op0 = XEXP (x, 0); op1 = XEXP (x, 1); - if (!REG_P (op0) || !REG_P (op1)) - return false; - - return ((INT_REG_OK_FOR_BASE_P (op0, strict) - && INT_REG_OK_FOR_INDEX_P (op1, strict)) - || (INT_REG_OK_FOR_BASE_P (op1, strict) - && INT_REG_OK_FOR_INDEX_P (op0, strict))); + if (REG_P (op0) && REG_P (op1)) + return ((INT_REG_OK_FOR_BASE_P (op0, strict) + && INT_REG_OK_FOR_INDEX_P (op1, strict)) + || (INT_REG_OK_FOR_BASE_P (op1, strict) + && INT_REG_OK_FOR_INDEX_P (op0, strict))); + + /* Recognize the rtl generated by reload which we know will later be + replaced by a base reg. We rely on nothing but reload generating + this particular pattern, a reasonable assumption because it is not + canonical. */ + else if (reload_in_progress + && GET_CODE (op0) == PLUS + && REG_P (XEXP (op0, 0)) + && GET_CODE (XEXP (op0, 1)) == CONST_INT + && REG_P (op1)) + return INT_REG_OK_FOR_INDEX_P (op1, strict); + return false; } inline bool |