https://gcc.gnu.org/g:1383c4ad0e9cde23c188b62c335fb7adad326f70
commit 1383c4ad0e9cde23c188b62c335fb7adad326f70 Author: Alexandre Oliva <ol...@gnu.org> Date: Fri Nov 8 02:13:15 2024 -0300 fold_truth_andor: test narrowing conversions Diff: --- gcc/gimple-fold.cc | 4 ++-- gcc/match.pd | 4 ++++ gcc/testsuite/gcc.dg/field-merge-8.c | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 1abf09470567..73a22ad3be59 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7387,7 +7387,7 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, return NULL_TREE; } -extern bool gimple_nop_convert (tree, tree *, tree (*)(tree)); +extern bool gimple_any_convert (tree, tree *, tree (*)(tree)); extern bool gimple_bit_and_cst (tree, tree *, tree (*)(tree)); extern bool gimple_bit_xor_cst (tree, tree *, tree (*)(tree)); extern bool gimple_rshift_cst (tree, tree *, tree (*)(tree)); @@ -7403,7 +7403,7 @@ is_cast_p (tree *name) tree type = 0; tree res_ops[1]; - while (gimple_nop_convert (*name, res_ops, follow_all_ssa_edges)) + while (gimple_any_convert (*name, res_ops, follow_all_ssa_edges)) { if (!type) type = TREE_TYPE (*name); diff --git a/gcc/match.pd b/gcc/match.pd index ffba6a8ac89c..9f8a9d690361 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -202,6 +202,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_xor_cst@0 @1 @2)) /* These are used by ifcombine fold_truth_andor. */ +(match (any_convert @0) + (convert @0)) +(match (any_convert @0) + (view_convert @0)) (match (bit_and_cst @0 @1) (bit_and @0 uniform_integer_cst_p@1)) (match (rshift_cst @0 @1) diff --git a/gcc/testsuite/gcc.dg/field-merge-8.c b/gcc/testsuite/gcc.dg/field-merge-8.c new file mode 100644 index 000000000000..34bfd0ddbcd6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/field-merge-8.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-O" } */ + +/* Check that narrowing conversions are not thrown away. */ + +struct s { + unsigned char a; + unsigned short b; +} __attribute__ ((aligned (4))); + +struct s p = { 42, 42 }; +struct s q = { 42, 42 | (2 << (__CHAR_BIT__ - 1)) }; + +void f (void) { + if (0 + || (short)(char)(long)p.a != (short)(char)(long)q.a + || (short)(long)(unsigned char)p.b != (short)(long)(unsigned char)q.b + ) + __builtin_abort (); +} + +int main () { + f (); + return 0; +}