# Problem in the combiner

Christian Iseli chris@lslsun.epfl.ch
Mon Sep 29 00:55:00 GMT 1997

```> What are your predicates for the *com_opqi3_accu pattern?

The pattern is the following, (but I'm afraid that's beside the point...)

(define_insn "*com_opqi3_accu"
[(set (match_operand:QI 0 "general_operand" "=g")
(match_operator:QI 3 "commutative_operator"
[(match_operand:QI 1 "general_operand" "%g")
(match_operand:QI 2 "general_operand" "g")]))]
""
"*
{
return output_commutative(insn, operands);
}")

> Normally something like 'register_operand' is used, which would
> allow the (subreg:QI (reg:HI)) to be matched just like a (reg:QI).

Ah, I fear my message was not very clear.  The problem I'm trying to describe
is not that a pattern is not recognized.  The problem is that the combiner is unable
to combine three instructions together.  The three instructions look like this:
I1: (set (reg:HI 3 %r1) ...)
I2: (set (reg:HI 51) (some_op:HI (reg:HI 3 %r1) ...))
I3: (set (reg:QI) (other_op:QI (subreg:QI (reg:HI 51) 1)))

The combiner works in two steps: first I2 and I3 are combined and the result is then combined
with I1.  The problem hits midway: after I2 and I3 are combined, but before the
result is combined with I1.  The problem is that combining I2 and I3 creates a subreg
(subreg:QI (reg:HI 3 %r1) 1) which, since (reg:HI 3 %r1) is a hard register, is simplified
to (reg:QI 4 %r0).  The bad thing is that (reg:QI 4 %r0) does not appear in I1 and so
the combiner cannot do the replacement and fails.  The proposed patch puts back
(subreg:QI (reg:HI 3 %r1) 1) in the intermediate pattern so that the combiner can do
the right thing when combining with I1...

Let me know if my explanation is still unclear...

Christian

```