aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2005-11-28 03:52:01 +0000
committerAlan Modra <amodra@gcc.gnu.org>2005-11-28 14:22:01 +1030
commitbf00cc0f1bcec18d171b241839ba13889c180e6f (patch)
treed889bface62f769703ebcef97eebe29b0a3db9a0
parent24a62419d9fac12ffc4700d0a370fdf0922c718a (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/config/rs6000/predicates.md44
-rw-r--r--gcc/config/rs6000/rs6000.c24
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