Richard Biener <richard.guent...@gmail.com> writes: > On Wed, Jul 17, 2024 at 11:48 AM <pan2...@intel.com> wrote: >> >> 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. > > Hmm, rather than restricting the matching the issue is the optab query or > in this case how *_optab_supported_p blindly uses TYPE_MODE without > either asserting the type has mode precision or failing the query in this > case. > > I think it would be simplest to adjust direct_optab_supported_p > (and convert_optab_supported_p) to reject such operations? Richard, do > you agree or should callers check this instead?
Sounds good to me, although I suppose it should go: bool direct_internal_fn_supported_p (internal_fn fn, tree_pair types, optimization_type opt_type) { // <--- Here switch (fn) { } } until we know of a specific case where that's wrong. Is type_has_mode_precision_p meaningful for all types? Richard > > So, instead of match.pd the check would need to be in vector pattern matching > and SSA math opts. Or alternatively in internal-fn.cc as laid out above. > > Richard. > >> 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 >>