From 2611198dc05ba2e1d526eb7818816e35f821ff73 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 25 Jul 2024 07:35:20 -0700 Subject: [PATCH 1/2] fix --- src/passes/TupleOptimization.cpp | 7 ++++- test/lit/passes/tuple-optimization.wast | 38 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/passes/TupleOptimization.cpp b/src/passes/TupleOptimization.cpp index 25da1c5ec30..944c96e2fb1 100644 --- a/src/passes/TupleOptimization.cpp +++ b/src/passes/TupleOptimization.cpp @@ -320,8 +320,13 @@ struct TupleOptimization : public WalkerPass> { // we were confused earlier and the target should not be. assert(sourceBase); + // The source and target may have different lane types due to subtyping + // (but their sizes must be equal). + auto sourceType = value->type; + assert(sourceType.size() == type.size()); + for (Index i = 0; i < type.size(); i++) { - auto* get = builder.makeLocalGet(sourceBase + i, type[i]); + auto* get = builder.makeLocalGet(sourceBase + i, sourceType[i]); contents.push_back(builder.makeLocalSet(targetBase + i, get)); } replace(builder.makeBlock(contents)); diff --git a/test/lit/passes/tuple-optimization.wast b/test/lit/passes/tuple-optimization.wast index d092d479f81..1d1f3d431f3 100644 --- a/test/lit/passes/tuple-optimization.wast +++ b/test/lit/passes/tuple-optimization.wast @@ -1026,4 +1026,42 @@ ) ) ) + + ;; CHECK: (func $tuple.lane.subtyping (type $0) + ;; CHECK-NEXT: (local $tuple_null (tuple i32 nullref)) + ;; CHECK-NEXT: (local $tuple_eq (tuple i32 eqref)) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 nullref) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 eqref) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $tuple.lane.subtyping + (local $tuple_null (tuple i32 nullref)) + (local $tuple_eq (tuple i32 eqref)) + ;; The tee emits a nullref in the second lane, which is written to a lane of + ;; eqref. That is, the source and the target do not have identical type, + ;; which we need to properly handle and not error. + (local.set $tuple_eq + (local.tee $tuple_null + (tuple.make 2 + (i32.const 0) + (ref.null none) + ) + ) + ) + ) ) From 2d46e918c9568f008a1c33318ed0ee815d297c9f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 25 Jul 2024 09:27:54 -0700 Subject: [PATCH 2/2] lane => element --- src/passes/TupleOptimization.cpp | 6 +++--- test/lit/passes/tuple-optimization.wast | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/passes/TupleOptimization.cpp b/src/passes/TupleOptimization.cpp index 944c96e2fb1..ca704f1a3d7 100644 --- a/src/passes/TupleOptimization.cpp +++ b/src/passes/TupleOptimization.cpp @@ -25,7 +25,7 @@ // (tuple.extract 3 0 // (local.get $tuple))) // -// If there are no other uses, then we just need one of the three lanes. By +// If there are no other uses, then we just need one of the three elements. By // lowing them to three separate locals, other passes can remove the other two. // // Specifically, this pass seeks out tuple locals that have these properties: @@ -320,8 +320,8 @@ struct TupleOptimization : public WalkerPass> { // we were confused earlier and the target should not be. assert(sourceBase); - // The source and target may have different lane types due to subtyping - // (but their sizes must be equal). + // The source and target may have different element types due to + // subtyping (but their sizes must be equal). auto sourceType = value->type; assert(sourceType.size() == type.size()); diff --git a/test/lit/passes/tuple-optimization.wast b/test/lit/passes/tuple-optimization.wast index 1d1f3d431f3..e0d68848e8a 100644 --- a/test/lit/passes/tuple-optimization.wast +++ b/test/lit/passes/tuple-optimization.wast @@ -15,7 +15,7 @@ ;; CHECK-NEXT: ) (func $just-set (local $tuple (tuple i32 i32)) - ;; This tuple local can be optimized into separate locals per lane. The + ;; This tuple local can be optimized into separate locals per element. The ;; tuple local itself then has no uses and other passes will remove it. (local.set $tuple (tuple.make 2 @@ -38,7 +38,7 @@ ;; CHECK-NEXT: ) (func $just-get (local $tuple (tuple i32 i32)) - ;; The default value of the tuple lanes is used here in the new locals we + ;; The default value of the tuple elements is used here in the new locals we ;; add. (drop (tuple.extract 2 0 @@ -1027,7 +1027,7 @@ ) ) - ;; CHECK: (func $tuple.lane.subtyping (type $0) + ;; CHECK: (func $tuple.element.subtyping (type $0) ;; CHECK-NEXT: (local $tuple_null (tuple i32 nullref)) ;; CHECK-NEXT: (local $tuple_eq (tuple i32 eqref)) ;; CHECK-NEXT: (local $2 i32) @@ -1049,12 +1049,12 @@ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $tuple.lane.subtyping + (func $tuple.element.subtyping (local $tuple_null (tuple i32 nullref)) (local $tuple_eq (tuple i32 eqref)) - ;; The tee emits a nullref in the second lane, which is written to a lane of - ;; eqref. That is, the source and the target do not have identical type, - ;; which we need to properly handle and not error. + ;; The tee emits a nullref in the second element, which is written to an + ;; element of eqref. That is, the source and the target do not have + ;; identical type, which we need to properly handle and not error. (local.set $tuple_eq (local.tee $tuple_null (tuple.make 2