On m68k, int % CONST is expanded to contain this insn:

(insn 6 5 7 3 (parallel [
            (set (reg:SI 35)
                (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (reg/v:SI 33 
[ a ]))
                            (const_int -2004318071 [0x88888889]))
                        (const_int 32 [0x20]))))
            (clobber (reg:SI 36))
        ]) mulsl.c:4 -1
     (nil))

which correspondents to this pattern:

(define_insn "const_smulsi3_highpart"
  [(set (match_operand:SI 0 "register_operand" "=d")
        (truncate:SI
         (lshiftrt:DI
          (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1"))
                   (match_operand:DI 3 "const_sint32_operand" "n"))
          (const_int 32))))
   (clobber (match_operand:SI 1 "register_operand" "=d"))]
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
  "muls%.l %3,%0:%1")

When regrename runs it turns it into this:

(insn 6 27 7 2 (parallel [
            (set (reg:SI 1 %d1 [35])
                (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 1 
%d1 [36]))
                            (const_int -2004318071 [0x88888889]))
                        (const_int 32 [0x20]))))
            (clobber (reg:SI 1 %d1 [36]))
        ]) mulsl.c:4 192 {const_smulsi3_highpart}
     (expr_list:REG_UNUSED (reg:SI 1 %d1 [36])
        (nil)))

Note that both output operands are allocated to the same register (which
generates a muls.l producing undefined results).  Is this transformation
actually valid?  I can stop regrename from doing this by marking operand
0 as earlyclobber, but the insn doesn't actually write the outputs
before reading the inputs, the issue is the dependency between the
outputs.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

Reply via email to