This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Unable to match instruction pattern


Found it ...

I had

(define_expand "zero_extendhisi2"
    [
        (set (subreg:HI (match_operand:SI 0 "general_operand" "")0)
                        (match_operand:HI 1 "general_operand" ""))
        (set (subreg:HI (match_dup 0)2)
                        (const_int 0))
    ]
""
""
)

which creates the subregs and performs the zero extension in a cpu agnostic manner... possibly leaving the contents of registers known and available for future use by optimizations. I was caught by this ...

gcc trunk
recog.c:1016
/* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory may result in incorrect reference. We should simplify all valid
         subregs of MEM anyway.  But allow this after reload because we
	 might be called from cleanup_subreg_operands.

	 ??? This is a kludge.  */
      if (!reload_completed && SUBREG_BYTE (op) != 0
	  && MEM_P (sub))
	return 0;

Which causes failure to recognize the second "(set (subeg...))" as a mov<> expansion. I used gdb to set reload_completed true temporarily and the correct match to mov<> was found and correct code generated. I don't know if the mentioned kludge refers to the need to avoid other than suibreg(() 0 ) or to the fact that more elegant alignment checking could be used to allow valid subreg constructs.

So, I replaced my (define_expand "zero_extendhisi2") with a cpu specific ((define_insn "zero_extendhisi2") which works but doesn't expose as much info for post reload cleanup.

Paul.


El 09/04/14 00:23, Paul Shortis escribiÃ:
I'm porting gcc to a 16 bit processor. Occasionally compiling source
such as

short v1;
long global;

....

global = (long)v1;

results in ...

(insn 11 10 12 2 (set (subreg:HI (mem/c:SI (symbol_ref:HI ("global")
<var_decl 0xb7076000 global>) [2 global+0 S4 A16]) 2)
        (const_int 0 [0])) t.c:15 -1
     (nil))
(insn 12 11 13 2 (set (subreg:HI (mem/c:SI (symbol_ref:HI ("global")
<var_decl 0xb7076000 global>) [2 global+0 S4 A16]) 0)
        (reg:HI 24 [ D.1348 ])) t.c:15 -1
     (nil))

The second of these instructions successfully matches a movhi pattern
which is found via the define_expand below

;the INTEGER iterator includes [QI HI SI]
(define_expand "mov<mode>"
  [(set (match_operand:INTEGER 0 "nonimmediate_operand" "")
    (match_operand:INTEGER 1 "general_operand" ""))]
  ""
  {
    if( can_create_pseudo_p() )
    {
            if( !register_operand( operands[0], <MODE>mode )
                && !register_operand( operands[1], <MODE>mode ))
            {
              /* one of the operands must be in a register.  */
operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
            }
     }


However the first instruction fails to match and be expanded so that
the const_int is forced into a register. I defined an instruction
which is an exact match

(define_insn "*storesic"
  [
    (set (subreg:HI (mem:SI (match_operand:HI 0 "symbol_ref_operand"
"")) 2)
                    (match_operand:HI 1 "const_int_operand"))
  ]

This matches, however I need a scratch register (R? below) to
transform this into

        load    R?, const_int_operand
        store R?, address

and as soon as I add the match_scratch

    (clobber(match_scratch:HI 2 "=r"))


the pattern no longer matches because expand calls recog() with
pnum_clobbers = 0 (NULL)

I a similar vein to the way CC setting instructions are handled I
tried defining a  second instruction containing the required
match_scratch prior to the define_insn "*storesic" (see above) in the
hope that it may match subsequent to the expand pass, however it is
never seen.

Can anyone offer any insight to what I'm doing wrong and how I might
proceed ?

Thanks, Paul.














Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]