validate subregs, part 6
Richard Henderson
rth@redhat.com
Wed Dec 1 19:14:00 GMT 2004
On Wed, Dec 01, 2004 at 06:22:03PM +0000, Joern RENNECKE wrote:
> optabs.c:expand_unop tries to expand the SFmode negate, and finds
> an DImode xor operation. It wants to generate an SFmode subreg
> of the SImode lowpart of a DImode register - which is perfectly fine
> for sh64 - but this fails because of your new check.
Try this.
r~
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.250
diff -u -p -r1.250 optabs.c
--- optabs.c 24 Nov 2004 18:50:20 -0000 1.250
+++ optabs.c 1 Dec 2004 19:11:55 -0000
@@ -2131,6 +2131,26 @@ expand_parity (enum machine_mode mode, r
return 0;
}
+/* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
+ conditions, VAL may already be a SUBREG against which we cannot generate
+ a further SUBREG. In this case, we expect forcing the value into a
+ register will work around the situation. */
+
+static rtx
+lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
+ enum machine_mode imode)
+{
+ rtx ret;
+ ret = lowpart_subreg (omode, val, imode);
+ if (ret == NULL)
+ {
+ val = force_reg (imode, val);
+ ret = lowpart_subreg (omode, val, imode);
+ gcc_assert (reg != NULL);
+ }
+ return ret;
+}
+
/* Generate code to perform an operation specified by UNOPTAB
on operand OP0, with result having machine-mode MODE.
@@ -2322,7 +2342,8 @@ expand_unop (enum machine_mode mode, opt
rtx insn;
if (target == 0)
target = gen_reg_rtx (mode);
- insn = emit_move_insn (target, gen_lowpart (mode, temp));
+ temp = lowpart_subreg_maybe_copy (mode, temp, imode);
+ insn = emit_move_insn (target, temp);
set_unique_reg_note (insn, REG_EQUAL,
gen_rtx_fmt_e (NEG, mode,
copy_rtx (op0)));
@@ -2513,7 +2534,8 @@ expand_abs_nojump (enum machine_mode mod
rtx insn;
if (target == 0)
target = gen_reg_rtx (mode);
- insn = emit_move_insn (target, gen_lowpart (mode, temp));
+ temp = lowpart_subreg_maybe_copy (mode, temp, imode);
+ insn = emit_move_insn (target, temp);
set_unique_reg_note (insn, REG_EQUAL,
gen_rtx_fmt_e (ABS, mode,
copy_rtx (op0)));
More information about the Gcc-patches
mailing list