From bf00cc0f1bcec18d171b241839ba13889c180e6f Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 28 Nov 2005 03:52:01 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 10 ++++++++ gcc/config/rs6000/predicates.md | 44 +++++++++++++++------------------ gcc/config/rs6000/rs6000.c | 24 ++++++++++++------ 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea1195107a9e..f4c260bde14f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-11-28 Alan Modra + + 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 * 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 2b0716e658c9..26f46a0e0fd7 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 d8d00a5b0371..d013916a42e8 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 -- 2.47.2