Changes since v2
 - Elide abnormal edges before LCM not after LCM
---

vsetvl phase4 uses LCM guided info to insert VSETVL insns, including a
straggler loop for "mising vsetvls" on certain edges. Currently it
asserts on encountering EDGE_ABNORMAL.

When enabling go frontend with V enabled, libgo build hits the assert.

The solution is to filter out abnormal edges from getting into LCM at
all. Existing invalid_opt_bb_p () has such checks for BB predecessors
but not for successors which is what the patch adds.

Crucially, the ICE/fix also depends on avoiding vsetvl hoisting past
non-transparent blocks: That is taken care of by Robin's patch
"RISC-V: Do not lift up vsetvl into non-transparent blocks [PR119547]"
or a different yet related issue.

Reported-by: Heinrich Schuchardt <heinrich.schucha...@canonical.com>
Signed-off-by: Vineet Gupta <vine...@rivosinc.com>

        PR target/119533

gcc/ChangeLog:

        * config/riscv/riscv-vsetvl.cc (invalid_opt_bb_p): Check for
        EDGE_ABNOMAL.
        (pre_vsetvl::compute_lcm_local_properties): Dump skipped edge.

gcc/testsuite/ChangeLog:

        * go.dg/pr119533-riscv.go: New test.
        * go.dg/pr119533-riscv-2.go: New test.

Signed-off-by: Vineet Gupta <vine...@rivosinc.com>
---
 gcc/config/riscv/riscv-vsetvl.cc        |   7 +-
 gcc/testsuite/go.dg/pr119533-riscv-2.go |  42 +++++++++
 gcc/testsuite/go.dg/pr119533-riscv.go   | 120 ++++++++++++++++++++++++
 3 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/go.dg/pr119533-riscv-2.go
 create mode 100644 gcc/testsuite/go.dg/pr119533-riscv.go

diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index c4046bcc3455..a8c92565541a 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -685,7 +685,7 @@ invalid_opt_bb_p (basic_block cfg_bb)
   /* We only do LCM optimizations on blocks that are post dominated by
      EXIT block, that is, we don't do LCM optimizations on infinite loop.  */
   FOR_EACH_EDGE (e, ei, cfg_bb->succs)
-    if (e->flags & EDGE_FAKE)
+    if ((e->flags & EDGE_FAKE) || (e->flags & EDGE_ABNORMAL))
       return true;
 
   return false;
@@ -2698,6 +2698,7 @@ pre_vsetvl::compute_lcm_local_properties ()
   m_avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), num_exprs);
 
   bitmap_vector_clear (m_avloc, last_basic_block_for_fn (cfun));
+  bitmap_vector_clear (m_kill, last_basic_block_for_fn (cfun));
   bitmap_vector_clear (m_antloc, last_basic_block_for_fn (cfun));
   bitmap_vector_ones (m_transp, last_basic_block_for_fn (cfun));
 
@@ -2749,6 +2750,10 @@ pre_vsetvl::compute_lcm_local_properties ()
 
       if (invalid_opt_bb_p (bb->cfg_bb ()))
        {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           fprintf (dump_file, "\n --- skipping bb %u due to weird edge",
+                    bb->index ());
+
          bitmap_clear (m_antloc[bb_index]);
          bitmap_clear (m_transp[bb_index]);
        }
