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]

i386 non-matching patterns


I am looking into why certain i386 patterns never seem to match:

(define_insn "*addsi3_carry"
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
		   (match_operand:SI 2 "general_operand" "ri,rm")))
   (clobber (reg:CC 17))]
  "ix86_binary_operator_ok (PLUS, SImode, operands)"
  "adc{l}\\t{%2, %0|%0, %2}"
  [(set_attr "type" "alu")
   (set_attr "pent_pair" "pu")
   (set_attr "mode" "SI")
   (set_attr "ppro_uops" "few")])

(define_insn "*addsi3_carry0"
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
	(plus:SI (ltu:SI (reg:CC 17) (const_int 0))
		 (match_operand:SI 1 "general_operand" "%0,0")))
   (clobber (reg:CC 17))]
  ""
  "*
{
  operands[2] = const0_rtx;
  return \"adc{l}\\t{%2, %0|%0, %2}\";
}"
  [(set_attr "type" "alu")
   (set_attr "pent_pair" "pu")
   (set_attr "mode" "SI")
   (set_attr "ppro_uops" "few")])

The first pattern here is in the current snapshots, the 2nd was added
by me as an experiments (it might need an ix86_binary_operator_ok
test, but that is beside the point).

None of these patterns seem to match, at least not for anything that I
have been able to come up with.  I debugged combine to see why they
are rejected.

try_combine will first delete the clobber from an incoming addsi_1.
With my experimental pattern, these two patterns,

(insn 36 9 38 (parallel[
            (set (reg:SI 46)
                (plus:SI (reg/v:SI 42)
                    (const_int 1 [0x1])))
            (clobber (reg:CC 17 flags))
        ] ) 118 {*addsi_1} (insn_list 4 (nil))
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))
(insn 39 38 24 (set (reg/v:SI 42)
     (if_then_else:SI (ltu (reg:CC 17 flags)
             (const_int 0 [0x0]))
         (reg:SI 46)
         (reg/v:SI 42))) 362 {*movsicc_noc} (insn_list 36 (insn_list 38 (nil)))
    (expr_list:REG_DEAD (reg:CC 17 flags)
        (expr_list:REG_DEAD (reg:SI 46)
            (nil))))

get combined into this pattern,

(set (reg/v:SI 42)
    (plus:SI (ltu:SI (reg:CC 17 flags)
            (const_int 0 [0x0]))
        (reg/v:SI 42)))

without the clobber.

In try_combine, we then come here:

  /* Note which hard regs this insn has as inputs.  */
  mark_used_regs_combine (newpat);

  /* Is the result of combination a valid instruction?  */
  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);

In mark_used_regs_combine, the register 17 (`flags') will be marked.
Then, when we are trying to match our new pattern, recog sets
num_clobbers_to_add to 1.  A PARALLEL is then formed, one that is
exactly what we want:

(parallel[
        (set (reg/v:SI 42)
            (plus:SI (ltu:SI (reg:CC 17 flags)
                    (const_int 0 [0x0]))
                (reg/v:SI 42)))
        (clobber (reg:CC 17 flags))
    ] )

But then strange things happen that makes this pattern be rejected.
A few lines further down we have this:

      for (i = XVECLEN (newpat, 0) - num_clobbers_to_add;
           i < XVECLEN (newpat, 0); i++)
        {
          if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG
=>            && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
            return -1;
          notes = gen_rtx_EXPR_LIST (REG_UNUSED,

here the naughty compiler rejects the pattern because register 17 is
marked in newpat_used_regs.

The requirement that clobbered hard regs may not be explicitly
mentioned in the combined pattern seems very strange.  Can somebody
please explain why this is needed?

-- 
Torbjörn

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