diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2009-04-12 20:55:25 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2009-04-12 20:55:25 +0200 |
commit | 4c48007b43c7e5fed48347f81e3d27e71e6a5751 (patch) | |
tree | 91cc1b83b4c42ec3e0bcf9a0ba74589e5b4a269e | |
parent | 4de43cbedd60c999ead68322684fa9735a079793 (diff) | |
download | gcc-4c48007b43c7e5fed48347f81e3d27e71e6a5751.zip gcc-4c48007b43c7e5fed48347f81e3d27e71e6a5751.tar.gz gcc-4c48007b43c7e5fed48347f81e3d27e71e6a5751.tar.bz2 |
re PR target/39740 (unrecognizable insn on alpha using -O3 and -std=c99)
2009-04-12 Uros Bizjak <ubizjak@gmail.com>
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/alpha/predicates.md | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/alpha/pr39740.c | 163 |
4 files changed, 177 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4ef03d0..cce9c47 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-04-12 Uros Bizjak <ubizjak@gmail.com> + + PR target/39740 + * config/alpha/predicates.md (local_symbolic_operand): Return 1 for + offseted label references. + 2009-04-11 Jan Hubicka <jh@suse.cz> * 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 247845c..b8e4242 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 28fa637..a4452b3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +009-04-12 Uros Bizjak <ubizjak@gmail.com> + + PR target/39740 + * gcc.target/alpha/pr39740.c: New test. + 2009-04-11 Daniel Kraft <d@domob.eu> 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 0000000..ed4fee1 --- /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; +} |