Skip to content

Commit 6e6bf9f

Browse files
authored
[WebAssembly] Disable multivalue emission temporarily (#82714)
We plan to enable multivalue in the features section soon (#80923) for other reasons, such as the feature having been standardized for many years and other features being developed (e.g. EH) depending on it. This is separate from enabling Clang experimental multivalue ABI (`-Xclang -target-abi -Xclang experimental-mv`), but it turned out we generate some multivalue code in the backend as well if it is enabled in the features section. Given that our backend multivalue generation still has not been much used nor tested, and enabling the feature in the features section can be a separate decision from how much multialue (including none) we decide to generate for now, I'd like to temporarily disable the actual generation of multivalue in our backend. To do that, this adds an internal flag `-wasm-emit-multivalue` that defaults to false. All our existing multivalue tests can use this to test multivalue code. This flag can be removed later when we are confident the multivalue generation is well tested.
1 parent 2e5af56 commit 6e6bf9f

9 files changed

+43
-24
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ using namespace llvm;
4343

4444
#define DEBUG_TYPE "wasm-lower"
4545

46+
extern cl::opt<bool> WasmEmitMultiValue;
47+
4648
WebAssemblyTargetLowering::WebAssemblyTargetLowering(
4749
const TargetMachine &TM, const WebAssemblySubtarget &STI)
4850
: TargetLowering(TM), Subtarget(&STI) {
@@ -1288,15 +1290,16 @@ bool WebAssemblyTargetLowering::CanLowerReturn(
12881290
const SmallVectorImpl<ISD::OutputArg> &Outs,
12891291
LLVMContext & /*Context*/) const {
12901292
// WebAssembly can only handle returning tuples with multivalue enabled
1291-
return Subtarget->hasMultivalue() || Outs.size() <= 1;
1293+
return (Subtarget->hasMultivalue() && WasmEmitMultiValue) || Outs.size() <= 1;
12921294
}
12931295

12941296
SDValue WebAssemblyTargetLowering::LowerReturn(
12951297
SDValue Chain, CallingConv::ID CallConv, bool /*IsVarArg*/,
12961298
const SmallVectorImpl<ISD::OutputArg> &Outs,
12971299
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
12981300
SelectionDAG &DAG) const {
1299-
assert((Subtarget->hasMultivalue() || Outs.size() <= 1) &&
1301+
assert(((Subtarget->hasMultivalue() && WasmEmitMultiValue) ||
1302+
Outs.size() <= 1) &&
13001303
"MVP WebAssembly can only return up to one value");
13011304
if (!callingConvSupported(CallConv))
13021305
fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");

llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "llvm/Target/TargetMachine.h"
2323
using namespace llvm;
2424

25+
extern cl::opt<bool> WasmEmitMultiValue;
26+
2527
WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor.
2628

2729
MachineFunctionInfo *WebAssemblyFunctionInfo::clone(
@@ -71,7 +73,8 @@ void llvm::computeSignatureVTs(const FunctionType *Ty,
7173

7274
MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
7375
if (Results.size() > 1 &&
74-
!TM.getSubtarget<WebAssemblySubtarget>(ContextFunc).hasMultivalue()) {
76+
(!TM.getSubtarget<WebAssemblySubtarget>(ContextFunc).hasMultivalue() ||
77+
!WasmEmitMultiValue)) {
7578
// WebAssembly can't lower returns of multiple values without demoting to
7679
// sret unless multivalue is enabled (see
7780
// WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return

llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
using namespace llvm;
2626

27+
extern cl::opt<bool> WasmEmitMultiValue;
28+
2729
namespace {
2830

2931
enum RuntimeLibcallSignature {
@@ -694,7 +696,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
694696
Params.push_back(PtrTy);
695697
break;
696698
case i64_i64_func_f32:
697-
if (Subtarget.hasMultivalue()) {
699+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
698700
Rets.push_back(wasm::ValType::I64);
699701
Rets.push_back(wasm::ValType::I64);
700702
} else {
@@ -703,7 +705,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
703705
Params.push_back(wasm::ValType::F32);
704706
break;
705707
case i64_i64_func_f64:
706-
if (Subtarget.hasMultivalue()) {
708+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
707709
Rets.push_back(wasm::ValType::I64);
708710
Rets.push_back(wasm::ValType::I64);
709711
} else {
@@ -712,7 +714,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
712714
Params.push_back(wasm::ValType::F64);
713715
break;
714716
case i16_i16_func_i16_i16:
715-
if (Subtarget.hasMultivalue()) {
717+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
716718
Rets.push_back(wasm::ValType::I32);
717719
Rets.push_back(wasm::ValType::I32);
718720
} else {
@@ -722,7 +724,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
722724
Params.push_back(wasm::ValType::I32);
723725
break;
724726
case i32_i32_func_i32_i32:
725-
if (Subtarget.hasMultivalue()) {
727+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
726728
Rets.push_back(wasm::ValType::I32);
727729
Rets.push_back(wasm::ValType::I32);
728730
} else {
@@ -732,7 +734,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
732734
Params.push_back(wasm::ValType::I32);
733735
break;
734736
case i64_i64_func_i64_i64:
735-
if (Subtarget.hasMultivalue()) {
737+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
736738
Rets.push_back(wasm::ValType::I64);
737739
Rets.push_back(wasm::ValType::I64);
738740
} else {
@@ -742,7 +744,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
742744
Params.push_back(wasm::ValType::I64);
743745
break;
744746
case i64_i64_func_i64_i64_i64_i64:
745-
if (Subtarget.hasMultivalue()) {
747+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
746748
Rets.push_back(wasm::ValType::I64);
747749
Rets.push_back(wasm::ValType::I64);
748750
} else {
@@ -754,7 +756,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
754756
Params.push_back(wasm::ValType::I64);
755757
break;
756758
case i64_i64_func_i64_i64_i64_i64_iPTR:
757-
if (Subtarget.hasMultivalue()) {
759+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
758760
Rets.push_back(wasm::ValType::I64);
759761
Rets.push_back(wasm::ValType::I64);
760762
} else {
@@ -767,7 +769,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
767769
Params.push_back(PtrTy);
768770
break;
769771
case i64_i64_i64_i64_func_i64_i64_i64_i64:
770-
if (Subtarget.hasMultivalue()) {
772+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
771773
Rets.push_back(wasm::ValType::I64);
772774
Rets.push_back(wasm::ValType::I64);
773775
Rets.push_back(wasm::ValType::I64);
@@ -781,7 +783,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
781783
Params.push_back(wasm::ValType::I64);
782784
break;
783785
case i64_i64_func_i64_i64_i32:
784-
if (Subtarget.hasMultivalue()) {
786+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
785787
Rets.push_back(wasm::ValType::I64);
786788
Rets.push_back(wasm::ValType::I64);
787789
} else {
@@ -851,7 +853,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
851853
Params.push_back(wasm::ValType::I64);
852854
break;
853855
case i64_i64_func_i64_i64_i64_i64_i64_i64:
854-
if (Subtarget.hasMultivalue()) {
856+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
855857
Rets.push_back(wasm::ValType::I64);
856858
Rets.push_back(wasm::ValType::I64);
857859
} else {
@@ -865,7 +867,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
865867
Params.push_back(wasm::ValType::I64);
866868
break;
867869
case i64_i64_func_i32:
868-
if (Subtarget.hasMultivalue()) {
870+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
869871
Rets.push_back(wasm::ValType::I64);
870872
Rets.push_back(wasm::ValType::I64);
871873
} else {
@@ -874,7 +876,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
874876
Params.push_back(wasm::ValType::I32);
875877
break;
876878
case i64_i64_func_i64:
877-
if (Subtarget.hasMultivalue()) {
879+
if (Subtarget.hasMultivalue() && WasmEmitMultiValue) {
878880
Rets.push_back(wasm::ValType::I64);
879881
Rets.push_back(wasm::ValType::I64);
880882
} else {

llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ static cl::opt<bool> WasmDisableFixIrreducibleControlFlowPass(
5454
" irreducible control flow optimization pass"),
5555
cl::init(false));
5656

57+
// A temporary option to control emission of multivalue until multivalue
58+
// implementation is stable enough. We currently don't emit multivalue by
59+
// default even if the feature section allows it.
60+
// TODO Stabilize multivalue and delete this option
61+
cl::opt<bool>
62+
WasmEmitMultiValue("wasm-emit-multivalue", cl::Hidden,
63+
cl::desc("WebAssembly: Emit multivalue in the backend"),
64+
cl::init(false));
65+
5766
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget() {
5867
// Register the target.
5968
RegisterTargetMachine<WebAssemblyTargetMachine> X(

llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj-multi-return.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
; RUN: not --crash llc < %s -enable-emscripten-cxx-exceptions -mattr=+multivalue 2>&1 | FileCheck %s --check-prefix=EH
2-
; RUN: not --crash llc < %s -enable-emscripten-sjlj -mattr=+multivalue 2>&1 | FileCheck %s --check-prefix=SJLJ
1+
; RUN: not --crash llc < %s -enable-emscripten-cxx-exceptions -mattr=+multivalue -wasm-emit-multivalue 2>&1 | FileCheck %s --check-prefix=EH
2+
; RUN: not --crash llc < %s -enable-emscripten-sjlj -mattr=+multivalue 2>&1 -wasm-emit-multivalue | FileCheck %s --check-prefix=SJLJ
33

44
; Currently multivalue returning functions are not supported in Emscripten EH /
55
; SjLj. Make sure they error out.

llvm/test/CodeGen/WebAssembly/multivalue-dont-move-def-past-use.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2-
# RUN: llc -mtriple=wasm32-unknown-unknown -mattr=+multivalue -run-pass=wasm-reg-stackify -verify-machineinstrs %s -o - | FileCheck %s
2+
# RUN: llc -mtriple=wasm32-unknown-unknown -mattr=+multivalue -wasm-emit-multivalue -run-pass=wasm-reg-stackify -verify-machineinstrs %s -o - | FileCheck %s
33

44
--- |
55
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"

llvm/test/CodeGen/WebAssembly/multivalue-stackify.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
22
; NOTE: Test functions have been generated by multivalue-stackify.py.
33

4-
; RUN: llc < %s -verify-machineinstrs -mattr=+multivalue | FileCheck %s
4+
; RUN: llc < %s -verify-machineinstrs -mattr=+multivalue -wasm-emit-multivalue | FileCheck %s
55

66
; Test that the multivalue stackification works
77

llvm/test/CodeGen/WebAssembly/multivalue.ll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mcpu=mvp -mattr=+multivalue,+tail-call | FileCheck %s
2-
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mcpu=mvp -mattr=+reference-types,+multivalue,+tail-call | FileCheck --check-prefix REF %s
3-
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mcpu=mvp -mattr=+multivalue,+tail-call | FileCheck %s --check-prefix REGS
4-
; RUN: llc < %s --filetype=obj -mcpu=mvp -mattr=+multivalue,+tail-call | obj2yaml | FileCheck %s --check-prefix OBJ
1+
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mcpu=mvp -mattr=+multivalue,+tail-call -wasm-emit-multivalue | FileCheck %s
2+
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mcpu=mvp -mattr=+reference-types,+multivalue,+tail-call -wasm-emit-multivalue | FileCheck --check-prefix REF %s
3+
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mcpu=mvp -mattr=+multivalue,+tail-call -wasm-emit-multivalue | FileCheck %s --check-prefix REGS
4+
; RUN: llc < %s --filetype=obj -mcpu=mvp -mattr=+multivalue,+tail-call -wasm-emit-multivalue | obj2yaml | FileCheck %s --check-prefix OBJ
5+
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mcpu=mvp -mattr=+multivalue,+tail-call | FileCheck %s --check-prefix NO-MULTIVALUE
56

67
; Test that the multivalue calls, returns, function types, and block
78
; types work as expected.
@@ -19,6 +20,7 @@ declare void @use_i64(i64)
1920
; CHECK-NEXT: i32.const 42{{$}}
2021
; CHECK-NEXT: i64.const 42{{$}}
2122
; CHECK-NEXT: end_function{{$}}
23+
; NO-MULTIVALUE-NOT: .functype pair_const () -> (i32, i64)
2224
define %pair @pair_const() {
2325
ret %pair { i32 42, i64 42 }
2426
}

llvm/test/CodeGen/WebAssembly/multivalue_libcall.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2-
; RUN: llc < %s -verify-machineinstrs -mcpu=mvp -mattr=+multivalue | FileCheck %s --check-prefix=MULTIVALUE
2+
; RUN: llc < %s -verify-machineinstrs -mcpu=mvp -mattr=+multivalue -wasm-emit-multivalue | FileCheck %s --check-prefix=MULTIVALUE
33
; RUN: llc < %s -verify-machineinstrs -mcpu=mvp | FileCheck %s --check-prefix=NO_MULTIVALUE
44

55
; Test libcall signatures when multivalue is enabled and disabled

0 commit comments

Comments
 (0)