This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
reload problems on c4x target
- From: Herman ten Brugge <Haj dot Ten dot Brugge at net dot HCC dot nl>
- To: gcc at gcc dot gnu dot org
- Date: Sat, 2 Mar 2002 20:43:45 +0000 (WET)
- Subject: reload problems on c4x target
Hello,
This is my own analyses of bug report 4016:
compiler bug during reload on c4x target
This compiler bug happens with gcc (version 3.1 20020223) and testcase
gcc/testsuite/gcc.c-torture/execute/961213-1.c.
When this testcase is compiled with compiler options '-m30 -O3'. The result is:
961213-1.c:22: unable to generate reloads for:
(insn 20 19 21 (parallel[
(set (reg:QI 0 r0 [41])
(mem:QI (post_inc:QI (reg/f:QI 8 ar0 [40])) [0 S1 A32]))
(set (mem:QI (plus:QI (reg/f:QI 11 ar3)
(const_int 2 [02h])) [0 S1 A32])
(reg:QI 0 r0 [41]))
] ) 10 {movqi_parallel} (insn_list 141 (insn_list 17 (insn_list 18 (nil))))
(expr_list:REG_INC (reg/f:QI 8 ar0 [40])
(nil)))
My analyses:
I first have to explain some internal things about the c4x target. This
target has 3 main insn groups. All insns are 32 bit. This means that not all
addressing modes are fully suppoerted because we have to fit them into
the 32 bit insn.
The 3 insn groups are (only the address register offset is mentioned here):
2 opererand insns wich allow an offset of -255 .. 255
3 opererand insns wich allow an offset of 0 .. 32
parallel insns (4/6 operands) wich allow an offset of -1 .. 1
The input of reload is an instruction like (parallel insns):
(insn 20 19 21 (parallel[
(set (reg:QI 41)
(mem:QI (post_inc:QI (reg/f:QI 40)) 0))
(set (mem:QI (plus:QI (reg/f:QI 59)
(const_int 1 [01h])) 0)
(reg:QI 41))
] ) 10 {movqi_parallel} (insn_list 121 (insn_list 17 (insn_list 18 (nil))))
(expr_list:REG_INC (reg/f:QI 40)
(nil)))
Reload also finds an eliminable register that can replace the
'(reg/f:QI 59)' part of this insn.
The replace is '(plus:QI (reg/f:QI 11 ar3) (const_int 1 [01h]))'.
The insn now looks like the error report above.
Reload uses the macro GO_IF_LEGITIMATE_ADDRESS to check if it can change
the address in this insn. The result is OK because we allow +/- 255 as
offset and not +/- 1 (This is done because otherwise we would only have
an offset of +/- 1 for ALL insns). Now reload aborts because it can not
handle the parallel insns anymore.
The definition of this insn in the md file is:
(define_insn "movqi_parallel"
[(set (match_operand:QI 0 "parallel_operand" "=q,S<>!V,q,S<>!V")
(match_operand:QI 1 "parallel_operand" "S<>!V,q,S<>!V,q"))
(set (match_operand:QI 2 "parallel_operand" "=q,S<>!V,S<>!V,q")
(match_operand:QI 3 "parallel_operand" "S<>!V,q,q,S<>!V"))]
"TARGET_PARALLEL && valid_parallel_load_store (operands, QImode)"
"@
ldi1\\t%1,%0\\n||\\tldi2\\t%3,%2
sti1\\t%1,%0\\n||\\tsti2\\t%3,%2
ldi\\t%1,%0\\n||\\tsti\\t%3,%2
ldi\\t%3,%2\\n||\\tsti\\t%1,%0"
[(set_attr "type" "load_load,store_store,load_store,store_load")])
We only allow an offset of +/- 1 in the parallel_operand, the 'S' constraint
and the valid_parallel_load_store check. So reload could conclude that
the change performed is invalid.
To allow parallel insns on the c4x target I have disabled the call to
form_sum in reload.c and reload1.c. When I do this the problem disappears
because we never calculate the new sum.
How can we correctly fix this problem so we can use the parallel insns on the
c4x target.
Herman.