From c6e3a931201a2ce47ede92668870388df4f25219 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Fri, 31 Oct 2014 11:55:07 +0000 Subject: [PATCH] re PR tree-optimization/63259 (Detecting byteswap sequence) 2014-10-31 Thomas Preud'homme gcc/ PR tree-optimization/63259 * tree-ssa-math-opts.c (bswap_replace): Replace expression by a rotation left if it is a 16 bit byte swap. (pass_optimize_bswap::execute): Also consider bswap in LROTATE_EXPR and RROTATE_EXPR statements if it is a byte rotation. gcc/testsuite/ PR tree-optimization/63259 * optimize-bswapsi-1.c (swap32_f): New bswap pass test. * optimize-bswaphi-1.c: Drop useless SIType definition and fix typo in following comment. From-SVN: r216971 --- gcc/ChangeLog | 8 ++++ gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/gcc.dg/optimize-bswaphi-1.c | 3 +- gcc/testsuite/gcc.dg/optimize-bswapsi-1.c | 13 +++++- gcc/tree-ssa-math-opts.c | 52 +++++++++++++++++------ 5 files changed, 68 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ffc217e634..f228610d0bb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-10-31 Thomas Preud'homme + + PR tree-optimization/63259 + * tree-ssa-math-opts.c (bswap_replace): Replace expression by a + rotation left if it is a 16 bit byte swap. + (pass_optimize_bswap::execute): Also consider bswap in LROTATE_EXPR + and RROTATE_EXPR statements if it is a byte rotation. + 2014-10-31 Jakub Jelinek PR sanitizer/63697 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7892292e078..adc0e3e366d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-10-31 Thomas Preud'homme + + PR tree-optimization/63259 + * optimize-bswapsi-1.c (swap32_f): New bswap pass test. + * optimize-bswaphi-1.c: Drop useless SIType definition and fix typo in + following comment. + 2014-10-31 Jakub Jelinek PR sanitizer/63697 diff --git a/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c b/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c index 18aba284e26..692fceb951f 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c +++ b/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c @@ -42,11 +42,10 @@ uint32_t read_be16_3 (unsigned char *data) return *(data + 1) | (*data << 8); } -typedef int SItype __attribute__ ((mode (SI))); typedef int HItype __attribute__ ((mode (HI))); /* Test that detection of significant sign extension works correctly. This - checks that unknown byte marker are set correctly in cast of cast. */ + checks that unknown byte markers are set correctly in cast of cast. */ HItype swap16 (HItype in) diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c index cfde2182e4c..ad3ede49255 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c +++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c @@ -78,5 +78,16 @@ swap32_e (SItype in) | (((in >> 24) & 0xFF) << 0); } -/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 5 "bswap" } } */ +/* This variant comes from PR63259. It compiles to a gimple sequence that ends + with a rotation instead of a bitwise OR. */ + +unsigned +swap32_f (unsigned in) +{ + in = ((in & 0xff00ff00) >> 8) | ((in & 0x00ff00ff) << 8); + in = ((in & 0xffff0000) >> 16) | ((in & 0x0000ffff) << 16); + return in; +} + +/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 6 "bswap" } } */ /* { dg-final { cleanup-tree-dump "bswap" } } */ diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 5daeff26ab3..27825895a27 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -2187,7 +2187,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt, struct symbolic_number *n, bool bswap) { tree src, tmp, tgt; - gimple call; + gimple bswap_stmt; src = gimple_assign_rhs1 (src_stmt); tgt = gimple_assign_lhs (cur_stmt); @@ -2293,16 +2293,28 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt, tmp = src; - /* Convert the src expression if necessary. */ - if (!useless_type_conversion_p (TREE_TYPE (tmp), bswap_type)) + /* Canonical form for 16 bit bswap is a rotate expression. */ + if (bswap && n->range == 16) { - gimple convert_stmt; - tmp = make_temp_ssa_name (bswap_type, NULL, "bswapsrc"); - convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tmp, src, NULL); - gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT); + tree count = build_int_cst (NULL, BITS_PER_UNIT); + bswap_type = TREE_TYPE (src); + src = fold_build2 (LROTATE_EXPR, bswap_type, src, count); + bswap_stmt = gimple_build_assign (NULL, src); } + else + { + /* Convert the src expression if necessary. */ + if (!useless_type_conversion_p (TREE_TYPE (tmp), bswap_type)) + { + gimple convert_stmt; + tmp = make_temp_ssa_name (bswap_type, NULL, "bswapsrc"); + convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tmp, src, + NULL); + gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT); + } - call = gimple_build_call (fndecl, 1, tmp); + bswap_stmt = gimple_build_call (fndecl, 1, tmp); + } tmp = tgt; @@ -2315,7 +2327,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt, gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT); } - gimple_call_set_lhs (call, tmp); + gimple_set_lhs (bswap_stmt, tmp); if (dump_file) { @@ -2324,7 +2336,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt, print_gimple_stmt (dump_file, cur_stmt, 0, 0); } - gsi_insert_after (&gsi, call, GSI_SAME_STMT); + gsi_insert_after (&gsi, bswap_stmt, GSI_SAME_STMT); gsi_remove (&gsi, true); return true; } @@ -2388,13 +2400,29 @@ pass_optimize_bswap::execute (function *fun) { gimple src_stmt, cur_stmt = gsi_stmt (gsi); tree fndecl = NULL_TREE, bswap_type = NULL_TREE, load_type; + enum tree_code code; struct symbolic_number n; bool bswap; - if (!is_gimple_assign (cur_stmt) - || gimple_assign_rhs_code (cur_stmt) != BIT_IOR_EXPR) + if (!is_gimple_assign (cur_stmt)) continue; + code = gimple_assign_rhs_code (cur_stmt); + switch (code) + { + case LROTATE_EXPR: + case RROTATE_EXPR: + if (!tree_fits_uhwi_p (gimple_assign_rhs2 (cur_stmt)) + || tree_to_uhwi (gimple_assign_rhs2 (cur_stmt)) + % BITS_PER_UNIT) + continue; + /* Fall through. */ + case BIT_IOR_EXPR: + break; + default: + continue; + } + src_stmt = find_bswap_or_nop (cur_stmt, &n, &bswap); if (!src_stmt) -- 2.30.2