From 5ea39b2412269d208bb6ebd78303815957bd4f70 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 31 Mar 2020 11:04:32 +0200 Subject: [PATCH] store-merging: Allow enums during bswap recognition [PR94403] The following testcase is optimized with char/unsigned char/signed char, but not with std::byte. The following patch fixes that. Didn't use INTEGRAL_TYPE_P because bswapping bools is just too weird. 2020-03-31 Jakub Jelinek PR tree-optimization/94403 * gimple-ssa-store-merging.c (verify_symbolic_number_p): Allow also ENUMERAL_TYPE lhs_type. * g++.dg/tree-ssa/pr94403.C: New test. --- gcc/ChangeLog | 4 +++ gcc/gimple-ssa-store-merging.c | 3 +- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/g++.dg/tree-ssa/pr94403.C | 37 +++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr94403.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f7d1ccf72b6..e7ff9131f5d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2020-03-31 Jakub Jelinek + PR tree-optimization/94403 + * gimple-ssa-store-merging.c (verify_symbolic_number_p): Allow also + ENUMERAL_TYPE lhs_type. + PR rtl-optimization/94344 * tree-ssa-forwprop.c (simplify_rotate): Handle also same precision conversions, either on both operands of |^+ or just one. Handle diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 83ae6c4c5b1..a6687cd9c98 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -315,7 +315,8 @@ verify_symbolic_number_p (struct symbolic_number *n, gimple *stmt) lhs_type = gimple_expr_type (stmt); - if (TREE_CODE (lhs_type) != INTEGER_TYPE) + if (TREE_CODE (lhs_type) != INTEGER_TYPE + && TREE_CODE (lhs_type) != ENUMERAL_TYPE) return false; if (TYPE_PRECISION (lhs_type) != TYPE_PRECISION (n->type)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 14faa3faa32..3f21cb32106 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2020-03-31 Jakub Jelinek + PR tree-optimization/94403 + * g++.dg/tree-ssa/pr94403.C: New test. + PR rtl-optimization/94344 * gcc.dg/pr94344.c: New test. diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr94403.C b/gcc/testsuite/g++.dg/tree-ssa/pr94403.C new file mode 100644 index 00000000000..d47e7fcc5a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr94403.C @@ -0,0 +1,37 @@ +// PR tree-optimization/94403 +// Only test on some 64-bit targets which do have bswap{si,di}2 patterns and +// are either big or little endian (not pdp endian). +// { dg-do compile { target { lp64 && { i?86-*-* x86_64-*-* powerpc*-*-* aarch64*-*-* } } } } +// { dg-require-effective-target store_merge } +// { dg-options "-O2 -fdump-tree-store-merging -std=c++17" } + +namespace std { + template + void swap (T& t1, T& t2) { T tmp (t1); t1 = t2; t2 = tmp; } + enum class byte : unsigned char {}; +} + +unsigned +bswap32 (unsigned int x) +{ + unsigned int y = x; + std::byte *bytes = reinterpret_cast (&y); + std::swap (bytes[0], bytes[3]); + std::swap (bytes[1], bytes[2]); + return y; +} + +unsigned long long +bswap64 (unsigned long long x) +{ + unsigned long long y = x; + std::byte *bytes = reinterpret_cast (&y); + std::swap (bytes[0], bytes[7]); + std::swap (bytes[1], bytes[6]); + std::swap (bytes[2], bytes[5]); + std::swap (bytes[3], bytes[4]); + return y; +} + +/* { dg-final { scan-tree-dump-times "__builtin_bswap64" 1 "store-merging" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_bswap32" 1 "store-merging" } } */ -- 2.30.2