This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Unnesting of nested subreg expressions
- From: Björn Haase <bjoern dot m dot haase at web dot de>
- To: gcc at gcc dot gnu dot org
- Date: Wed, 20 Apr 2005 00:09:12 +0200
- Subject: Unnesting of nested subreg expressions
Hi,
when working on removing avr's present monolithic SI-mode instruction patterns
by splitters after reload and lowering to QI modes after expand, I have
stepped over the following general issue:
The mid-end seems not to be able to simplify nested subreg expressions. I.e.
it seems that there is no known transformation
(subreg:QI (subreg:HI (reg:SI xx) 0) 0)
-> (subreg:QI (reg:SI xx) 0)
. I have stepped over the problem when replacing the avr-target's present
xorsi3 define_insn by a corresponding define_expand explicitly using 4
subregs, i.e. after replacing
(define_insn "xorhi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(xor:SI (match_operand:HI 1 "register_operand" "%0")
(match_operand:HI 2 "register_operand" "r")))]
""
"eor %0,%2
eor %B0,%B2"
[(set_attr "length" "2")
(set_attr "cc" "set_n")])
by
(define_expand "xorhi3"
[(set (subreg:QI (match_operand:HI 0 "register_operand" "=r") 0)
(xor:QI (subreg:QI (match_operand:HI 1 "register_operand" "%0") 0)
(subreg:QI (match_operand:HI 2 "register_operand" "r") 0)))
(set (subreg:QI (match_dup 0) 1)
(xor:QI (subreg:QI (match_dup 1) 1)
(subreg:QI (match_dup 2) 1)))]
""
"")
So far I had seen no regressions on the testsuite, however after adapting the
testcase gcc.c-torture/execute/200406029-1.c to compile also on int=16bits
targets, I am now getting an ICE. The error message reads:
/home/bmh/gnucvs/head/gcc/gcc/testsuite/gcc.c-torture/execute/20040629-1.c:139:
error: unrecognizable insn:
(insn 28 27 29 0 (set (subreg:QI (reg:HI 59) 0)
(xor:QI (subreg:QI (reg:HI 42) 0)
(subreg:QI (subreg:HI (reg/v:SI 41 [ x ]) 0) 0))) -1
(insn_list:REG_DEP_TRUE 68 (insn_list:REG_DEP_TRUE 3 (insn_list:REG_DEP_TRUE
27 (nil))))
(nil))
/home/bmh/gnucvs/head/gcc/gcc/testsuite/gcc.c-torture/execute/20040629-1.c:139:
internal compiler error: in extract_insn, at recog.c:2082
Please submit a full bug report,
with preprocessed source if appropriate.
The 20040629-1.c's bitfield operations generate HI mode subregs of SI mode
registers and these HI mode subregs are themselves passed to the HI->QI mode
expander. My question therefore is:
It seems that the cleanest solution would be to teach gcc how to unnest
subregs. Therefore my question: Is this possible and where would be the place
for doing this?
Yours,
Björn
BTW. I have stepped over a similar issue when using the gen_highpart and
gen_lowpart functions for splitters after reload. It sometimes happens that
one of these functions also gets a subreg expression as input operand while
not being able to handle it. Both functions seem to fail as well when they
are working on a label reference immediate operand. It seems that in their
present form gen_lowpart and gen_highpart should be used only in DI-SI-mode
splitters since then there is no danger that the DI mode expression itself is
a subreg of an even larger mode.