From fb6234e0f88b9623472927b15277da9f3c54518e Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Wed, 24 Jun 2009 07:01:24 +0000 Subject: [PATCH] re PR middle-end/40501 (error: invalid conversion in gimple call) 2009-06-24 Andreas Krebbel PR middle-end/40501 * tree-ssa-math-opts.c (execute_optimize_bswap): Convert the bswap src and dst operands if necessary. 2009-06-24 Andreas Krebbel * gcc.dg/pr40501.c: New testcase. From-SVN: r148892 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/pr40501.c | 24 +++++++++++++ gcc/tree-ssa-math-opts.c | 65 +++++++++++++++++++++++++++++++--- 4 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr40501.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0d8c09d1763..948a35abcf0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-06-24 Andreas Krebbel + + PR middle-end/40501 + * tree-ssa-math-opts.c (execute_optimize_bswap): Convert the bswap + src and dst operands if necessary. + 2009-06-23 DJ Delorie Add MeP port. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c09e9d4dc7..faee9d1cb3b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-06-24 Andreas Krebbel + + * gcc.dg/pr40501.c: New testcase. + 2009-06-23 DJ Delorie Add MeP port. diff --git a/gcc/testsuite/gcc.dg/pr40501.c b/gcc/testsuite/gcc.dg/pr40501.c new file mode 100644 index 00000000000..0e43e63c654 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr40501.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target alpha*-*-* ia64*-*-* x86_64-*-* s390x-*-* } } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target lp64 } */ + +/* PR middle-end/40501 */ + +/* This once failed due to the bswap pass missing to add the type + casts of the signed argument and result to the proper unsigned + types. */ + +typedef long int int64_t; + +int64_t +swap64 (int64_t n) +{ + return (((n & (((int64_t) 0xff) )) << 56) | + ((n & (((int64_t) 0xff) << 8)) << 40) | + ((n & (((int64_t) 0xff) << 16)) << 24) | + ((n & (((int64_t) 0xff) << 24)) << 8) | + ((n & (((int64_t) 0xff) << 32)) >> 8) | + ((n & (((int64_t) 0xff) << 40)) >> 24) | + ((n & (((int64_t) 0xff) << 48)) >> 40) | + ((n & (((int64_t) 0xff) << 56)) >> 56)); +} diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 20ddbad5e55..11ce546e2d4 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1164,6 +1164,7 @@ execute_optimize_bswap (void) basic_block bb; bool bswap32_p, bswap64_p; bool changed = false; + tree bswap32_type = NULL_TREE, bswap64_type = NULL_TREE; if (BITS_PER_UNIT != 8) return 0; @@ -1181,6 +1182,20 @@ execute_optimize_bswap (void) if (!bswap32_p && !bswap64_p) return 0; + /* Determine the argument type of the builtins. The code later on + assumes that the return and argument type are the same. */ + if (bswap32_p) + { + tree fndecl = built_in_decls[BUILT_IN_BSWAP32]; + bswap32_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); + } + + if (bswap64_p) + { + tree fndecl = built_in_decls[BUILT_IN_BSWAP64]; + bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); + } + FOR_EACH_BB (bb) { gimple_stmt_iterator gsi; @@ -1188,7 +1203,8 @@ execute_optimize_bswap (void) for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); - tree bswap_src; + tree bswap_src, bswap_type; + tree bswap_tmp; tree fndecl = NULL_TREE; int type_size; gimple call; @@ -1203,11 +1219,17 @@ execute_optimize_bswap (void) { case 32: if (bswap32_p) - fndecl = built_in_decls[BUILT_IN_BSWAP32]; + { + fndecl = built_in_decls[BUILT_IN_BSWAP32]; + bswap_type = bswap32_type; + } break; case 64: if (bswap64_p) - fndecl = built_in_decls[BUILT_IN_BSWAP64]; + { + fndecl = built_in_decls[BUILT_IN_BSWAP64]; + bswap_type = bswap64_type; + } break; default: continue; @@ -1222,8 +1244,41 @@ execute_optimize_bswap (void) continue; changed = true; - call = gimple_build_call (fndecl, 1, bswap_src); - gimple_call_set_lhs (call, gimple_assign_lhs (stmt)); + + bswap_tmp = bswap_src; + + /* Convert the src expression if necessary. */ + if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp), bswap_type)) + { + gimple convert_stmt; + + bswap_tmp = create_tmp_var (bswap_type, "bswapsrc"); + add_referenced_var (bswap_tmp); + bswap_tmp = make_ssa_name (bswap_tmp, NULL); + + convert_stmt = gimple_build_assign_with_ops ( + CONVERT_EXPR, bswap_tmp, bswap_src, NULL); + gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT); + } + + call = gimple_build_call (fndecl, 1, bswap_tmp); + + bswap_tmp = gimple_assign_lhs (stmt); + + /* Convert the result if necessary. */ + if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp), bswap_type)) + { + gimple convert_stmt; + + bswap_tmp = create_tmp_var (bswap_type, "bswapdst"); + add_referenced_var (bswap_tmp); + bswap_tmp = make_ssa_name (bswap_tmp, NULL); + convert_stmt = gimple_build_assign_with_ops ( + CONVERT_EXPR, gimple_assign_lhs (stmt), bswap_tmp, NULL); + gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT); + } + + gimple_call_set_lhs (call, bswap_tmp); if (dump_file) {