mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 09:34:42 +01:00
[WebAssembly] Update latest implemented SIMD instructions
Summary: Move instructions that have recently been implemented in V8 from the `unimplemented-simd128` target feature to the `simd128` target feature. The updated instructions match the update at https://github.com/WebAssembly/simd/pull/223. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D79973
This commit is contained in:
@@ -70,7 +70,7 @@ TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f64, "LLid", "nc", "nontrappi
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc", "nontrapping-fptoint")
|
||||
|
||||
// SIMD builtins
|
||||
TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16cV16cV16c", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16cV16cV16c", "nc", "simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "simd128")
|
||||
|
||||
@@ -50,8 +50,6 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_load(const void *__mem) {
|
||||
return ((const struct __wasm_v128_load_struct *)__mem)->__v;
|
||||
}
|
||||
|
||||
#ifdef __wasm_unimplemented_simd128__
|
||||
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS
|
||||
wasm_v8x16_load_splat(const void *__mem) {
|
||||
struct __wasm_v8x16_load_splat_struct {
|
||||
@@ -149,8 +147,6 @@ wasm_u64x2_load_32x2(const void *__mem) {
|
||||
return (v128_t) __builtin_convertvector(__v, __u64x2);
|
||||
}
|
||||
|
||||
#endif // __wasm_unimplemented_simd128__
|
||||
|
||||
static __inline__ void __DEFAULT_FN_ATTRS wasm_v128_store(void *__mem,
|
||||
v128_t __a) {
|
||||
// UB-free unaligned access copied from xmmintrin.h
|
||||
@@ -564,15 +560,11 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_xor(v128_t __a,
|
||||
return __a ^ __b;
|
||||
}
|
||||
|
||||
#ifdef __wasm_unimplemented_simd128__
|
||||
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_andnot(v128_t __a,
|
||||
v128_t __b) {
|
||||
return __a & ~__b;
|
||||
}
|
||||
|
||||
#endif // __wasm_unimplemented_simd128__
|
||||
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_bitselect(v128_t __a,
|
||||
v128_t __b,
|
||||
v128_t __mask) {
|
||||
@@ -1066,15 +1058,11 @@ wasm_f32x4_convert_u32x4(v128_t __a) {
|
||||
__c1 * 8, __c1 * 8 + 1, __c1 * 8 + 2, __c1 * 8 + 3, __c1 * 8 + 4, \
|
||||
__c1 * 8 + 5, __c1 * 8 + 6, __c1 * 8 + 7))
|
||||
|
||||
#ifdef __wasm_unimplemented_simd128__
|
||||
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v8x16_swizzle(v128_t __a,
|
||||
v128_t __b) {
|
||||
return (v128_t)__builtin_wasm_swizzle_v8x16((__i8x16)__a, (__i8x16)__b);
|
||||
}
|
||||
|
||||
#endif // __wasm_unimplemented_simd128__
|
||||
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS
|
||||
wasm_i8x16_narrow_i16x8(v128_t __a, v128_t __b) {
|
||||
return (v128_t)__builtin_wasm_narrow_s_i8x16_i16x8((__i16x8)__a,
|
||||
|
||||
@@ -239,12 +239,10 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
|
||||
}
|
||||
}
|
||||
// But some vector extending loads are legal
|
||||
if (Subtarget->hasUnimplementedSIMD128()) {
|
||||
for (auto Ext : {ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}) {
|
||||
setLoadExtAction(Ext, MVT::v8i16, MVT::v8i8, Legal);
|
||||
setLoadExtAction(Ext, MVT::v4i32, MVT::v4i16, Legal);
|
||||
setLoadExtAction(Ext, MVT::v2i64, MVT::v2i32, Legal);
|
||||
}
|
||||
for (auto Ext : {ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}) {
|
||||
setLoadExtAction(Ext, MVT::v8i16, MVT::v8i8, Legal);
|
||||
setLoadExtAction(Ext, MVT::v4i32, MVT::v4i16, Legal);
|
||||
setLoadExtAction(Ext, MVT::v2i64, MVT::v2i32, Legal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,8 +597,6 @@ bool WebAssemblyTargetLowering::isIntDivCheap(EVT VT,
|
||||
}
|
||||
|
||||
bool WebAssemblyTargetLowering::isVectorLoadExtDesirable(SDValue ExtVal) const {
|
||||
if (!Subtarget->hasUnimplementedSIMD128())
|
||||
return false;
|
||||
MVT ExtT = ExtVal.getSimpleValueType();
|
||||
MVT MemT = cast<LoadSDNode>(ExtVal->getOperand(0))->getSimpleValueType(0);
|
||||
return (ExtT == MVT::v8i16 && MemT == MVT::v8i8) ||
|
||||
@@ -1423,7 +1419,7 @@ SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
|
||||
const EVT VecT = Op.getValueType();
|
||||
const EVT LaneT = Op.getOperand(0).getValueType();
|
||||
const size_t Lanes = Op.getNumOperands();
|
||||
bool CanSwizzle = Subtarget->hasUnimplementedSIMD128() && VecT == MVT::v16i8;
|
||||
bool CanSwizzle = VecT == MVT::v16i8;
|
||||
|
||||
// BUILD_VECTORs are lowered to the instruction that initializes the highest
|
||||
// possible number of lanes at once followed by a sequence of replace_lane
|
||||
@@ -1522,38 +1518,37 @@ SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
|
||||
// original instruction
|
||||
std::function<bool(size_t, const SDValue &)> IsLaneConstructed;
|
||||
SDValue Result;
|
||||
if (Subtarget->hasUnimplementedSIMD128()) {
|
||||
// Prefer swizzles over vector consts over splats
|
||||
if (NumSwizzleLanes >= NumSplatLanes &&
|
||||
NumSwizzleLanes >= NumConstantLanes) {
|
||||
Result = DAG.getNode(WebAssemblyISD::SWIZZLE, DL, VecT, SwizzleSrc,
|
||||
SwizzleIndices);
|
||||
auto Swizzled = std::make_pair(SwizzleSrc, SwizzleIndices);
|
||||
IsLaneConstructed = [&, Swizzled](size_t I, const SDValue &Lane) {
|
||||
return Swizzled == GetSwizzleSrcs(I, Lane);
|
||||
};
|
||||
} else if (NumConstantLanes >= NumSplatLanes) {
|
||||
SmallVector<SDValue, 16> ConstLanes;
|
||||
for (const SDValue &Lane : Op->op_values()) {
|
||||
if (IsConstant(Lane)) {
|
||||
ConstLanes.push_back(Lane);
|
||||
} else if (LaneT.isFloatingPoint()) {
|
||||
ConstLanes.push_back(DAG.getConstantFP(0, DL, LaneT));
|
||||
} else {
|
||||
ConstLanes.push_back(DAG.getConstant(0, DL, LaneT));
|
||||
}
|
||||
// Prefer swizzles over vector consts over splats
|
||||
if (NumSwizzleLanes >= NumSplatLanes &&
|
||||
(!Subtarget->hasUnimplementedSIMD128() ||
|
||||
NumSwizzleLanes >= NumConstantLanes)) {
|
||||
Result = DAG.getNode(WebAssemblyISD::SWIZZLE, DL, VecT, SwizzleSrc,
|
||||
SwizzleIndices);
|
||||
auto Swizzled = std::make_pair(SwizzleSrc, SwizzleIndices);
|
||||
IsLaneConstructed = [&, Swizzled](size_t I, const SDValue &Lane) {
|
||||
return Swizzled == GetSwizzleSrcs(I, Lane);
|
||||
};
|
||||
} else if (NumConstantLanes >= NumSplatLanes &&
|
||||
Subtarget->hasUnimplementedSIMD128()) {
|
||||
SmallVector<SDValue, 16> ConstLanes;
|
||||
for (const SDValue &Lane : Op->op_values()) {
|
||||
if (IsConstant(Lane)) {
|
||||
ConstLanes.push_back(Lane);
|
||||
} else if (LaneT.isFloatingPoint()) {
|
||||
ConstLanes.push_back(DAG.getConstantFP(0, DL, LaneT));
|
||||
} else {
|
||||
ConstLanes.push_back(DAG.getConstant(0, DL, LaneT));
|
||||
}
|
||||
Result = DAG.getBuildVector(VecT, DL, ConstLanes);
|
||||
IsLaneConstructed = [&](size_t _, const SDValue &Lane) {
|
||||
return IsConstant(Lane);
|
||||
};
|
||||
}
|
||||
Result = DAG.getBuildVector(VecT, DL, ConstLanes);
|
||||
IsLaneConstructed = [&](size_t _, const SDValue &Lane) {
|
||||
return IsConstant(Lane);
|
||||
};
|
||||
}
|
||||
if (!Result) {
|
||||
// Use a splat, but possibly a load_splat
|
||||
LoadSDNode *SplattedLoad;
|
||||
if (Subtarget->hasUnimplementedSIMD128() &&
|
||||
(SplattedLoad = dyn_cast<LoadSDNode>(SplatValue)) &&
|
||||
if ((SplattedLoad = dyn_cast<LoadSDNode>(SplatValue)) &&
|
||||
SplattedLoad->getMemoryVT() == VecT.getVectorElementType()) {
|
||||
Result = DAG.getMemIntrinsicNode(
|
||||
WebAssemblyISD::LOAD_SPLAT, DL, DAG.getVTList(VecT),
|
||||
|
||||
@@ -58,8 +58,7 @@ def : LoadPatGlobalAddrOffOnly<vec_t, load, LOAD_V128>;
|
||||
|
||||
// vNxM.load_splat
|
||||
multiclass SIMDLoadSplat<string vec, bits<32> simdop> {
|
||||
let mayLoad = 1, UseNamedOperandTable = 1,
|
||||
Predicates = [HasUnimplementedSIMD128] in
|
||||
let mayLoad = 1, UseNamedOperandTable = 1 in
|
||||
defm LOAD_SPLAT_#vec :
|
||||
SIMD_I<(outs V128:$dst), (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
|
||||
(outs), (ins P2Align:$p2align, offset32_op:$off), [],
|
||||
@@ -77,7 +76,6 @@ def wasm_load_splat : SDNode<"WebAssemblyISD::LOAD_SPLAT", wasm_load_splat_t,
|
||||
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
|
||||
def load_splat : PatFrag<(ops node:$addr), (wasm_load_splat node:$addr)>;
|
||||
|
||||
let Predicates = [HasUnimplementedSIMD128] in
|
||||
foreach args = [["v16i8", "v8x16"], ["v8i16", "v16x8"], ["v4i32", "v32x4"],
|
||||
["v2i64", "v64x2"], ["v4f32", "v32x4"], ["v2f64", "v64x2"]] in {
|
||||
def : LoadPatNoOffset<!cast<ValueType>(args[0]),
|
||||
@@ -101,8 +99,7 @@ def : LoadPatGlobalAddrOffOnly<!cast<ValueType>(args[0]),
|
||||
|
||||
// Load and extend
|
||||
multiclass SIMDLoadExtend<ValueType vec_t, string name, bits<32> simdop> {
|
||||
let mayLoad = 1, UseNamedOperandTable = 1,
|
||||
Predicates = [HasUnimplementedSIMD128] in {
|
||||
let mayLoad = 1, UseNamedOperandTable = 1 in {
|
||||
defm LOAD_EXTEND_S_#vec_t :
|
||||
SIMD_I<(outs V128:$dst), (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
|
||||
(outs), (ins P2Align:$p2align, offset32_op:$off), [],
|
||||
@@ -120,7 +117,6 @@ defm "" : SIMDLoadExtend<v8i16, "i16x8.load8x8", 1>;
|
||||
defm "" : SIMDLoadExtend<v4i32, "i32x4.load16x4", 3>;
|
||||
defm "" : SIMDLoadExtend<v2i64, "i64x2.load32x2", 5>;
|
||||
|
||||
let Predicates = [HasUnimplementedSIMD128] in
|
||||
foreach types = [[v8i16, i8], [v4i32, i16], [v2i64, i32]] in
|
||||
foreach exts = [["sextloadv", "_S"],
|
||||
["zextloadv", "_U"],
|
||||
@@ -273,7 +269,6 @@ def : Pat<(vec_t (wasm_shuffle (vec_t V128:$x), (vec_t V128:$y),
|
||||
// Swizzle lanes: v8x16.swizzle
|
||||
def wasm_swizzle_t : SDTypeProfile<1, 2, []>;
|
||||
def wasm_swizzle : SDNode<"WebAssemblyISD::SWIZZLE", wasm_swizzle_t>;
|
||||
let Predicates = [HasUnimplementedSIMD128] in
|
||||
defm SWIZZLE :
|
||||
SIMD_I<(outs V128:$dst), (ins V128:$src, V128:$mask), (outs), (ins),
|
||||
[(set (v16i8 V128:$dst),
|
||||
@@ -517,7 +512,7 @@ multiclass SIMDUnary<ValueType vec_t, string vec, SDNode node, string name,
|
||||
foreach vec_t = [v16i8, v8i16, v4i32, v2i64] in
|
||||
defm NOT: SIMDUnary<vec_t, "v128", vnot, "not", 77>;
|
||||
|
||||
// Bitwise logic: v128.and / v128.andnot / v128.or / v128.xor
|
||||
// Bitwise logic: v128.and / v128.or / v128.xor
|
||||
let isCommutable = 1 in {
|
||||
defm AND : SIMDBitwise<and, "and", 78>;
|
||||
defm OR : SIMDBitwise<or, "or", 80>;
|
||||
@@ -526,7 +521,6 @@ defm XOR : SIMDBitwise<xor, "xor", 81>;
|
||||
|
||||
// Bitwise logic: v128.andnot
|
||||
def andnot : PatFrag<(ops node:$left, node:$right), (and $left, (vnot $right))>;
|
||||
let Predicates = [HasUnimplementedSIMD128] in
|
||||
defm ANDNOT : SIMDBitwise<andnot, "andnot", 79>;
|
||||
|
||||
// Bitwise select: v128.bitselect
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-SLOW
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-FAST
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128-VM
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128-VM
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 -fast-isel | FileCheck %s
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes CHECK,NO-SIMD128
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
|
||||
|
||||
@@ -308,7 +308,6 @@ define <16 x i8> @not_v16i8(<16 x i8> %x) {
|
||||
|
||||
; CHECK-LABEL: andnot_v16i8:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: v128.andnot
|
||||
; SIMD128-NEXT: .functype andnot_v16i8 (v128, v128) -> (v128){{$}}
|
||||
; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
|
||||
; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
|
||||
@@ -625,7 +624,6 @@ define <8 x i16> @not_v8i16(<8 x i16> %x) {
|
||||
}
|
||||
|
||||
; CHECK-LABEL: andnot_v8i16:
|
||||
; SIMD128-VM-NOT: v128.andnot
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-NEXT: .functype andnot_v8i16 (v128, v128) -> (v128){{$}}
|
||||
; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
|
||||
@@ -904,7 +902,6 @@ define <4 x i32> @not_v4i32(<4 x i32> %x) {
|
||||
}
|
||||
|
||||
; CHECK-LABEL: andnot_v4i32:
|
||||
; SIMD128-VM-NOT: v128.andnot
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-NEXT: .functype andnot_v4i32 (v128, v128) -> (v128){{$}}
|
||||
; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
|
||||
@@ -1222,7 +1219,6 @@ define <2 x i64> @not_v2i64(<2 x i64> %x) {
|
||||
}
|
||||
|
||||
; CHECK-LABEL: andnot_v2i64:
|
||||
; SIMD128-VM-NOT: v128.andnot
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-NEXT: .functype andnot_v2i64 (v128, v128) -> (v128){{$}}
|
||||
; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 | FileCheck %s
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 | FileCheck %s --check-prefixes=CHECK,UNIMP
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s --check-prefixes=CHECK,SIMD-VM
|
||||
|
||||
; Test that the logic to choose between v128.const vector
|
||||
; initialization and splat vector initialization and to optimize the
|
||||
@@ -9,9 +10,10 @@ target triple = "wasm32-unknown-unknown"
|
||||
|
||||
; CHECK-LABEL: same_const_one_replaced_i16x8:
|
||||
; CHECK-NEXT: .functype same_const_one_replaced_i16x8 (i32) -> (v128)
|
||||
; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 42, 42, 42, 42, 42, 0, 42, 42
|
||||
; CHECK-NEXT: i16x8.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 5, $0
|
||||
; CHECK-NEXT: return $pop[[L1]]
|
||||
; UNIMP-NEXT: v128.const $push[[L0:[0-9]+]]=, 42, 42, 42, 42, 42, 0, 42, 42
|
||||
; UNIMP-NEXT: i16x8.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 5, $0
|
||||
; UNIMP-NEXT: return $pop[[L1]]
|
||||
; SIMD-VM: i16x8.splat
|
||||
define <8 x i16> @same_const_one_replaced_i16x8(i16 %x) {
|
||||
%v = insertelement
|
||||
<8 x i16> <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>,
|
||||
@@ -22,9 +24,10 @@ define <8 x i16> @same_const_one_replaced_i16x8(i16 %x) {
|
||||
|
||||
; CHECK-LABEL: different_const_one_replaced_i16x8:
|
||||
; CHECK-NEXT: .functype different_const_one_replaced_i16x8 (i32) -> (v128)
|
||||
; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 1, -2, 3, -4, 5, 0, 7, -8
|
||||
; CHECK-NEXT: i16x8.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 5, $0
|
||||
; CHECK-NEXT: return $pop[[L1]]
|
||||
; UNIMP-NEXT: v128.const $push[[L0:[0-9]+]]=, 1, -2, 3, -4, 5, 0, 7, -8
|
||||
; UNIMP-NEXT: i16x8.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 5, $0
|
||||
; UNIMP-NEXT: return $pop[[L1]]
|
||||
; SIMD-VM: i16x8.splat
|
||||
define <8 x i16> @different_const_one_replaced_i16x8(i16 %x) {
|
||||
%v = insertelement
|
||||
<8 x i16> <i16 1, i16 -2, i16 3, i16 -4, i16 5, i16 -6, i16 7, i16 -8>,
|
||||
@@ -35,9 +38,10 @@ define <8 x i16> @different_const_one_replaced_i16x8(i16 %x) {
|
||||
|
||||
; CHECK-LABEL: same_const_one_replaced_f32x4:
|
||||
; CHECK-NEXT: .functype same_const_one_replaced_f32x4 (f32) -> (v128)
|
||||
; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 0x1.5p5, 0x1.5p5, 0x0p0, 0x1.5p5
|
||||
; CHECK-NEXT: f32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 2, $0
|
||||
; CHECK-NEXT: return $pop[[L1]]
|
||||
; UNIMP-NEXT: v128.const $push[[L0:[0-9]+]]=, 0x1.5p5, 0x1.5p5, 0x0p0, 0x1.5p5
|
||||
; UNIMP-NEXT: f32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 2, $0
|
||||
; UNIMP-NEXT: return $pop[[L1]]
|
||||
; SIMD-VM: f32x4.splat
|
||||
define <4 x float> @same_const_one_replaced_f32x4(float %x) {
|
||||
%v = insertelement
|
||||
<4 x float> <float 42., float 42., float 42., float 42.>,
|
||||
@@ -48,9 +52,10 @@ define <4 x float> @same_const_one_replaced_f32x4(float %x) {
|
||||
|
||||
; CHECK-LABEL: different_const_one_replaced_f32x4:
|
||||
; CHECK-NEXT: .functype different_const_one_replaced_f32x4 (f32) -> (v128)
|
||||
; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 0x1p0, 0x1p1, 0x0p0, 0x1p2
|
||||
; CHECK-NEXT: f32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 2, $0
|
||||
; CHECK-NEXT: return $pop[[L1]]
|
||||
; UNIMP-NEXT: v128.const $push[[L0:[0-9]+]]=, 0x1p0, 0x1p1, 0x0p0, 0x1p2
|
||||
; UNIMP-NEXT: f32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 2, $0
|
||||
; UNIMP-NEXT: return $pop[[L1]]
|
||||
; SIMD-VM: f32x4.splat
|
||||
define <4 x float> @different_const_one_replaced_f32x4(float %x) {
|
||||
%v = insertelement
|
||||
<4 x float> <float 1., float 2., float 3., float 4.>,
|
||||
@@ -61,8 +66,9 @@ define <4 x float> @different_const_one_replaced_f32x4(float %x) {
|
||||
|
||||
; CHECK-LABEL: splat_common_const_i32x4:
|
||||
; CHECK-NEXT: .functype splat_common_const_i32x4 () -> (v128)
|
||||
; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 0, 3, 3, 1
|
||||
; CHECK-NEXT: return $pop[[L0]]
|
||||
; UNIMP-NEXT: v128.const $push[[L0:[0-9]+]]=, 0, 3, 3, 1
|
||||
; UNIMP-NEXT: return $pop[[L0]]
|
||||
; SIMD-VM: i32x4.splat
|
||||
define <4 x i32> @splat_common_const_i32x4() {
|
||||
ret <4 x i32> <i32 undef, i32 3, i32 3, i32 1>
|
||||
}
|
||||
@@ -195,11 +201,12 @@ define <16 x i8> @mashup_swizzle_i8x16(<16 x i8> %src, <16 x i8> %mask, i8 %spla
|
||||
|
||||
; CHECK-LABEL: mashup_const_i8x16:
|
||||
; CHECK-NEXT: .functype mashup_const_i8x16 (v128, v128, i32) -> (v128)
|
||||
; CHECK: v128.const $push[[L0:[0-9]+]]=, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0
|
||||
; CHECK: i8x16.replace_lane
|
||||
; CHECK: i8x16.replace_lane
|
||||
; CHECK: i8x16.replace_lane
|
||||
; CHECK: return
|
||||
; UNIMP: v128.const $push[[L0:[0-9]+]]=, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0
|
||||
; UNIMP: i8x16.replace_lane
|
||||
; UNIMP: i8x16.replace_lane
|
||||
; UNIMP: i8x16.replace_lane
|
||||
; UNIMP: return
|
||||
; SIMD-VM: i8x16.splat
|
||||
define <16 x i8> @mashup_const_i8x16(<16 x i8> %src, <16 x i8> %mask, i8 %splatted) {
|
||||
; swizzle 0
|
||||
%m0 = extractelement <16 x i8> %mask, i32 0
|
||||
@@ -238,8 +245,9 @@ define <16 x i8> @mashup_splat_i8x16(<16 x i8> %src, <16 x i8> %mask, i8 %splatt
|
||||
|
||||
; CHECK-LABEL: undef_const_insert_f32x4:
|
||||
; CHECK-NEXT: .functype undef_const_insert_f32x4 () -> (v128)
|
||||
; CHECK-NEXT: v128.const $push[[L0:[0-9]+]]=, 0x0p0, 0x1.5p5, 0x0p0, 0x0p0
|
||||
; CHECK-NEXT: return $pop[[L0]]
|
||||
; UNIMP-NEXT: v128.const $push[[L0:[0-9]+]]=, 0x0p0, 0x1.5p5, 0x0p0, 0x0p0
|
||||
; UNIMP-NEXT: return $pop[[L0]]
|
||||
; SIMD-VM: f32x4.splat
|
||||
define <4 x float> @undef_const_insert_f32x4() {
|
||||
%v = insertelement <4 x float> undef, float 42., i32 1
|
||||
ret <4 x float> %v
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-disable-explicit-locals -mattr=+unimplemented-simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-disable-explicit-locals -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128-VM
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-disable-explicit-locals -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
|
||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-disable-explicit-locals | FileCheck %s --check-prefixes CHECK,NO-SIMD128
|
||||
|
||||
; Test SIMD loads and stores
|
||||
@@ -21,7 +20,6 @@ define <16 x i8> @load_v16i8(<16 x i8>* %p) {
|
||||
}
|
||||
|
||||
; CHECK-LABEL: load_splat_v16i8:
|
||||
; SIMD128-VM-NOT: v8x16.load_splat
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-NEXT: .functype load_splat_v16i8 (i32) -> (v128){{$}}
|
||||
; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 0($0){{$}}
|
||||
@@ -1594,7 +1592,6 @@ define <2 x i64> @load_zext_v2i64(<2 x i32>* %p) {
|
||||
|
||||
; CHECK-LABEL: load_ext_v2i64:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: load32x2
|
||||
; SIMD128-NEXT: .functype load_ext_v2i64 (i32) -> (v128){{$}}
|
||||
; SIMD128-NEXT: i64x2.load32x2_u $push[[R:[0-9]+]]=, 0($0){{$}}
|
||||
; SIMD128-NEXT: return $pop[[R]]{{$}}
|
||||
@@ -1661,7 +1658,6 @@ define <2 x i64> @load_zext_v2i64_with_folded_offset(<2 x i32>* %p) {
|
||||
|
||||
; CHECK-LABEL: load_ext_v2i64_with_folded_offset:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: load32x2
|
||||
; SIMD128-NEXT: .functype load_ext_v2i64_with_folded_offset (i32) -> (v128){{$}}
|
||||
; SIMD128-NEXT: i64x2.load32x2_u $push[[R:[0-9]+]]=, 16($0){{$}}
|
||||
; SIMD128-NEXT: return $pop[[R]]{{$}}
|
||||
@@ -1723,7 +1719,6 @@ define <2 x i64> @load_zext_v2i64_with_folded_gep_offset(<2 x i32>* %p) {
|
||||
|
||||
; CHECK-LABEL: load_ext_v2i64_with_folded_gep_offset:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: load32x2
|
||||
; SIMD128-NEXT: .functype load_ext_v2i64_with_folded_gep_offset (i32) -> (v128){{$}}
|
||||
; SIMD128-NEXT: i64x2.load32x2_u $push[[R:[0-9]+]]=, 8($0){{$}}
|
||||
; SIMD128-NEXT: return $pop[[R]]{{$}}
|
||||
@@ -1791,7 +1786,6 @@ define <2 x i64> @load_zext_v2i64_with_unfolded_gep_negative_offset(<2 x i32>* %
|
||||
|
||||
; CHECK-LABEL: load_ext_v2i64_with_unfolded_gep_negative_offset:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: load32x2
|
||||
; SIMD128-NEXT: .functype load_ext_v2i64_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
|
||||
; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, -8{{$}}
|
||||
; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
|
||||
@@ -1869,7 +1863,6 @@ define <2 x i64> @load_zext_v2i64_with_unfolded_offset(<2 x i32>* %p) {
|
||||
|
||||
; CHECK-LABEL: load_ext_v2i64_with_unfolded_offset:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: load32x2
|
||||
; SIMD128-NEXT: .functype load_ext_v2i64_with_unfolded_offset (i32) -> (v128){{$}}
|
||||
; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 16{{$}}
|
||||
; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
|
||||
@@ -1941,7 +1934,6 @@ define <2 x i64> @load_zext_v2i64_with_unfolded_gep_offset(<2 x i32>* %p) {
|
||||
|
||||
; CHECK-LABEL: load_ext_v2i64_with_unfolded_gep_offset:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: load32x2
|
||||
; SIMD128-NEXT: .functype load_ext_v2i64_with_unfolded_gep_offset (i32) -> (v128){{$}}
|
||||
; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 8{{$}}
|
||||
; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
|
||||
@@ -2007,7 +1999,6 @@ define <2 x i64> @load_zext_v2i64_from_numeric_address() {
|
||||
|
||||
; CHECK-LABEL: load_ext_v2i64_from_numeric_address:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: load32x2
|
||||
; SIMD128-NEXT: .functype load_ext_v2i64_from_numeric_address () -> (v128){{$}}
|
||||
; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
|
||||
; SIMD128-NEXT: i64x2.load32x2_u $push[[R:[0-9]+]]=, 32($pop[[L0]]){{$}}
|
||||
@@ -2071,7 +2062,6 @@ define <2 x i64> @load_zext_v2i64_from_global_address() {
|
||||
|
||||
; CHECK-LABEL: load_ext_v2i64_from_global_address:
|
||||
; NO-SIMD128-NOT: v128
|
||||
; SIMD128-VM-NOT: load32x2
|
||||
; SIMD128-NEXT: .functype load_ext_v2i64_from_global_address () -> (v128){{$}}
|
||||
; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
|
||||
; SIMD128-NEXT: i64x2.load32x2_u $push[[R:[0-9]+]]=, gv_v2i32($pop[[L0]]){{$}}
|
||||
|
||||
Reference in New Issue
Block a user