Skip to content

Commit e548091

Browse files
authored
TypeRefining-GUFA: Fix bug with considering continuation fields empty (#8150)
We must skip such fields and not refine them, as we can't use casts to fix up refinement issues. But we were just not writing anything to GUFA's tracking of that location, which meant it looked unwritten - hence any reads would be unreachable, and trap. To fix this, just write the current type there.
1 parent 775030a commit e548091

File tree

2 files changed

+147
-2
lines changed

2 files changed

+147
-2
lines changed

src/passes/TypeRefining.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,9 @@ struct TypeRefining : public Pass {
210210
gufaType = gufaType.withInexactIfNoCustomDescs(module->features);
211211
}
212212
// Do not use the GUFA type if it is a continuation, as we cannot add
213-
// casts to fix up issues later.
213+
// casts to fix up issues later. Instead, use the original type.
214214
if (gufaType.isContinuation()) {
215-
continue;
215+
gufaType = fields[i].type;
216216
}
217217
infos[i] = LUBFinder(gufaType);
218218
}

test/lit/passes/type-refining-gufa.wast

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,3 +476,148 @@
476476
)
477477
)
478478
)
479+
480+
;; $wrap-cont has a continuation field, a type which we must not modify. There
481+
;; are other optimization opportunities in the module ($wrap-array's field can
482+
;; become exact), so we end up optimizing here. While doing so, we must not
483+
;; change the continuation type (due to cast limitations), and we must not get
484+
;; confused and think there is no value in that field because of that
485+
;; restriction (if we did, the outer struct.get in $a would trap, as it would be
486+
;; reading from a place nothing was written to, so it would need to be
487+
;; unreachable).
488+
(module
489+
;; NRML: (type $func (func))
490+
;; GUFA: (type $func (func))
491+
;; O3O3: (type $func (func))
492+
(type $func (func))
493+
(rec
494+
;; NRML: (rec
495+
;; NRML-NEXT: (type $cont (cont $func))
496+
;; GUFA: (rec
497+
;; GUFA-NEXT: (type $cont (cont $func))
498+
;; O3O3: (rec
499+
;; O3O3-NEXT: (type $cont (cont $func))
500+
(type $cont (cont $func))
501+
;; NRML: (type $wrap-cont (struct (field (ref $cont))))
502+
;; GUFA: (type $wrap-cont (struct (field (ref $cont))))
503+
;; O3O3: (type $wrap-cont (struct (field (ref $cont))))
504+
(type $wrap-cont (struct (field (ref $cont))))
505+
)
506+
;; NRML: (rec
507+
;; NRML-NEXT: (type $array (array i32))
508+
;; GUFA: (rec
509+
;; GUFA-NEXT: (type $array (array i32))
510+
(type $array (array i32))
511+
;; NRML: (type $wrap-array (sub (struct (field (ref (exact $array))))))
512+
;; GUFA: (type $wrap-array (sub (struct (field (ref (exact $array))))))
513+
(type $wrap-array (sub (struct (field (ref $array)))))
514+
515+
;; NRML: (type $5 (func (result (ref $cont))))
516+
517+
;; NRML: (elem declare func $ref)
518+
519+
;; NRML: (export "a" (func $a))
520+
;; GUFA: (type $5 (func (result (ref $cont))))
521+
522+
;; GUFA: (elem declare func $ref)
523+
524+
;; GUFA: (export "a" (func $a))
525+
;; O3O3: (type $3 (func (result (ref $cont))))
526+
527+
;; O3O3: (elem declare func $ref)
528+
529+
;; O3O3: (export "a" (func $a))
530+
(export "a" (func $a))
531+
;; NRML: (export "b" (func $b))
532+
;; GUFA: (export "b" (func $b))
533+
;; O3O3: (export "b" (func $b))
534+
(export "b" (func $b))
535+
536+
;; NRML: (func $a (type $func)
537+
;; NRML-NEXT: (drop
538+
;; NRML-NEXT: (struct.get $wrap-cont 0
539+
;; NRML-NEXT: (struct.new $wrap-cont
540+
;; NRML-NEXT: (cont.new $cont
541+
;; NRML-NEXT: (ref.func $ref)
542+
;; NRML-NEXT: )
543+
;; NRML-NEXT: )
544+
;; NRML-NEXT: )
545+
;; NRML-NEXT: )
546+
;; NRML-NEXT: )
547+
;; GUFA: (func $a (type $func)
548+
;; GUFA-NEXT: (drop
549+
;; GUFA-NEXT: (struct.get $wrap-cont 0
550+
;; GUFA-NEXT: (struct.new $wrap-cont
551+
;; GUFA-NEXT: (cont.new $cont
552+
;; GUFA-NEXT: (ref.func $ref)
553+
;; GUFA-NEXT: )
554+
;; GUFA-NEXT: )
555+
;; GUFA-NEXT: )
556+
;; GUFA-NEXT: )
557+
;; GUFA-NEXT: )
558+
;; O3O3: (func $a (type $func)
559+
;; O3O3-NEXT: (drop
560+
;; O3O3-NEXT: (cont.new $cont
561+
;; O3O3-NEXT: (ref.func $ref)
562+
;; O3O3-NEXT: )
563+
;; O3O3-NEXT: )
564+
;; O3O3-NEXT: )
565+
(func $a
566+
;; GUFA cannot improve things here (-O3 can remove the struct operations,
567+
;; though).
568+
(drop
569+
(struct.get $wrap-cont 0
570+
(struct.new $wrap-cont
571+
(cont.new $cont
572+
(ref.func $ref)
573+
)
574+
)
575+
)
576+
)
577+
)
578+
579+
;; NRML: (func $b (type $5) (result (ref $cont))
580+
;; NRML-NEXT: (unreachable)
581+
;; NRML-NEXT: )
582+
;; GUFA: (func $b (type $5) (result (ref $cont))
583+
;; GUFA-NEXT: (unreachable)
584+
;; GUFA-NEXT: )
585+
;; O3O3: (func $b (type $3) (result (ref $cont))
586+
;; O3O3-NEXT: (unreachable)
587+
;; O3O3-NEXT: )
588+
(func $b (result (ref $cont))
589+
(unreachable)
590+
)
591+
592+
;; NRML: (func $ref (type $func)
593+
;; NRML-NEXT: (drop
594+
;; NRML-NEXT: (struct.new $wrap-array
595+
;; NRML-NEXT: (array.new_default $array
596+
;; NRML-NEXT: (i32.const 0)
597+
;; NRML-NEXT: )
598+
;; NRML-NEXT: )
599+
;; NRML-NEXT: )
600+
;; NRML-NEXT: )
601+
;; GUFA: (func $ref (type $func)
602+
;; GUFA-NEXT: (drop
603+
;; GUFA-NEXT: (struct.new $wrap-array
604+
;; GUFA-NEXT: (array.new_default $array
605+
;; GUFA-NEXT: (i32.const 0)
606+
;; GUFA-NEXT: )
607+
;; GUFA-NEXT: )
608+
;; GUFA-NEXT: )
609+
;; GUFA-NEXT: )
610+
;; O3O3: (func $ref (type $func)
611+
;; O3O3-NEXT: (nop)
612+
;; O3O3-NEXT: )
613+
(func $ref (type $func)
614+
(drop
615+
(struct.new $wrap-array
616+
(array.new_default $array
617+
(i32.const 0)
618+
)
619+
)
620+
)
621+
)
622+
)
623+

0 commit comments

Comments
 (0)