This is the mail archive of the gcc-patches@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: [PATCH] operands_match_p for multiple hard registers


>>>>> Richard Henderson writes:

Richard> Would you like to describe the actual problem?

	A particular test case using the rs6000 long double format
produces the following failure:

bad.c:21: error: could not split insn
(insn 17 55 53 (set (reg/v:DF 33 f1 [orig:118 doubleValue ] [118])
         (float_truncate:DF (reg:TF 32 f0 [orig:122 longDoubleValue ] 
[122]))) 347 {trunctfdf2_internal1} (insn_list:REG_DEP_TRUE 16 (nil))
     (expr_list:REG_DEAD (reg:DI 32 f0)
         (nil)))
bad.c:21: internal compiler error: in final_scan_insn, at final.c:2500

The problem is that recog.c:constrain_operands() chooses an alternative
that requires matching operands, but the two operands differ.  The operand
part of the pattern looks like:

  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f")
        (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))]

reload.c:operands_match_p() is called with (reg:DF 33) and (reg:TF 32).
The code for multiple hard register groups triggers for TFmode:

      i = REGNO (x);  /* i = 33 */
      j = REGNO (y);  /* j = 32 */
...
      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
          && j < FIRST_PSEUDO_REGISTER)
        j += hard_regno_nregs[j][GET_MODE (y)] - 1;

j is incremented to 33.

      return i == j;

operands_match_p returns true for operands that differ and
constrain_operands() chooses an invalid alternative.

	GCC uses the lowest numbered register to reference multiple hard
register groups.  On a 32-bit target, (reg:DI x) refers to concatenation
of register numbers x:x+1; (reg:TI x) refers to concatenation of register
numbers x:x+1:x+2:x+3.  On a target with 64-bit FPRs that holds TFmode in
a pair of hard registers, (reg:TF x) refers to concatenation of register
numbers x:x+1.

	Maybe I am not thinking creatively enough, but comparing the
highest numbered register of a group of hard registers for two different
modes in the context of matching operands only makes sense to me if one
expects the least significant bits to conform to one another, which
implies an integer mode.

	If you think that CANNOT_CHANGE_MODE_CLASS is the more appropriate
test, it can be used, but it is a more invasive change because the macro
is optional, CLASS would need to be manufactured, and the macro definition
needs to be tightened on PowerPC.

David


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