From 4c48007b43c7e5fed48347f81e3d27e71e6a5751 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Sun, 12 Apr 2009 20:55:25 +0200 Subject: [PATCH] re PR target/39740 (unrecognizable insn on alpha using -O3 and -std=c99) 2009-04-12 Uros Bizjak PR target/39740 * config/alpha/predicates.md (local_symbolic_operand): Return 1 for offseted label references. testsuite/ChangeLog: PR target/39740 * gcc.target/alpha/pr39740.c: New test. From-SVN: r145985 --- gcc/ChangeLog | 6 + gcc/config/alpha/predicates.md | 6 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.target/alpha/pr39740.c | 163 +++++++++++++++++++++++ 4 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/alpha/pr39740.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4ef03d04723..cce9c47783d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-04-12 Uros Bizjak + + PR target/39740 + * config/alpha/predicates.md (local_symbolic_operand): Return 1 for + offseted label references. + 2009-04-11 Jan Hubicka * tree-ssa-pre.c (eliminate): Fix call of update_stmt. diff --git a/gcc/config/alpha/predicates.md b/gcc/config/alpha/predicates.md index 247845c24af..b8e424273b8 100644 --- a/gcc/config/alpha/predicates.md +++ b/gcc/config/alpha/predicates.md @@ -324,14 +324,14 @@ (define_predicate "local_symbolic_operand" (match_code "label_ref,const,symbol_ref") { - if (GET_CODE (op) == LABEL_REF) - return 1; - if (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT) op = XEXP (XEXP (op, 0), 0); + if (GET_CODE (op) == LABEL_REF) + return 1; + if (GET_CODE (op) != SYMBOL_REF) return 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28fa637a6e4..a4452b37566 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +009-04-12 Uros Bizjak + + PR target/39740 + * gcc.target/alpha/pr39740.c: New test. + 2009-04-11 Daniel Kraft PR fortran/37746 diff --git a/gcc/testsuite/gcc.target/alpha/pr39740.c b/gcc/testsuite/gcc.target/alpha/pr39740.c new file mode 100644 index 00000000000..ed4fee145d4 --- /dev/null +++ b/gcc/testsuite/gcc.target/alpha/pr39740.c @@ -0,0 +1,163 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -std=c99" } */ + +typedef int R_len_t; +typedef unsigned int SEXPTYPE; +struct sxpinfo_struct +{ + SEXPTYPE type:5; +}; + +struct vecsxp_struct +{ + R_len_t length; + R_len_t truelength; +}; + +struct listsxp_struct +{ + struct SEXPREC *carval; + struct SEXPREC *cdrval; + struct SEXPREC *tagval; +}; + +typedef struct SEXPREC +{ + struct sxpinfo_struct sxpinfo; + union + { + struct listsxp_struct listsxp; + } u; +} SEXPREC, *SEXP; + +typedef struct VECTOR_SEXPREC +{ + struct vecsxp_struct vecsxp; +} VECTOR_SEXPREC, *VECSEXP; + +typedef union +{ + VECTOR_SEXPREC s; + double align; +} SEXPREC_ALIGN; + +extern SEXP R_NilValue; +extern SEXP R_MissingArg; + +int Rf_envlength (SEXP rho); +SEXP Rf_protect (SEXP); +const char *Rf_translateChar (SEXP); + +inline R_len_t +Rf_length (SEXP s) +{ + int i; + switch (((s)->sxpinfo.type)) + { + case 0: + return 0; + case 24: + return (((VECSEXP) (s))->vecsxp.length); + case 6: + case 17: + i = 0; + while (s != ((void *) 0) && s != R_NilValue) + { + i++; + s = ((s)->u.listsxp.cdrval); + } + return i; + case 4: + return Rf_envlength (s); + default: + return 1; + } +} + +inline SEXP +Rf_lang3 (SEXP s, SEXP t, SEXP u) +{ + return s; +} + +typedef SEXP (*CCODE) (SEXP, SEXP, SEXP, SEXP); + +static SEXP PlusSymbol; +static SEXP MinusSymbol; +static SEXP DivideSymbol; + +int isZero (SEXP s); +SEXP PP (SEXP s); +SEXP AddParens (SEXP expr); +SEXP Rf_install (); + +static int +isUminus (SEXP s) +{ + if (((s)->sxpinfo.type) == 6 && ((s)->u.listsxp.carval) == MinusSymbol) + { + switch (Rf_length (s)) + { + case 2: + return 1; + case 3: + if (((((((s)->u.listsxp.cdrval))->u.listsxp.cdrval))->u.listsxp. + carval) == R_MissingArg) + return 1; + else + return 0; + } + } + else + return 0; +} + +static SEXP +simplify (SEXP fun, SEXP arg1, SEXP arg2) +{ + SEXP ans; + if (fun == PlusSymbol) + { + if (isZero (arg1)) + ans = arg2; + else if (isUminus (arg1)) + ans = + simplify (MinusSymbol, arg2, + ((((arg1)->u.listsxp.cdrval))->u.listsxp.carval)); + else if (isUminus (arg2)) + ans = + simplify (MinusSymbol, arg1, + ((((arg2)->u.listsxp.cdrval))->u.listsxp.carval)); + } + else if (fun == DivideSymbol) + { + ans = Rf_lang3 (DivideSymbol, arg1, arg2); + } + + return ans; +} + + +static SEXP +D (SEXP expr, SEXP var) +{ + return simplify (PlusSymbol, + PP (D + (((((expr)->u.listsxp.cdrval))->u.listsxp.carval), + var)), + PP (D + (((((((expr)->u.listsxp.cdrval))->u.listsxp.cdrval))-> + u.listsxp.carval), var))); +} + +SEXP + __attribute__ ((visibility ("hidden"))) do_D (SEXP call, SEXP op, SEXP args, + SEXP env) +{ + SEXP expr, var; + var = Rf_install (); + expr = ((args)->u.listsxp.carval); + Rf_protect (expr = D (expr, var)); + expr = AddParens (expr); + return expr; +} -- 2.30.2