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