diff mbox

[RS6000] VSX splat fix

Message ID 20121010024715.GO25219@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra Oct. 10, 2012, 2:47 a.m. UTC
This fixes a problem with my PR45844 fix.  PR45844 was due to rs6000.c
reg_offset_addressing_ok_p testing the operand mode to determine
whether an insn supports reg+offset addressing, but the VSX splat insn
uses a DF/DI mode input operand.  So the memory form of this insn was
wrongly seen to support reg+offset addressing.  I hacked around this
by adjusting the mode in the insn predicate, which happened to work
for the PR45844 testcase, but actually causes the predicate to reject
all MEMs since general_operand checks that the mode matches.  (Oddly,
this does not stop reload using the memory form of the insn!
const_double passes the predicate, reload forces to mem which matches
one of the constraints, and the predicate is not checked again.)

This avoids the general_operand mode check by expanding code from
there relevant to MEMs.  Bootstrapped and regression tested
powerpc64-linux.  OK for mainline and 4.6/4.7?

	* config/rs6000/predicates.md (splat_input_operand): Don't call
	input_operand for MEMs.  Instead check for volatile and call
	memory_address_addr_space_p with modified mode.

Comments

David Edelsohn Oct. 10, 2012, 3:26 p.m. UTC | #1
On Tue, Oct 9, 2012 at 10:47 PM, Alan Modra <amodra@gmail.com> wrote:
> This fixes a problem with my PR45844 fix.  PR45844 was due to rs6000.c
> reg_offset_addressing_ok_p testing the operand mode to determine
> whether an insn supports reg+offset addressing, but the VSX splat insn
> uses a DF/DI mode input operand.  So the memory form of this insn was
> wrongly seen to support reg+offset addressing.  I hacked around this
> by adjusting the mode in the insn predicate, which happened to work
> for the PR45844 testcase, but actually causes the predicate to reject
> all MEMs since general_operand checks that the mode matches.  (Oddly,
> this does not stop reload using the memory form of the insn!
> const_double passes the predicate, reload forces to mem which matches
> one of the constraints, and the predicate is not checked again.)
>
> This avoids the general_operand mode check by expanding code from
> there relevant to MEMs.  Bootstrapped and regression tested
> powerpc64-linux.  OK for mainline and 4.6/4.7?
>
>         * config/rs6000/predicates.md (splat_input_operand): Don't call
>         input_operand for MEMs.  Instead check for volatile and call
>         memory_address_addr_space_p with modified mode.

Okay in trunk and GCC 4.7.  I guess I don't see a cleaner solution.

Thanks, David
diff mbox

Patch

Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 192236)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -941,12 +941,16 @@ 
 {
   if (MEM_P (op))
     {
+      if (! volatile_ok && MEM_VOLATILE_P (op))
+	return 0;
       if (mode == DFmode)
 	mode = V2DFmode;
       else if (mode == DImode)
 	mode = V2DImode;
       else
-	gcc_unreachable ();        
+	gcc_unreachable ();
+      return memory_address_addr_space_p (mode, XEXP (op, 0),
+					  MEM_ADDR_SPACE (op));
     }
   return input_operand (op, mode);
 })