Reload pass ignores constraints. Why?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi.

Working out recommendations for a new instruction set architecture (no silicon yet), I run into the following problem with a port based on gcc_4_3_3_release: postreload complains

error: insn does not satisfy its constraints:
(insn 1636 1635 410 35 k_rem_pio2.c:816 (set (reg:SI 28 a12)
        (lshiftrt:SI (reg:SI 28 a12)
            (const_int 8 [0x8]))) 22 {lshrsi3} (nil))
k_rem_pio2.c:910: internal compiler error: in reload_cse_simplify_operands, at postreload.c:395

The reason is obvious: Pass greg chooses reg a12 which is not in class "d" as required by this insn:

(define_insn "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "=d ,d ,d") (lshiftrt:SI (match_operand:SI 1 "register_operand" "d ,0 ,d") (match_operand:SI 2 "reg_or_u5_operand" "d ,Ku4 ,Ku5")))]
  ""
  "...")

"Ku4" is an unsigned 4-bit constant, "Ku5" likewise.
The register set consists of two disjoint register classes "a" and "d":
a-regs are used to access memory, address arithmetic, etc.
d-regs are used to perform arithmetic
Both classes allow SImode=Pmode, a12 is an element of "a".

In pass lreg everything is all right:

*lreg*
(insn:HI 408 202 409 17 k_rem_pio2.c:816 (set (reg:SI 569)
(const_int -1 [0xffffffff])) 2 {*movsi_insn} (expr_list:REG_EQUIV (const_int -1 [0xffffffff])
        (nil)))

(insn:HI 409 408 400 17 k_rem_pio2.c:816 (set (reg:SI 570)
        (lshiftrt:SI (reg:SI 569)
(const_int 8 [0x8]))) 22 {lshrsi3} (expr_list:REG_EQUIV (const_int 16777215 [0xffffff])
        (expr_list:REG_DEAD (reg:SI 569)
            (nil))))

This is the cheapest way to load the desired constant 0xffffff into a register: load -1 and shift it right by 8. The sequence was expanded in pass expand. But despite the constraints "d" in the insns, greg allocates a12:

*greg*
(insn 1635 407 1636 35 k_rem_pio2.c:816 (set (reg:SI 28 a12)
        (const_int -1 [0xffffffff])) 2 {*movsi_insn} (nil))

(insn 1636 1635 410 35 k_rem_pio2.c:816 (set (reg:SI 28 a12)
        (lshiftrt:SI (reg:SI 28 a12)
            (const_int 8 [0x8]))) 22 {lshrsi3} (nil))

movsi knows how to move all kinds of memory, registers and constants. There is no secondary reload needed to copy from "a" to "d" or from "d" to "a". -1 is allright for both "a" and "d". The classes are big enough so that CLASS_LIKELY_SPILLED_P is false for them. PREFERRED_(OUTPUT_)RELOAD_CLASS does nothing.

According to GCC internals this should work without any problems:

> Any operand expression can be reloaded by copying it into a register.
> So if an operand's constraints allow some kind of register, it is
> certain to be safe.  It need not permit all classes of registers; the
> compiler knows how to copy a register into another register of the
> proper class in order to make an instruction valid.

What am I missing? Would be great if some expert could give me a hint.

I browsed SVN for bug fixes in reload/ira, but no fix seems to address this problem. Is therer a problem with REG_EQUIV notes that make reload blindly take some register?

To give it a try I also defined a "d_register_operand" predicate which leads to "unrecognizable insn", just as I expected...

Thanks very mutch

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux