From: Pan Li <pan2...@intel.com> The .SAT_TRUNC matching doesn't check the type has mode precision. Thus when bitfield like below will be recog as .SAT_TRUNC.
struct e { unsigned pre : 12; unsigned a : 4; }; __attribute__((noipa)) void bug (e * v, unsigned def, unsigned use) { e & defE = *v; defE.a = min_u (use + 1, 0xf); } This patch would like to add type_has_mode_precision_p for the .SAT_TRUNC matching to get rid of this. The below test suites are passed for this patch: 1. The rv64gcv fully regression tests. 2. The x86 bootstrap tests. 3. The x86 fully regression tests. PR target/115961 gcc/ChangeLog: * match.pd: Add type_has_mode_precision_p check for .SAT_TRUNC. gcc/testsuite/ChangeLog: * g++.target/i386/pr115961-run-1.C: New test. * g++.target/riscv/rvv/base/pr115961-run-1.C: New test. Signed-off-by: Pan Li <pan2...@intel.com> --- gcc/match.pd | 4 +-- .../g++.target/i386/pr115961-run-1.C | 34 +++++++++++++++++++ .../riscv/rvv/base/pr115961-run-1.C | 34 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.target/i386/pr115961-run-1.C create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C diff --git a/gcc/match.pd b/gcc/match.pd index 24a0bbead3e..8121ec09f53 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3240,7 +3240,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_ior:c (negate (convert (gt @0 INTEGER_CST@1))) (convert @0)) (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) - && TYPE_UNSIGNED (TREE_TYPE (@0))) + && TYPE_UNSIGNED (TREE_TYPE (@0)) && type_has_mode_precision_p (type)) (with { unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0)); @@ -3255,7 +3255,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (match (unsigned_integer_sat_trunc @0) (convert (min @0 INTEGER_CST@1)) (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) - && TYPE_UNSIGNED (TREE_TYPE (@0))) + && TYPE_UNSIGNED (TREE_TYPE (@0)) && type_has_mode_precision_p (type)) (with { unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0)); diff --git a/gcc/testsuite/g++.target/i386/pr115961-run-1.C b/gcc/testsuite/g++.target/i386/pr115961-run-1.C new file mode 100644 index 00000000000..b8c8aef3b17 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr115961-run-1.C @@ -0,0 +1,34 @@ +/* PR target/115961 */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-rtl-expand-details" } */ + +struct e +{ + unsigned pre : 12; + unsigned a : 4; +}; + +static unsigned min_u (unsigned a, unsigned b) +{ + return (b < a) ? b : a; +} + +__attribute__((noipa)) +void bug (e * v, unsigned def, unsigned use) { + e & defE = *v; + defE.a = min_u (use + 1, 0xf); +} + +__attribute__((noipa, optimize(0))) +int main(void) +{ + e v = { 0xded, 3 }; + + bug(&v, 32, 33); + + if (v.a != 0xf) + __builtin_abort (); + + return 0; +} +/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */ diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C b/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C new file mode 100644 index 00000000000..b8c8aef3b17 --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C @@ -0,0 +1,34 @@ +/* PR target/115961 */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-rtl-expand-details" } */ + +struct e +{ + unsigned pre : 12; + unsigned a : 4; +}; + +static unsigned min_u (unsigned a, unsigned b) +{ + return (b < a) ? b : a; +} + +__attribute__((noipa)) +void bug (e * v, unsigned def, unsigned use) { + e & defE = *v; + defE.a = min_u (use + 1, 0xf); +} + +__attribute__((noipa, optimize(0))) +int main(void) +{ + e v = { 0xded, 3 }; + + bug(&v, 32, 33); + + if (v.a != 0xf) + __builtin_abort (); + + return 0; +} +/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */ -- 2.34.1