On 04/10/2023 21:39, Jørgen Kvalsvik wrote:
A check was missing for is-single when contracting, so if a
multi-successor node that was not a condition node (e.g. a switch) a
random edge would be picked and contracted into.
---
  gcc/testsuite/gcc.misc-tests/gcov-23.c | 48 ++++++++++++++++++++++++++
  gcc/tree-profile.cc                    |  4 +++
  2 files changed, 52 insertions(+)

diff --git a/gcc/testsuite/gcc.misc-tests/gcov-23.c 
b/gcc/testsuite/gcc.misc-tests/gcov-23.c
index c4afc5e700d..856e97f5088 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-23.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-23.c
@@ -3,6 +3,7 @@
  int id (int);
  int idp (int *);
  int err;
+char c;
/* This becomes problematic only under optimization for the case when the
     compiler cannot inline the function but have to generate a call.  It is not
@@ -72,4 +73,51 @@ exit:
      return a;
  }
+/* Adapted from icu4c-73.1 common/ucase.cpp ucase_getLocaleCase (). */
+int
+mcdc003 (const char *locale)
+{
+    /* extern, so its effect won't be optimized out.  */
+    c = *locale++;
+    if (c == 'z') /* conditions(0/2) true(0) false(0) */
+                 /* conditions(end) */
+    {
+       return 1;
+    }
+    else if (c >= 'a') /* conditions(0/2) true(0) false(0) */
+                     /* conditions(end) */
+    {
+       if (id (c)) /* conditions(0/2) true(0) false(0) */
+                   /* conditions(end) */
+           c = *locale++;
+    }
+    else
+    {
+       if (c == 'T')
+       {
+           if (id (c)) /* conditions(0/2) true(0) false(0) */
+                       /* conditions(end) */
+               c = *locale++;
+           if (id (c)) /* conditions(0/2) true(0) false(0) */
+                       /* conditions(end) */
+               c = *locale++;
+       }
+       else if (c == 'L')
+           c = *locale++;
+       else if (c == 'E')
+           c = *locale++;
+       else if (c == 'N')
+           c = *locale++;
+       else if (c == 'H')
+       {
+           c = *locale++;
+           if (id (c)) /* conditions(0/2) true(0) false(0) */
+                       /* conditions(end) */
+               c = *locale++;
+       }
+    }
+
+    return 1;
+}
+
  /* { dg-final { run-gcov conditions { --conditions gcov-23.c } } } */
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index 26e1924d444..ce679130ca0 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -297,6 +297,10 @@ contract_edge (edge e, sbitmap G = nullptr)
            return source;
        if (block_conditional_p (dest))
            return e;
+       /* This happens for switches, and must be checked after the 
is-conditional
+          (which is also not single).  */
+       if (!single (dest->succs))
+           return source;
if (G)
            bitmap_set_bit (G, dest->index);

This test seems to fail on aarch64 (thanks, linaro bot)


FAIL: 24 regressions

regressions.sum:
                === gcc tests ===

Running gcc:gcc.misc-tests/gcov.exp ...
FAIL: gcc.misc-tests/gcov-23.c gcov: 0 failures in line counts, 0 in branch percentages, 13 in condition/decision, 0 in return percentages, 0 in intermediate format
FAIL: gcc.misc-tests/gcov-23.c line 108: unexpected summary 0/2
FAIL: gcc.misc-tests/gcov-23.c line 108: unexpected uncovered term 0 (false)
FAIL: gcc.misc-tests/gcov-23.c line 108: unexpected uncovered term 0 (true)
FAIL: gcc.misc-tests/gcov-23.c line 110: unexpected summary 0/2
FAIL: gcc.misc-tests/gcov-23.c line 110: unexpected uncovered term 0 (false)
FAIL: gcc.misc-tests/gcov-23.c line 110: unexpected uncovered term 0 (true)
... and 19 more entries

Apparently the if-else do not get turned into a switch here. I have a look and see if I can reproduce the problem with an explicit switch rather than the implied one from if-else, as it is broken in its current state.

Reply via email to