This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR middle-end/8408
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 3 Nov 2002 19:29:04 +0100
- Subject: PR middle-end/8408
- Organization: Home
This is a high-priority PR, regression on the mainline but not on the
gcc-3_2-branch. The compiler ICEs during the ADDRESSOF purging pass in
fixup_var_refs_1 on the following insn:
(insn 10 8 14 0 0x4014d294 (set (reg:CCZ 17 flags)
(compare:CCZ (addressof:SI (reg/v:DF 61) 60 0x40176e70)
(addressof:SI (reg/v:DF 59) 58 0x40176e00))) -1 (nil)
(nil))
because the recognizer rejects the modified insn
(insn 10 8 14 0 0x4014d294 (set (reg:CCZ 17 flags)
(compare:CCZ (addressof:SI (reg/v:DF 61) 60 0x40176e70)
(reg/f:SI 62))) -1 (nil)
(nil))
despite the following pattern in i386.md:
(define_insn "*cmpsi_1_insn"
[(set (reg 17)
(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
(match_operand:SI 1 "general_operand" "ri,mr")))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& ix86_match_ccmode (insn, CCmode)"
"cmp{l}\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")
(set_attr "mode" "SI")])
which should be matching (and is matching on the gcc-3_2-branch).
That's purely the recognizer's fault: because of some changes in the md file,
the decision tree for cmpsi_1_insn on the mainline is very different from the
one on the branch. More precisely, the nonimmediate_operand predicate for
operand 0 is reached through the default case of a switch statement on the
branch, which lets ADDRESSOF be accepted.
On the other hand, the decision tree for cmpsi_1_insn is merged with others on
the mainline, so the nonimmediate_operand predicate is reached through
explicit cases of a switch statement. Now the three only cases listed in
genrecog.c for the nonimmediate_operand predicate are SUBREG, REG and MEM.
The proposed fix is to teach genrecog.c the ADDRESSOF code, based on what
recog.c already knows about it. Bootstrapped/regtested (c,c++,objc,f77) on
i586-redhat-linux-gnu. However, I experienced 1% increase in bootstrap time
because of this patch.
2002-11-03 Eric Botcazou <ebotcazou@libertysurf.fr>
PR middle-end/8408
* genrecog.c (preds): handle ADDRESSOF.
(validate_pattern): mark it as lvalue.
--
Eric Botcazou
--- gcc/genrecog.c Fri Nov 1 21:53:03 2002
+++ gcc/genrecog.c Sun Nov 3 09:31:38 2002
@@ -187,22 +187,23 @@
const RTX_CODE codes[NUM_RTX_CODE];
} preds[] = {
{"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG, MEM}},
+ LABEL_REF, SUBREG, REG, MEM, ADDRESSOF}},
#ifdef PREDICATE_CODES
PREDICATE_CODES
#endif
{"address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG, MEM, PLUS, MINUS, MULT}},
- {"register_operand", {SUBREG, REG}},
- {"pmode_register_operand", {SUBREG, REG}},
+ LABEL_REF, SUBREG, REG, MEM, ADDRESSOF,
+ PLUS, MINUS, MULT}},
+ {"register_operand", {SUBREG, REG, ADDRESSOF}},
+ {"pmode_register_operand", {SUBREG, REG, ADDRESSOF}},
{"scratch_operand", {SCRATCH, REG}},
{"immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF}},
{"const_int_operand", {CONST_INT}},
{"const_double_operand", {CONST_INT, CONST_DOUBLE}},
- {"nonimmediate_operand", {SUBREG, REG, MEM}},
+ {"nonimmediate_operand", {SUBREG, REG, MEM, ADDRESSOF}},
{"nonmemory_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG}},
+ LABEL_REF, SUBREG, REG, ADDRESSOF}},
{"push_operand", {MEM}},
{"pop_operand", {MEM}},
{"memory_operand", {SUBREG, MEM}},
@@ -211,7 +212,7 @@
UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
UNLT, LTGT}},
{"mode_independent_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG, MEM}}
+ LABEL_REF, SUBREG, REG, MEM, ADDRESSOF}}
};
#define NUM_KNOWN_PREDS ARRAY_SIZE (preds)
@@ -520,6 +521,7 @@
if (c != REG
&& c != SUBREG
&& c != MEM
+ && c != ADDRESSOF
&& c != CONCAT
&& c != PARALLEL
&& c != STRICT_LOW_PART)
/* PR middle-end/8408 */
/* Verify that the recognizer explicitly
handles ADDRESSOF operands. */
void foo(void)
{
double d1 = 3.14159, d2;
if (&d2 == &d1)
;
}