Message ID | 20240717094826.394649-1-pan2.li@intel.com |
---|---|
State | New |
Headers | show |
Series | [v1] Match: Bugfix .SAT_TRUNC honor types has no mode precision [PR115961] | expand |
On Wed, Jul 17, 2024 at 11:48 AM <pan2.li@intel.com> wrote: > > From: Pan Li <pan2.li@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? 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.li@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 >
On Wed, Jul 17, 2024 at 4:13 AM Richard Biener <richard.guenther@gmail.com> wrote: > > On Wed, Jul 17, 2024 at 11:48 AM <pan2.li@intel.com> wrote: > > > > From: Pan Li <pan2.li@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? I was thinking it should be in direct_optab_supported_p/convert_optab_supported_p/direct_internal_fn_optab too when I did my initial analysis of the bug report. I tried to see if there was another use of direct_optab_supported_p where this could happen but I didn't find one. Thanks, Andrew > > 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.li@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 > >
Richard Biener <richard.guenther@gmail.com> writes: > On Wed, Jul 17, 2024 at 11:48 AM <pan2.li@intel.com> wrote: >> >> From: Pan Li <pan2.li@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.li@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 >>
> -----Original Message----- > From: Richard Sandiford <richard.sandiford@arm.com> > Sent: Wednesday, July 17, 2024 8:55 PM > To: Richard Biener <richard.guenther@gmail.com> > Cc: pan2.li@intel.com; gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; > kito.cheng@gmail.com; Tamar Christina <Tamar.Christina@arm.com>; > jeffreyalaw@gmail.com; rdapp.gcc@gmail.com; hongtao.liu@intel.com > Subject: Re: [PATCH v1] Match: Bugfix .SAT_TRUNC honor types has no mode > precision [PR115961] > > Richard Biener <richard.guenther@gmail.com> writes: > > On Wed, Jul 17, 2024 at 11:48 AM <pan2.li@intel.com> wrote: > >> > >> From: Pan Li <pan2.li@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? > I was wondering about that, wouldn't VECTOR_BOOLEAN_TYPE_P types fail? e.g. on AVX where the type precision is 1 but the mode precision QImode? Unless I misunderstood the predicate. Regards, Tamar > 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.li@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 > >>
On Wed, Jul 17, 2024 at 1:03 PM Tamar Christina <Tamar.Christina@arm.com> wrote: > > > -----Original Message----- > > From: Richard Sandiford <richard.sandiford@arm.com> > > Sent: Wednesday, July 17, 2024 8:55 PM > > To: Richard Biener <richard.guenther@gmail.com> > > Cc: pan2.li@intel.com; gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; > > kito.cheng@gmail.com; Tamar Christina <Tamar.Christina@arm.com>; > > jeffreyalaw@gmail.com; rdapp.gcc@gmail.com; hongtao.liu@intel.com > > Subject: Re: [PATCH v1] Match: Bugfix .SAT_TRUNC honor types has no mode > > precision [PR115961] > > > > Richard Biener <richard.guenther@gmail.com> writes: > > > On Wed, Jul 17, 2024 at 11:48 AM <pan2.li@intel.com> wrote: > > >> > > >> From: Pan Li <pan2.li@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? > > > > I was wondering about that, wouldn't VECTOR_BOOLEAN_TYPE_P types fail? > e.g. on AVX where the type precision is 1 but the mode precision QImode? > > Unless I misunderstood the predicate. So type_has_mode_precision_p only works with scalar integral types (maybe scalar real types too) since it uses TYPE_PRECISION directly and not element_precision (the precision field is overloaded for vectors for the number of elements and TYPE_PRECISION on a vector type will cause an ICE since r14-2150-gfe48f2651334bc). So I suspect you need to check !VECTOR_TYPE_P (type) before calling type_has_mode_precision_p . Thanks, Andrew Pinski > > Regards, > Tamar > > > 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.li@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 > > >>
Andrew Pinski <pinskia@gmail.com> writes: > On Wed, Jul 17, 2024 at 1:03 PM Tamar Christina <Tamar.Christina@arm.com> wrote: >> >> > -----Original Message----- >> > From: Richard Sandiford <richard.sandiford@arm.com> >> > Sent: Wednesday, July 17, 2024 8:55 PM >> > To: Richard Biener <richard.guenther@gmail.com> >> > Cc: pan2.li@intel.com; gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; >> > kito.cheng@gmail.com; Tamar Christina <Tamar.Christina@arm.com>; >> > jeffreyalaw@gmail.com; rdapp.gcc@gmail.com; hongtao.liu@intel.com >> > Subject: Re: [PATCH v1] Match: Bugfix .SAT_TRUNC honor types has no mode >> > precision [PR115961] >> > >> > Richard Biener <richard.guenther@gmail.com> writes: >> > > On Wed, Jul 17, 2024 at 11:48 AM <pan2.li@intel.com> wrote: >> > >> >> > >> From: Pan Li <pan2.li@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? >> > >> >> I was wondering about that, wouldn't VECTOR_BOOLEAN_TYPE_P types fail? >> e.g. on AVX where the type precision is 1 but the mode precision QImode? >> >> Unless I misunderstood the predicate. > > So type_has_mode_precision_p only works with scalar integral types > (maybe scalar real types too) since it uses TYPE_PRECISION directly > and not element_precision (the precision field is overloaded for > vectors for the number of elements and TYPE_PRECISION on a vector type > will cause an ICE since r14-2150-gfe48f2651334bc). > So I suspect you need to check !VECTOR_TYPE_P (type) before calling > type_has_mode_precision_p . I think for VECTOR_TYPE_P it would be worth checking VECTOR_MODE_P instead, if we're not requiring callers to check this kind of thing. So something like: bool mode_describes_type_p (const_tree type) { if (VECTOR_TYPE_P (type)) return VECTOR_MODE_P (TREE_TYPE (type)); if (INTEGRAL_TYPE_P (type)) return type_has_mode_precision_p (type); if (SCALAR_FLOAT_TYPE_P (type)) return true; return false; } ? Possibly also with complex handling if we need that. Richard
Thanks all, will have a try in v2. Pan -----Original Message----- From: Richard Sandiford <richard.sandiford@arm.com> Sent: Thursday, July 18, 2024 5:14 AM To: Andrew Pinski <pinskia@gmail.com> Cc: Tamar Christina <Tamar.Christina@arm.com>; Richard Biener <richard.guenther@gmail.com>; Li, Pan2 <pan2.li@intel.com>; gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; kito.cheng@gmail.com; jeffreyalaw@gmail.com; rdapp.gcc@gmail.com; Liu, Hongtao <hongtao.liu@intel.com> Subject: Re: [PATCH v1] Match: Bugfix .SAT_TRUNC honor types has no mode precision [PR115961] Andrew Pinski <pinskia@gmail.com> writes: > On Wed, Jul 17, 2024 at 1:03 PM Tamar Christina <Tamar.Christina@arm.com> wrote: >> >> > -----Original Message----- >> > From: Richard Sandiford <richard.sandiford@arm.com> >> > Sent: Wednesday, July 17, 2024 8:55 PM >> > To: Richard Biener <richard.guenther@gmail.com> >> > Cc: pan2.li@intel.com; gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; >> > kito.cheng@gmail.com; Tamar Christina <Tamar.Christina@arm.com>; >> > jeffreyalaw@gmail.com; rdapp.gcc@gmail.com; hongtao.liu@intel.com >> > Subject: Re: [PATCH v1] Match: Bugfix .SAT_TRUNC honor types has no mode >> > precision [PR115961] >> > >> > Richard Biener <richard.guenther@gmail.com> writes: >> > > On Wed, Jul 17, 2024 at 11:48 AM <pan2.li@intel.com> wrote: >> > >> >> > >> From: Pan Li <pan2.li@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? >> > >> >> I was wondering about that, wouldn't VECTOR_BOOLEAN_TYPE_P types fail? >> e.g. on AVX where the type precision is 1 but the mode precision QImode? >> >> Unless I misunderstood the predicate. > > So type_has_mode_precision_p only works with scalar integral types > (maybe scalar real types too) since it uses TYPE_PRECISION directly > and not element_precision (the precision field is overloaded for > vectors for the number of elements and TYPE_PRECISION on a vector type > will cause an ICE since r14-2150-gfe48f2651334bc). > So I suspect you need to check !VECTOR_TYPE_P (type) before calling > type_has_mode_precision_p . I think for VECTOR_TYPE_P it would be worth checking VECTOR_MODE_P instead, if we're not requiring callers to check this kind of thing. So something like: bool mode_describes_type_p (const_tree type) { if (VECTOR_TYPE_P (type)) return VECTOR_MODE_P (TREE_TYPE (type)); if (INTEGRAL_TYPE_P (type)) return type_has_mode_precision_p (type); if (SCALAR_FLOAT_TYPE_P (type)) return true; return false; } ? Possibly also with complex handling if we need that. Richard
> Am 17.07.2024 um 23:13 schrieb Richard Sandiford <richard.sandiford@arm.com>: > > Andrew Pinski <pinskia@gmail.com> writes: >>> On Wed, Jul 17, 2024 at 1:03 PM Tamar Christina <Tamar.Christina@arm.com> wrote: >>> >>>> -----Original Message----- >>>> From: Richard Sandiford <richard.sandiford@arm.com> >>>> Sent: Wednesday, July 17, 2024 8:55 PM >>>> To: Richard Biener <richard.guenther@gmail.com> >>>> Cc: pan2.li@intel.com; gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; >>>> kito.cheng@gmail.com; Tamar Christina <Tamar.Christina@arm.com>; >>>> jeffreyalaw@gmail.com; rdapp.gcc@gmail.com; hongtao.liu@intel.com >>>> Subject: Re: [PATCH v1] Match: Bugfix .SAT_TRUNC honor types has no mode >>>> precision [PR115961] >>>> >>>> Richard Biener <richard.guenther@gmail.com> writes: >>>>> On Wed, Jul 17, 2024 at 11:48 AM <pan2.li@intel.com> wrote: >>>>>> >>>>>> From: Pan Li <pan2.li@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? >>>> >>> >>> I was wondering about that, wouldn't VECTOR_BOOLEAN_TYPE_P types fail? >>> e.g. on AVX where the type precision is 1 but the mode precision QImode? >>> >>> Unless I misunderstood the predicate. >> >> So type_has_mode_precision_p only works with scalar integral types >> (maybe scalar real types too) since it uses TYPE_PRECISION directly >> and not element_precision (the precision field is overloaded for >> vectors for the number of elements and TYPE_PRECISION on a vector type >> will cause an ICE since r14-2150-gfe48f2651334bc). >> So I suspect you need to check !VECTOR_TYPE_P (type) before calling >> type_has_mode_precision_p . > > I think for VECTOR_TYPE_P it would be worth checking VECTOR_MODE_P instead, > if we're not requiring callers to check this kind of thing. > > So something like: > > bool > mode_describes_type_p (const_tree type) > { > if (VECTOR_TYPE_P (type)) > return VECTOR_MODE_P (TREE_TYPE (type)); That’s a good point and another mistake that keeps popping up. I hope the generic vector support passes in a scalar type when checking for support on the underlying integer mode… > > if (INTEGRAL_TYPE_P (type)) > return type_has_mode_precision_p (type); > > if (SCALAR_FLOAT_TYPE_P (type)) > return true; > > return false; > } > > ? Possibly also with complex handling if we need that. > > Richard
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" } } */