diff --git a/lib/Target/WebAssembly/WebAssembly.td b/lib/Target/WebAssembly/WebAssembly.td index 99cf1f119a20..76b3ddbbfffa 100644 --- a/lib/Target/WebAssembly/WebAssembly.td +++ b/lib/Target/WebAssembly/WebAssembly.td @@ -32,6 +32,11 @@ def FeatureNontrappingFPToInt : "HasNontrappingFPToInt", "true", "Enable non-trapping float-to-int conversion operators">; +def FeatureSignExt : + SubtargetFeature<"sign-ext", + "HasSignExt", "true", + "Enable sign extension operators">; + //===----------------------------------------------------------------------===// // Architectures. //===----------------------------------------------------------------------===// diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 299009fa6674..d0b3ad371191 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -117,8 +117,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( // As a special case, these operators use the type to mean the type to // sign-extend from. setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); - if (!Subtarget->hasAtomics()) { - // The Atomics feature includes signext intructions. + if (!Subtarget->hasSignExt()) { for (auto T : {MVT::i8, MVT::i16, MVT::i32}) setOperationAction(ISD::SIGN_EXTEND_INREG, T, Expand); } diff --git a/lib/Target/WebAssembly/WebAssemblyInstrConv.td b/lib/Target/WebAssembly/WebAssemblyInstrConv.td index 426c2c802172..bf1282b5edfa 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrConv.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrConv.td @@ -26,7 +26,7 @@ def I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src), [(set I64:$dst, (zext I32:$src))], "i64.extend_u/i32\t$dst, $src", 0xad>; -let Predicates = [HasAtomics] in { +let Predicates = [HasSignExt] in { def I32_EXTEND8_S_I32 : I<(outs I32:$dst), (ins I32:$src), [(set I32:$dst, (sext_inreg I32:$src, i8))], "i32.extend8_s\t$dst, $src", 0xc0>; @@ -42,7 +42,7 @@ def I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src), def I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src), [(set I64:$dst, (sext_inreg I64:$src, i32))], "i64.extend32_s\t$dst, $src", 0xc4>; -} // Predicates = [HasAtomics] +} // Predicates = [HasSignExt] } // defs = [ARGUMENTS] diff --git a/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/lib/Target/WebAssembly/WebAssemblyInstrInfo.td index f8d311ac3b00..245d5abbf263 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrInfo.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrInfo.td @@ -30,6 +30,14 @@ def NotHasNontrappingFPToInt : Predicate<"!Subtarget->hasNontrappingFPToInt()">, AssemblerPredicate<"!FeatureNontrappingFPToInt", "nontrapping-fptoint">; +def HasSignExt : + Predicate<"Subtarget->hasSignExt()">, + AssemblerPredicate<"FeatureSignExt", + "sign-ext">; +def NotHasSignExt : + Predicate<"!Subtarget->hasSignExt()">, + AssemblerPredicate<"!FeatureSignExt", + "sign-ext">; //===----------------------------------------------------------------------===// // WebAssembly-specific DAG Node Types. diff --git a/lib/Target/WebAssembly/WebAssemblySubtarget.cpp b/lib/Target/WebAssembly/WebAssemblySubtarget.cpp index 9e122a5f1574..78602a35e649 100644 --- a/lib/Target/WebAssembly/WebAssemblySubtarget.cpp +++ b/lib/Target/WebAssembly/WebAssemblySubtarget.cpp @@ -41,8 +41,8 @@ WebAssemblySubtarget::WebAssemblySubtarget(const Triple &TT, const std::string &FS, const TargetMachine &TM) : WebAssemblyGenSubtargetInfo(TT, CPU, FS), HasSIMD128(false), - HasAtomics(false), HasNontrappingFPToInt(false), CPUString(CPU), - TargetTriple(TT), FrameLowering(), + HasAtomics(false), HasNontrappingFPToInt(false), HasSignExt(false), + CPUString(CPU), TargetTriple(TT), FrameLowering(), InstrInfo(initializeSubtargetDependencies(FS)), TSInfo(), TLInfo(TM, *this) {} diff --git a/lib/Target/WebAssembly/WebAssemblySubtarget.h b/lib/Target/WebAssembly/WebAssemblySubtarget.h index a6bf0b6d54f6..c999f501a9c9 100644 --- a/lib/Target/WebAssembly/WebAssemblySubtarget.h +++ b/lib/Target/WebAssembly/WebAssemblySubtarget.h @@ -32,6 +32,7 @@ class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo { bool HasSIMD128; bool HasAtomics; bool HasNontrappingFPToInt; + bool HasSignExt; /// String name of used CPU. std::string CPUString; @@ -78,6 +79,7 @@ class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo { bool hasSIMD128() const { return HasSIMD128; } bool hasAtomics() const { return HasAtomics; } bool hasNontrappingFPToInt() const { return HasNontrappingFPToInt; } + bool hasSignExt() const { return HasSignExt; } /// Parses features string setting specified subtarget options. Definition of /// function is auto generated by tblgen. diff --git a/test/CodeGen/WebAssembly/load-ext-atomic.ll b/test/CodeGen/WebAssembly/load-ext-atomic.ll index 0c4552dc9afb..862f29583a9b 100644 --- a/test/CodeGen/WebAssembly/load-ext-atomic.ll +++ b/test/CodeGen/WebAssembly/load-ext-atomic.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s +; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s ; Test that extending loads are assembled properly. diff --git a/test/CodeGen/WebAssembly/offset-atomics.ll b/test/CodeGen/WebAssembly/offset-atomics.ll index 24727fc2608d..3415f07a81e3 100644 --- a/test/CodeGen/WebAssembly/offset-atomics.ll +++ b/test/CodeGen/WebAssembly/offset-atomics.ll @@ -1,5 +1,5 @@ ; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics,+sign-ext | FileCheck %s ; Test that atomic loads are assembled properly. diff --git a/test/CodeGen/WebAssembly/signext-inreg.ll b/test/CodeGen/WebAssembly/signext-inreg.ll index c97a1bf1b0e8..00637f10eb91 100644 --- a/test/CodeGen/WebAssembly/signext-inreg.ll +++ b/test/CodeGen/WebAssembly/signext-inreg.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s --check-prefix=NOATOMIC +; RUN: llc < %s -mattr=+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s --check-prefix=NOSIGNEXT target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown-wasm" @@ -10,8 +10,8 @@ target triple = "wasm32-unknown-unknown-wasm" ; CHECK-NEXT: i32.extend8_s $push[[NUM:[0-9]+]]=, $0{{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} -; NOATOMIC-LABEL: i32_extend8_s -; NOATOMIC-NOT: i32.extend8_s +; NOSIGNEXT-LABEL: i32_extend8_s +; NOSIGNEXT-NOT: i32.extend8_s define i32 @i32_extend8_s(i8 %x) { %a = sext i8 %x to i32 ret i32 %a @@ -23,8 +23,8 @@ define i32 @i32_extend8_s(i8 %x) { ; CHECK-NEXT: i32.extend16_s $push[[NUM:[0-9]+]]=, $0{{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} -; NOATOMIC-LABEL: i32_extend16_s -; NOATOMIC-NOT: i32.extend16_s +; NOSIGNEXT-LABEL: i32_extend16_s +; NOSIGNEXT-NOT: i32.extend16_s define i32 @i32_extend16_s(i16 %x) { %a = sext i16 %x to i32 ret i32 %a @@ -37,8 +37,8 @@ define i32 @i32_extend16_s(i16 %x) { ; CHECK-NEXT: i64.extend8_s $push[[NUM2:[0-9]+]]=, $pop[[NUM1]]{{$}} ; CHECK-NEXT: return $pop[[NUM2]]{{$}} -; NOATOMIC-LABEL: i64_extend8_s -; NOATOMIC-NOT: i64.extend8_s +; NOSIGNEXT-LABEL: i64_extend8_s +; NOSIGNEXT-NOT: i64.extend8_s define i64 @i64_extend8_s(i8 %x) { %a = sext i8 %x to i64 ret i64 %a @@ -51,8 +51,8 @@ define i64 @i64_extend8_s(i8 %x) { ; CHECK-NEXT: i64.extend16_s $push[[NUM2:[0-9]+]]=, $pop[[NUM1]]{{$}} ; CHECK-NEXT: return $pop[[NUM2]]{{$}} -; NOATOMIC-LABEL: i64_extend16_s -; NOATOMIC-NOT: i16.extend16_s +; NOSIGNEXT-LABEL: i64_extend16_s +; NOSIGNEXT-NOT: i16.extend16_s define i64 @i64_extend16_s(i16 %x) { %a = sext i16 %x to i64 ret i64 %a