From 0d19fbc7b0760ce665fa6a88cd40cfa0311358d7 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 22 Jul 2024 18:01:57 +0200 Subject: [PATCH] Compare loop bounds in ipa-icf Hi, this testcase shows another poblem with missing comparators for metadata in ICF. With value ranges available to loop optimizations during early opts we can estimate number of iterations based on guarding condition that can be split away by the fnsplit pass. This patch disables ICF when number of iteraitons does not match. Bootstrapped/regtesed x86_64-linux, will commit it shortly gcc/ChangeLog: PR ipa/115277 * ipa-icf-gimple.cc (func_checker::compare_loops): compare loop bounds. gcc/testsuite/ChangeLog: * gcc.c-torture/compile/pr115277.c: New test. --- gcc/ipa-icf-gimple.cc | 4 +++ .../gcc.c-torture/compile/pr115277.c | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr115277.c diff --git a/gcc/ipa-icf-gimple.cc b/gcc/ipa-icf-gimple.cc index c25eb24710f..4c3174b68b6 100644 --- a/gcc/ipa-icf-gimple.cc +++ b/gcc/ipa-icf-gimple.cc @@ -543,6 +543,10 @@ func_checker::compare_loops (basic_block bb1, basic_block bb2) return return_false_with_msg ("unroll"); if (!compare_variable_decl (l1->simduid, l2->simduid)) return return_false_with_msg ("simduid"); + if ((l1->any_upper_bound != l2->any_upper_bound) + || (l1->any_upper_bound + && (l1->nb_iterations_upper_bound != l2->nb_iterations_upper_bound))) + return return_false_with_msg ("nb_iterations_upper_bound"); return true; } diff --git a/gcc/testsuite/gcc.c-torture/compile/pr115277.c b/gcc/testsuite/gcc.c-torture/compile/pr115277.c new file mode 100644 index 00000000000..27449eb254f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr115277.c @@ -0,0 +1,28 @@ +int array[1000]; +void +test (int a) +{ + if (__builtin_expect (a > 3, 1)) + return; + for (int i = 0; i < a; i++) + array[i]=i; +} +void +test2 (int a) +{ + if (__builtin_expect (a > 10, 1)) + return; + for (int i = 0; i < a; i++) + array[i]=i; +} +int +main() +{ + test(1); + test(2); + test(3); + test2(10); + if (array[9] != 9) + __builtin_abort (); + return 0; +}