This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch: 3334280
- From: Dale Johannesen <dalej at apple dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Dale Johannesen <dalej at apple dot com>
- Date: Fri, 25 Jul 2003 14:40:55 -0700
- Subject: Patch: 3334280
This patch prevents combine from generating a compare to an invalid
subreg, as
discussed in my earlier mail on this bug (at bottom). Running
testsuite.
Index: combine.c
===================================================================
RCS file: /cvs/repository/CoreTools/gcc3/gcc/combine.c,v
retrieving revision 1.22.2.3
diff -u -d -b -w -r1.22.2.3 combine.c
--- combine.c 2003/04/23 00:14:16 1.22.2.3
+++ combine.c 2003/07/25 21:38:20
@@ -11360,6 +11360,7 @@
if (have_insn_for (COMPARE, tmode))
{
int zero_extended;
+ rtx new_op0, new_op1;
/* If the only nonzero bits in OP0 and OP1 are those in the
narrower mode and this is an equality or unsigned
comparison,
@@ -11392,11 +11393,20 @@
gen_lowpart_for_combine (tmode,
XEXP (op0,
1)));
- op0 = gen_lowpart_for_combine (tmode, op0);
+ /* APPLE LOCAL ban undefined SUBREG */
+ /* We can't accept a (necessarily paradoxical) SUBREG
+ here, as the high bits of it are undefined. */
+ new_op0 = gen_lowpart_for_combine (tmode, op0);
+ new_op1 = gen_lowpart_for_combine (tmode, op1);
+ if (GET_CODE (new_op0) != SUBREG
+ && (op1 == new_op1 || GET_CODE (new_op1) != SUBREG))
+ {
+ op0 = new_op0;
+ op1 = new_op1;
if (zero_extended && GET_CODE (op1) == CONST_INT)
op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode));
- op1 = gen_lowpart_for_combine (tmode, op1);
break;
+ }
}
/* If this is a test for negative, we can make an explicit
This is a bad-codegen regression from 3.1, still broken in FSF 3.3 and
3.4.
The RTL starts to differ as far back as expand, and I could track that
down,
but the new RTL looks correct for a while. The actual problem seems
to be
introduced by combine, which merges
(insn 28 27 30 0 0x0 (set (reg:SI 129)
(sign_extend:SI (reg:QI 127))) 21 {extendqisi2_ppc} (insn_list
27 (nil))
(expr_list:REG_DEAD (reg:QI 127)
(nil)))
(insn 30 28 31 0 0x0 (set (reg:CC 131)
(compare:CC (reg:SI 129)
(const_int -1 [0xffffffff]))) 426 {*cmpsi_internal1}
(insn_list 28 (nil))
(expr_list:REG_DEAD (reg:SI 129)
(nil)))
into
(insn 30 28 31 0 0x0 (set (reg:CC 131)
(compare:CC (subreg:SI (reg:QI 127) 0)
(const_int 255 [0xff]))) 426 {*cmpsi_internal1} (insn_list
27 (nil))
(expr_list:REG_DEAD (reg:QI 127)
(nil)))
This seems wrong; it is doing a 32-bit comparison, but in the
subreg:SI(QI)
expression, the high 24 bits are undefined as I read the docs. But
I'm not on
firm ground with subreg's, so I want to get confirmation before
proceeding...