This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Use RTX_AUTOINC in rs6000 predicates.md
2009/7/14 David Edelsohn <dje.gcc@gmail.com>:
>> Like you said in your reply in the autoinc thread, this predicate could
>> be used with a new ia64-like constraint that asm writers can use. ?OTOH,
>> it might make sense for the new constraint to use the same condition as
>> the ia64 one, thus skipping the memory_operand check. ?We know that
>> reload will make every MEM legitimate, so for exclusive checks like this,
>> '(match_test "mem")' seems better than '(match_operand "memory_operand")'.
>> (I was just about to start on a patch for that.)
>>
>> I think this is probably just telling you back what you already said,
>> but the predicate's current name seems misleading; it accepts reg+reg
>> addresses whereas "o" doesn't. ?So as things stand, the FP conversion
>> patterns could in principle accept a non-offsettable memref that needs
>> to be reloaded into an offsettable one. ?(And the insns really do need
>> offsettable addresses.)
>>
>> So I was wondering about adding the new constraint with:
>>
>> ?(and (match_code "mem")
>> ? ? ? (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
>>
>> and rewriting offsettable_mem_operand to use offsettable_memref_p.
>
> I investigated the history from EGCS days and that seems reasonable.
As it turned out I needed another change. rs6000_mode_dependent_address_p
tries to check whether we can safely access subwords of a TFmode operand
(which I agree is the right given the current recog code, that's not the
problem). However, we treat any offset from virtual_stack_vars_rtx and
arg_pointer_rtx as legitimate before reload (which again seems good
given the way elimination works). But this means that any subword
of a TFmode access based on virtual_stack_vars_rtx or arg_pointer_rtx
is also legitimate, so we shouldn't treat the addresses as mode-dependent.
Or in rtl, things like:
(mem:TF (plus arg_pointer_rtx (const_int 0x20000)))
(mem:SI (plus arg_pointer_rtx (const_int 0x20000)))
(mem:QI (plus arg_pointer_rtx (const_int 0x2000F)))
are all OK, so they should not be treated as mode-dependent.
At the moment, none of them satisfy offsettable_nonstrict_memref_p.
After the change to the predicate, the split checks are redundant:
the operand always satisfies offsettable_nonstrict_memref_p.
Cross-tested on powerpc-ibm-aix6.1. OK to install?
Richard
gcc/
* config/rs6000/rs6000.c (rs6000_mode_dependent_address): Allow any
offset from virtual_stack_vars_rtx and arg_pointer_rtx.
* config/rs6000/predicates.md (volatile_mem_operand): Use
offsettable_nonstrict_memref_p.
* config/rs6000/rs6000.md (*floatsidf2_internal): Remove split check.
(*floatunssidf2_internal): Likewise.
(*fix_truncdfsi2_internal): Likewise.
(*fix_trunctfsi2_internal): Likewise.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c 2009-07-15 15:34:57.000000000 +0100
+++ gcc/config/rs6000/rs6000.c 2009-07-16 08:39:23.000000000 +0100
@@ -5165,7 +5165,15 @@ rs6000_mode_dependent_address (rtx addr)
switch (GET_CODE (addr))
{
case PLUS:
- if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
+ is considered a legitimate address before reload, so there
+ are no offset restrictions in that case. Note that this
+ condition is safe in strict mode because any address involving
+ virtual_stack_vars_rtx or arg_pointer_rtx would already have
+ been rejected as illegitimate. */
+ if (XEXP (addr, 0) != virtual_stack_vars_rtx
+ && XEXP (addr, 0) != arg_pointer_rtx
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT)
{
unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
return val + 12 + 0x8000 >= 0x10000;
Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md 2009-07-15 15:34:57.000000000 +0100
+++ gcc/config/rs6000/predicates.md 2009-07-16 08:31:34.000000000 +0100
@@ -367,9 +367,7 @@ (define_predicate "volatile_mem_operand"
;; Return 1 if the operand is an offsettable memory operand.
(define_predicate "offsettable_mem_operand"
(and (match_operand 0 "memory_operand")
- (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC
- && GET_CODE (XEXP (op, 0)) != PRE_DEC
- && GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
+ (match_test "offsettable_nonstrict_memref_p (op)")))
;; Return 1 if the operand is a memory operand with an address divisible by 4
(define_predicate "word_offset_memref_operand"
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md 2009-07-15 15:34:57.000000000 +0100
+++ gcc/config/rs6000/rs6000.md 2009-07-16 08:31:34.000000000 +0100
@@ -6354,7 +6354,7 @@ (define_insn_and_split "*floatsidf2_inte
(clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"#"
- "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
+ ""
[(pc)]
"
{
@@ -6421,7 +6421,7 @@ (define_insn_and_split "*floatunssidf2_i
(clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"#"
- "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
+ ""
[(pc)]
"
{
@@ -6488,7 +6488,7 @@ (define_insn_and_split "*fix_truncdfsi2_
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_DOUBLE_FLOAT"
"#"
- "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))"
+ ""
[(pc)]
"
{
@@ -9396,7 +9396,7 @@ (define_insn_and_split "*fix_trunctfsi2_
"!TARGET_IEEEQUAD
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"#"
- "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[5]))"
+ ""
[(pc)]
{
rtx lowword;