forked from OSchip/llvm-project
[WebAssembly] Add sign extend instructions from atomics proposal
Select them from ISD::SIGN_EXTEND_INREG Differential Revision: https://reviews.llvm.org/D37603 remove spurious change llvm-svn: 313101
This commit is contained in:
parent
97ec1451a8
commit
a519fe5a37
|
@ -115,8 +115,12 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
|
|||
|
||||
// As a special case, these operators use the type to mean the type to
|
||||
// sign-extend from.
|
||||
for (auto T : {MVT::i1, MVT::i8, MVT::i16, MVT::i32})
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, T, Expand);
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
|
||||
if (!Subtarget->hasAtomics()) {
|
||||
// The Atomics feature includes signext intructions.
|
||||
for (auto T : {MVT::i8, MVT::i16, MVT::i32})
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, T, Expand);
|
||||
}
|
||||
|
||||
// Dynamic stack allocation: use the default expansion.
|
||||
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
||||
|
|
|
@ -26,6 +26,24 @@ 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 {
|
||||
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>;
|
||||
def I32_EXTEND16_S_I32 : I<(outs I32:$dst), (ins I32:$src),
|
||||
[(set I32:$dst, (sext_inreg I32:$src, i16))],
|
||||
"i32.extend16_s\t$dst, $src", 0xc1>;
|
||||
def I64_EXTEND8_S_I64 : I<(outs I64:$dst), (ins I64:$src),
|
||||
[(set I64:$dst, (sext_inreg I64:$src, i8))],
|
||||
"i64.extend8_s\t$dst, $src", 0xc2>;
|
||||
def I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src),
|
||||
[(set I64:$dst, (sext_inreg I64:$src, i16))],
|
||||
"i64.extend16_s\t$dst, $src", 0xc3>;
|
||||
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]
|
||||
|
||||
} // defs = [ARGUMENTS]
|
||||
|
||||
// Expand a "don't care" extend into zero-extend (chosen over sign-extend
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
; 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
|
||||
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
; CHECK-LABEL: i32_extend8_s:
|
||||
; CHECK-NEXT: .param i32{{$}}
|
||||
; CHECK-NEXT: .result i32{{$}}
|
||||
; 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
|
||||
define i32 @i32_extend8_s(i8 %x) {
|
||||
%a = sext i8 %x to i32
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: i32_extend16_s:
|
||||
; CHECK-NEXT: .param i32{{$}}
|
||||
; CHECK-NEXT: .result i32{{$}}
|
||||
; 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
|
||||
define i32 @i32_extend16_s(i16 %x) {
|
||||
%a = sext i16 %x to i32
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: i64_extend8_s:
|
||||
; CHECK-NEXT: .param i32{{$}}
|
||||
; CHECK-NEXT: .result i64{{$}}
|
||||
; CHECK-NEXT: i64.extend_u/i32 $push[[NUM1:[0-9]+]]=, $0{{$}}
|
||||
; 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
|
||||
define i64 @i64_extend8_s(i8 %x) {
|
||||
%a = sext i8 %x to i64
|
||||
ret i64 %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: i64_extend16_s:
|
||||
; CHECK-NEXT: .param i32{{$}}
|
||||
; CHECK-NEXT: .result i64{{$}}
|
||||
; CHECK-NEXT: i64.extend_u/i32 $push[[NUM1:[0-9]+]]=, $0{{$}}
|
||||
; 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
|
||||
define i64 @i64_extend16_s(i16 %x) {
|
||||
%a = sext i16 %x to i64
|
||||
ret i64 %a
|
||||
}
|
||||
|
||||
; No SIGN_EXTEND_INREG is needed for 32->64 extension.
|
||||
; CHECK-LABEL: i64_extend32_s:
|
||||
; CHECK-NEXT: .param i32{{$}}
|
||||
; CHECK-NEXT: .result i64{{$}}
|
||||
; CHECK-NEXT: i64.extend_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
|
||||
; CHECK-NEXT: return $pop[[NUM]]{{$}}
|
||||
define i64 @i64_extend32_s(i32 %x) {
|
||||
%a = sext i32 %x to i64
|
||||
ret i64 %a
|
||||
}
|
||||
|
Loading…
Reference in New Issue