https://gcc.gnu.org/g:e363940e1cef7f6face970414ffaa565daf413bd

commit r14-11701-ge363940e1cef7f6face970414ffaa565daf413bd
Author: Vineet Gupta <vine...@rivosinc.com>
Date:   Tue Apr 15 09:29:08 2025 -0700

    RISC-V: vsetvl: elide abnormal edges from LCM computations [PR119533]
    
    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 prevent abnormal edges from getting into LCM at all
    (my prior attempt at this just ignored them after LCM which is not
    right). Existing invalid_opt_bb_p () current does this 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]"
    for 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): Initialize kill
            bitmap.
            Debug dump skipped edge.
    
    gcc/testsuite/ChangeLog:
    
            * go.dg/pr119533-riscv.go: New test.
            * go.dg/pr119533-riscv-2.go: New test.
    
    (cherry picked from commit edb4867412895100b3addc525bc0dba0ea90c7f9)

Diff:
---
 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(-)

diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index ae62402ca52a..97578f8c4c23 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -684,7 +684,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;
@@ -2654,6 +2654,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));
 
@@ -2705,6 +2706,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}
+}

Reply via email to