diff --git a/gcc/testsuite/go.dg/pr119533-riscv-2.go 
b/gcc/testsuite/go.dg/pr119533-riscv-2.go
new file mode 100644
index 000000000000..ce3ffaffe9d4
--- /dev/null
+++ b/gcc/testsuite/go.dg/pr119533-riscv-2.go
@@ -0,0 +1,42 @@
+// { dg-do compile { target riscv64*-*-* } }
+// { dg-options "-O2 -march=rv64gcv -mabi=lp64d" }
+
+package ast
+
+type as struct {
+       bt []struct{}
+       an string
+}
+
+func bj(a *as) string {
+       if b := a.bt; len(a.an) == 1 {
+               _ = b[0]
+       }
+       return a.an
+}
+
+func MergePackageFiles(f map[string][]interface{}, g uint) []interface{} {
+       bl := make([]string, len(f))
+       var bo []interface{}
+       bu := make(map[string]int)
+       for _, bm := range bl {
+               a := f[bm]
+               for _, d := range a {
+                       if g != 0 {
+                               if a, p := d.(*as); p {
+                                       n := bj(a)
+                                       if j, bp := bu[n]; bp {
+                                               _ = j
+                                       }
+                               }
+                       }
+               }
+       }
+       for _, bm := range bl {
+               _ = bm
+       }
+       for _, bm := range bl {
+               _ = f[bm]
+       }
+       return bo
+}
diff --git a/gcc/testsuite/go.dg/pr119533-riscv.go 
b/gcc/testsuite/go.dg/pr119533-riscv.go
new file mode 100644
index 000000000000..30f52d267c5f
--- /dev/null
+++ b/gcc/testsuite/go.dg/pr119533-riscv.go
@@ -0,0 +1,120 @@
+// { dg-do compile { target riscv64*-*-* } }
+// { dg-options "-O2 -march=rv64gcv -mabi=lp64d" }
+
+// Reduced from libgo build (multi-file reduction, merged mnaully
+// and hand reduced again).
+
+package ast
+import (
+       "go/token"
+       "go/scanner"
+       "reflect"
+)
+type v struct {}
+type w func( string,  reflect.Value) bool
+func x( string,  reflect.Value) bool
+type r struct {
+       scanner.ErrorList
+}
+type ab interface {}
+type ae interface {}
+type af interface {}
+type ag struct {}
+func (ag) Pos() token.Pos
+func (ag) ah() token.Pos
+type c struct {
+       aj    ae          }
+type ak struct {
+       al    []c  }
+type (
+       am struct {
+               an    string    }
+       bs struct {
+               Value    string
+         }
+)
+func ao(string) *am
+type (
+       ap interface {}
+       aq struct {
+               ar    bs     }
+as struct {
+               bt ak
+               an am        }
+)
+type File struct {
+       *ag
+       token.Pos
+       *am
+       at      []af
+       *v
+       au    []*aq
+       av *am
+       aw   []*ag }
+type ax struct {
+       an    string
+       *v
+       ay   map[string]File   }
+func a(az *token.FileSet, b token.Pos) int
+type k struct {
+       l token.Pos
+       ah   token.Pos
+}
+type m struct {
+       bb bool
+       bc   *ag
+}
+
+type bi uint
+func bj(a *as) string {
+       if b := a.bt; len(b.al) == 1 {
+               c := b.al[0].aj
+               if e := c; e != nil {}
+       }
+       return a.an.an
+}
+func MergePackageFiles(f ax, g bi) *File {
+       h := 0
+       bk := 0
+       k := 0
+       bl := make([]string, len(f.ay))
+       i := 0
+       for bm, a := range f.ay {
+               bl[i] = bm
+               k += len(a.at)
+       }
+       var bn *ag
+       var l token.Pos
+       if h > 0 {}
+       var bo []af
+               bu := make(map[string]int)
+               m := 0
+               for _, bm := range bl {
+                       a := f.ay[bm]
+                       for _, d := range a.at {
+                               if g!= 0 {
+                                       if a, p := d.(*as); p {
+                                               n := bj(a)
+                                               if j, bp := bu[n]; bp {
+                                                       if bo != nil && bo[j]== 
nil {}
+                                               }
+                                       }
+                               }
+                       }
+               }
+               if m > 0 {}
+       var bq []*aq
+               q := make(map[string]bool)
+               for _, bm := range bl {
+                       a := f.ay[bm]
+                       for _, br := range a.au {
+                               if o := br.ar.Value; q[o] {}
+                       }
+               }
+       var bh = make([]*ag, bk)
+               for _, bm := range bl {
+                       a := f.ay[bm]
+                       copy(bh, a.aw)
+               }
+       return &File{bn, l, ao(f.an), bo, f.v, bq, nil, bh}
+}
-- 
2.43.0

Reply via email to