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