|
2635 | 2635 | (type $A (sub (struct (field (ref null $A))))) |
2636 | 2636 | ;; CHECK: (type $1 (func (result anyref))) |
2637 | 2637 |
|
2638 | | - ;; CHECK: (type $B (sub $A (struct (field (ref $A))))) |
2639 | | - (type $B (sub $A (struct (field (ref $A))))) |
| 2638 | + ;; CHECK: (type $B (sub $A (struct (field (ref $A)) (field i32)))) |
| 2639 | + (type $B (sub $A (struct (field (ref $A)) (field i32)))) |
| 2640 | + |
| 2641 | + ;; CHECK: (type $3 (func (result i32))) |
2640 | 2642 |
|
2641 | 2643 | ;; CHECK: (func $func (type $1) (result anyref) |
2642 | 2644 | ;; CHECK-NEXT: (local $a (ref $A)) |
2643 | 2645 | ;; CHECK-NEXT: (local $1 (ref $A)) |
2644 | | - ;; CHECK-NEXT: (local $2 (ref $A)) |
| 2646 | + ;; CHECK-NEXT: (local $2 i32) |
| 2647 | + ;; CHECK-NEXT: (local $3 (ref $A)) |
| 2648 | + ;; CHECK-NEXT: (local $4 i32) |
2645 | 2649 | ;; CHECK-NEXT: (ref.cast (ref $B) |
2646 | 2650 | ;; CHECK-NEXT: (block (result (ref $A)) |
2647 | 2651 | ;; CHECK-NEXT: (drop |
2648 | 2652 | ;; CHECK-NEXT: (block (result nullref) |
2649 | | - ;; CHECK-NEXT: (local.set $2 |
| 2653 | + ;; CHECK-NEXT: (local.set $3 |
2650 | 2654 | ;; CHECK-NEXT: (struct.new $A |
2651 | 2655 | ;; CHECK-NEXT: (ref.null none) |
2652 | 2656 | ;; CHECK-NEXT: ) |
2653 | 2657 | ;; CHECK-NEXT: ) |
| 2658 | + ;; CHECK-NEXT: (local.set $4 |
| 2659 | + ;; CHECK-NEXT: (i32.const 1) |
| 2660 | + ;; CHECK-NEXT: ) |
2654 | 2661 | ;; CHECK-NEXT: (local.set $1 |
2655 | | - ;; CHECK-NEXT: (local.get $2) |
| 2662 | + ;; CHECK-NEXT: (local.get $3) |
| 2663 | + ;; CHECK-NEXT: ) |
| 2664 | + ;; CHECK-NEXT: (local.set $2 |
| 2665 | + ;; CHECK-NEXT: (local.get $4) |
2656 | 2666 | ;; CHECK-NEXT: ) |
2657 | 2667 | ;; CHECK-NEXT: (ref.null none) |
2658 | 2668 | ;; CHECK-NEXT: ) |
|
2675 | 2685 | (struct.new $A |
2676 | 2686 | (ref.null none) |
2677 | 2687 | ) |
| 2688 | + (i32.const 1) |
2678 | 2689 | ) |
2679 | 2690 | ) |
2680 | 2691 | ) |
|
2683 | 2694 |
|
2684 | 2695 | ;; CHECK: (func $cast-success (type $1) (result anyref) |
2685 | 2696 | ;; CHECK-NEXT: (local $0 (ref $A)) |
2686 | | - ;; CHECK-NEXT: (local $1 (ref $A)) |
| 2697 | + ;; CHECK-NEXT: (local $1 i32) |
| 2698 | + ;; CHECK-NEXT: (local $2 (ref $A)) |
| 2699 | + ;; CHECK-NEXT: (local $3 i32) |
2687 | 2700 | ;; CHECK-NEXT: (drop |
2688 | 2701 | ;; CHECK-NEXT: (block (result nullref) |
2689 | | - ;; CHECK-NEXT: (local.set $1 |
| 2702 | + ;; CHECK-NEXT: (local.set $2 |
2690 | 2703 | ;; CHECK-NEXT: (struct.new $A |
2691 | 2704 | ;; CHECK-NEXT: (ref.null none) |
2692 | 2705 | ;; CHECK-NEXT: ) |
2693 | 2706 | ;; CHECK-NEXT: ) |
| 2707 | + ;; CHECK-NEXT: (local.set $3 |
| 2708 | + ;; CHECK-NEXT: (i32.const 1) |
| 2709 | + ;; CHECK-NEXT: ) |
2694 | 2710 | ;; CHECK-NEXT: (local.set $0 |
2695 | | - ;; CHECK-NEXT: (local.get $1) |
| 2711 | + ;; CHECK-NEXT: (local.get $2) |
| 2712 | + ;; CHECK-NEXT: ) |
| 2713 | + ;; CHECK-NEXT: (local.set $1 |
| 2714 | + ;; CHECK-NEXT: (local.get $3) |
2696 | 2715 | ;; CHECK-NEXT: ) |
2697 | 2716 | ;; CHECK-NEXT: (ref.null none) |
2698 | 2717 | ;; CHECK-NEXT: ) |
|
2706 | 2725 | (struct.new $A |
2707 | 2726 | (ref.null none) |
2708 | 2727 | ) |
| 2728 | + (i32.const 1) |
2709 | 2729 | ) |
2710 | 2730 | ) |
2711 | 2731 | ) |
2712 | 2732 | ) |
2713 | 2733 | ;; CHECK: (func $cast-failure (type $1) (result anyref) |
2714 | | - ;; CHECK-NEXT: (struct.get $B 0 |
2715 | | - ;; CHECK-NEXT: (ref.cast (ref $B) |
2716 | | - ;; CHECK-NEXT: (struct.new $A |
2717 | | - ;; CHECK-NEXT: (struct.new $A |
2718 | | - ;; CHECK-NEXT: (ref.null none) |
| 2734 | + ;; CHECK-NEXT: (local $0 (ref null $A)) |
| 2735 | + ;; CHECK-NEXT: (local $1 (ref null $A)) |
| 2736 | + ;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit) |
| 2737 | + ;; CHECK-NEXT: (drop |
| 2738 | + ;; CHECK-NEXT: (block |
| 2739 | + ;; CHECK-NEXT: (drop |
| 2740 | + ;; CHECK-NEXT: (block (result nullref) |
| 2741 | + ;; CHECK-NEXT: (local.set $1 |
| 2742 | + ;; CHECK-NEXT: (struct.new $A |
| 2743 | + ;; CHECK-NEXT: (ref.null none) |
| 2744 | + ;; CHECK-NEXT: ) |
| 2745 | + ;; CHECK-NEXT: ) |
| 2746 | + ;; CHECK-NEXT: (local.set $0 |
| 2747 | + ;; CHECK-NEXT: (local.get $1) |
| 2748 | + ;; CHECK-NEXT: ) |
| 2749 | + ;; CHECK-NEXT: (ref.null none) |
| 2750 | + ;; CHECK-NEXT: ) |
2719 | 2751 | ;; CHECK-NEXT: ) |
| 2752 | + ;; CHECK-NEXT: (unreachable) |
2720 | 2753 | ;; CHECK-NEXT: ) |
2721 | 2754 | ;; CHECK-NEXT: ) |
| 2755 | + ;; CHECK-NEXT: (unreachable) |
2722 | 2756 | ;; CHECK-NEXT: ) |
2723 | 2757 | ;; CHECK-NEXT: ) |
2724 | 2758 | (func $cast-failure (result anyref) |
2725 | 2759 | (struct.get $B 0 |
2726 | | - ;; The allocated $A arrives here, but the cast will fail, so we do not |
2727 | | - ;; optimize. |
| 2760 | + ;; The allocated $A arrives here, but the cast will fail. We can remove |
| 2761 | + ;; the allocation and put an unreachable here. (Note that the inner |
| 2762 | + ;; struct.new survives, which would take another cycle to remove.) |
| 2763 | + (ref.cast (ref $B) |
| 2764 | + (struct.new $A |
| 2765 | + (struct.new $A |
| 2766 | + (ref.null none) |
| 2767 | + ) |
| 2768 | + ) |
| 2769 | + ) |
| 2770 | + ) |
| 2771 | + ) |
| 2772 | + |
| 2773 | + ;; CHECK: (func $cast-failure-nofield (type $3) (result i32) |
| 2774 | + ;; CHECK-NEXT: (local $0 (ref null $A)) |
| 2775 | + ;; CHECK-NEXT: (local $1 (ref null $A)) |
| 2776 | + ;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit) |
| 2777 | + ;; CHECK-NEXT: (drop |
| 2778 | + ;; CHECK-NEXT: (block |
| 2779 | + ;; CHECK-NEXT: (drop |
| 2780 | + ;; CHECK-NEXT: (block (result nullref) |
| 2781 | + ;; CHECK-NEXT: (local.set $1 |
| 2782 | + ;; CHECK-NEXT: (struct.new $A |
| 2783 | + ;; CHECK-NEXT: (ref.null none) |
| 2784 | + ;; CHECK-NEXT: ) |
| 2785 | + ;; CHECK-NEXT: ) |
| 2786 | + ;; CHECK-NEXT: (local.set $0 |
| 2787 | + ;; CHECK-NEXT: (local.get $1) |
| 2788 | + ;; CHECK-NEXT: ) |
| 2789 | + ;; CHECK-NEXT: (ref.null none) |
| 2790 | + ;; CHECK-NEXT: ) |
| 2791 | + ;; CHECK-NEXT: ) |
| 2792 | + ;; CHECK-NEXT: (unreachable) |
| 2793 | + ;; CHECK-NEXT: ) |
| 2794 | + ;; CHECK-NEXT: ) |
| 2795 | + ;; CHECK-NEXT: (unreachable) |
| 2796 | + ;; CHECK-NEXT: ) |
| 2797 | + ;; CHECK-NEXT: ) |
| 2798 | + (func $cast-failure-nofield (result i32) |
| 2799 | + ;; As above, but we read from a field that only exists in $B, despite the |
| 2800 | + ;; allocation that flows here being an $A. We should not error on that. |
| 2801 | + (struct.get $B 1 ;; this changes from 0 to 1 |
2728 | 2802 | (ref.cast (ref $B) |
2729 | 2803 | (struct.new $A |
2730 | 2804 | (struct.new $A |
|
0 commit comments