[WebAssembly] Implement i64x2 comparisons

Removes the prototype builtin and intrinsic for i64x2.eq and implements that
instruction as well as the other i64x2 comparison instructions in the final SIMD
spec. Unsigned comparisons were not included in the final spec, so they still
need to be scalarized via a custom lowering.

Differential Revision: https://reviews.llvm.org/D99623
This commit is contained in:
Thomas Lively 2021-03-31 10:46:17 -07:00
parent df0b97dab0
commit 45783d0e8a
10 changed files with 69 additions and 71 deletions

View File

@ -215,7 +215,5 @@ TARGET_BUILTIN(__builtin_wasm_store16_lane, "vs*V8sIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_store32_lane, "vi*V4iIi", "n", "simd128") TARGET_BUILTIN(__builtin_wasm_store32_lane, "vi*V4iIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_store64_lane, "vLLi*V2LLiIi", "n", "simd128") TARGET_BUILTIN(__builtin_wasm_store64_lane, "vLLi*V2LLiIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_eq_i64x2, "V2LLiV2LLiV2LLi", "nc", "simd128")
#undef BUILTIN #undef BUILTIN
#undef TARGET_BUILTIN #undef TARGET_BUILTIN

View File

@ -17400,12 +17400,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_popcnt); Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_popcnt);
return Builder.CreateCall(Callee, {Vec}); return Builder.CreateCall(Callee, {Vec});
} }
case WebAssembly::BI__builtin_wasm_eq_i64x2: {
Value *LHS = EmitScalarExpr(E->getArg(0));
Value *RHS = EmitScalarExpr(E->getArg(1));
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_eq);
return Builder.CreateCall(Callee, {LHS, RHS});
}
case WebAssembly::BI__builtin_wasm_any_true_i8x16: case WebAssembly::BI__builtin_wasm_any_true_i8x16:
case WebAssembly::BI__builtin_wasm_any_true_i16x8: case WebAssembly::BI__builtin_wasm_any_true_i16x8:
case WebAssembly::BI__builtin_wasm_any_true_i32x4: case WebAssembly::BI__builtin_wasm_any_true_i32x4:

View File

@ -650,12 +650,6 @@ i8x16 popcnt(i8x16 x) {
// WEBASSEMBLY-NEXT: ret // WEBASSEMBLY-NEXT: ret
} }
i64x2 eq_i64x2(i64x2 x, i64x2 y) {
return __builtin_wasm_eq_i64x2(x, y);
// WEBASSEMBLY: call <2 x i64> @llvm.wasm.eq(<2 x i64> %x, <2 x i64> %y)
// WEBASSEMBLY-NEXT: ret
}
int any_true_i8x16(i8x16 x) { int any_true_i8x16(i8x16 x) {
return __builtin_wasm_any_true_i8x16(x); return __builtin_wasm_any_true_i8x16(x);
// WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x) // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x)

View File

@ -294,13 +294,6 @@ def int_wasm_extadd_pairwise_unsigned :
[LLVMSubdivide2VectorType<0>], [LLVMSubdivide2VectorType<0>],
[IntrNoMem, IntrSpeculatable]>; [IntrNoMem, IntrSpeculatable]>;
// TODO: Remove this intrinsic and the associated builtin if i64x2.eq gets
// merged to the proposal.
def int_wasm_eq :
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_v2i64_ty],
[IntrNoMem, IntrSpeculatable]>;
// TODO: Remove these if possible if they are merged to the spec. // TODO: Remove these if possible if they are merged to the spec.
def int_wasm_convert_low_signed : def int_wasm_convert_low_signed :
Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],

View File

@ -186,9 +186,9 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
for (auto T : {MVT::v4f32, MVT::v2f64}) for (auto T : {MVT::v4f32, MVT::v2f64})
setOperationAction(Op, T, Expand); setOperationAction(Op, T, Expand);
// Expand operations not supported for i64x2 vectors // Unsigned comparison operations are unavailable for i64x2 vectors.
for (unsigned CC = 0; CC < ISD::SETCC_INVALID; ++CC) for (auto CC : {ISD::SETUGT, ISD::SETUGE, ISD::SETULT, ISD::SETULE})
setCondCodeAction(static_cast<ISD::CondCode>(CC), MVT::v2i64, Custom); setCondCodeAction(CC, MVT::v2i64, Custom);
// 64x2 conversions are not in the spec // 64x2 conversions are not in the spec
for (auto Op : for (auto Op :
@ -1779,11 +1779,8 @@ WebAssemblyTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
SDValue WebAssemblyTargetLowering::LowerSETCC(SDValue Op, SDValue WebAssemblyTargetLowering::LowerSETCC(SDValue Op,
SelectionDAG &DAG) const { SelectionDAG &DAG) const {
SDLoc DL(Op); SDLoc DL(Op);
// The legalizer does not know how to expand the comparison modes of i64x2 // The legalizer does not know how to expand the unsupported comparison modes
// vectors because no comparison modes are supported. We could solve this by // of i64x2 vectors, so we manually unroll them here.
// expanding all i64x2 SETCC nodes, but that seems to expand f64x2 SETCC nodes
// (which return i64x2 results) as well. So instead we manually unroll i64x2
// comparisons here.
assert(Op->getOperand(0)->getSimpleValueType(0) == MVT::v2i64); assert(Op->getOperand(0)->getSimpleValueType(0) == MVT::v2i64);
SmallVector<SDValue, 2> LHS, RHS; SmallVector<SDValue, 2> LHS, RHS;
DAG.ExtractVectorElements(Op->getOperand(0), LHS); DAG.ExtractVectorElements(Op->getOperand(0), LHS);

View File

@ -650,32 +650,38 @@ multiclass SIMDConditionFP<string name, CondCode cond, bits<32> baseInst> {
// Equality: eq // Equality: eq
let isCommutable = 1 in { let isCommutable = 1 in {
defm EQ : SIMDConditionInt<"eq", SETEQ, 35>; defm EQ : SIMDConditionInt<"eq", SETEQ, 35>;
defm EQ : SIMDCondition<I64x2, "eq", SETEQ, 214>;
defm EQ : SIMDConditionFP<"eq", SETOEQ, 65>; defm EQ : SIMDConditionFP<"eq", SETOEQ, 65>;
} // isCommutable = 1 } // isCommutable = 1
// Non-equality: ne // Non-equality: ne
let isCommutable = 1 in { let isCommutable = 1 in {
defm NE : SIMDConditionInt<"ne", SETNE, 36>; defm NE : SIMDConditionInt<"ne", SETNE, 36>;
defm NE : SIMDCondition<I64x2, "ne", SETNE, 215>;
defm NE : SIMDConditionFP<"ne", SETUNE, 66>; defm NE : SIMDConditionFP<"ne", SETUNE, 66>;
} // isCommutable = 1 } // isCommutable = 1
// Less than: lt_s / lt_u / lt // Less than: lt_s / lt_u / lt
defm LT_S : SIMDConditionInt<"lt_s", SETLT, 37>; defm LT_S : SIMDConditionInt<"lt_s", SETLT, 37>;
defm LT_S : SIMDCondition<I64x2, "lt_s", SETLT, 216>;
defm LT_U : SIMDConditionInt<"lt_u", SETULT, 38>; defm LT_U : SIMDConditionInt<"lt_u", SETULT, 38>;
defm LT : SIMDConditionFP<"lt", SETOLT, 67>; defm LT : SIMDConditionFP<"lt", SETOLT, 67>;
// Greater than: gt_s / gt_u / gt // Greater than: gt_s / gt_u / gt
defm GT_S : SIMDConditionInt<"gt_s", SETGT, 39>; defm GT_S : SIMDConditionInt<"gt_s", SETGT, 39>;
defm GT_S : SIMDCondition<I64x2, "gt_s", SETGT, 217>;
defm GT_U : SIMDConditionInt<"gt_u", SETUGT, 40>; defm GT_U : SIMDConditionInt<"gt_u", SETUGT, 40>;
defm GT : SIMDConditionFP<"gt", SETOGT, 68>; defm GT : SIMDConditionFP<"gt", SETOGT, 68>;
// Less than or equal: le_s / le_u / le // Less than or equal: le_s / le_u / le
defm LE_S : SIMDConditionInt<"le_s", SETLE, 41>; defm LE_S : SIMDConditionInt<"le_s", SETLE, 41>;
defm LE_S : SIMDCondition<I64x2, "le_s", SETLE, 218>;
defm LE_U : SIMDConditionInt<"le_u", SETULE, 42>; defm LE_U : SIMDConditionInt<"le_u", SETULE, 42>;
defm LE : SIMDConditionFP<"le", SETOLE, 69>; defm LE : SIMDConditionFP<"le", SETOLE, 69>;
// Greater than or equal: ge_s / ge_u / ge // Greater than or equal: ge_s / ge_u / ge
defm GE_S : SIMDConditionInt<"ge_s", SETGE, 43>; defm GE_S : SIMDConditionInt<"ge_s", SETGE, 43>;
defm GE_S : SIMDCondition<I64x2, "ge_s", SETGE, 219>;
defm GE_U : SIMDConditionInt<"ge_u", SETUGE, 44>; defm GE_U : SIMDConditionInt<"ge_u", SETUGE, 44>;
defm GE : SIMDConditionFP<"ge", SETOGE, 70>; defm GE : SIMDConditionFP<"ge", SETOGE, 70>;
@ -692,14 +698,6 @@ foreach nodes = [[seteq, EQ_F64x2], [setne, NE_F64x2], [setlt, LT_F64x2],
def : Pat<(v2i64 (nodes[0] (v2f64 V128:$lhs), (v2f64 V128:$rhs))), def : Pat<(v2i64 (nodes[0] (v2f64 V128:$lhs), (v2f64 V128:$rhs))),
(nodes[1] $lhs, $rhs)>; (nodes[1] $lhs, $rhs)>;
// Prototype i64x2.eq
defm EQ_v2i64 :
SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs), (outs), (ins),
[(set (v2i64 V128:$dst),
(int_wasm_eq (v2i64 V128:$lhs), (v2i64 V128:$rhs)))],
"i64x2.eq\t$dst, $lhs, $rhs", "i64x2.eq", 192>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Bitwise operations // Bitwise operations
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -637,14 +637,20 @@ define <4 x i32> @compare_sext_uge_v4i32 (<4 x i32> %x, <4 x i32> %y) {
} }
; CHECK-LABEL: compare_eq_v2i64: ; CHECK-LABEL: compare_eq_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_eq_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_eq_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.eq $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i1> @compare_eq_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_eq_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp eq <2 x i64> %x, %y %res = icmp eq <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
} }
; CHECK-LABEL: compare_sext_eq_v2i64: ; CHECK-LABEL: compare_sext_eq_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sext_eq_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_eq_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.eq $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i64> @compare_sext_eq_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_eq_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp eq <2 x i64> %x, %y %cmp = icmp eq <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -652,14 +658,20 @@ define <2 x i64> @compare_sext_eq_v2i64 (<2 x i64> %x, <2 x i64> %y) {
} }
; CHECK-LABEL: compare_ne_v2i64: ; CHECK-LABEL: compare_ne_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_ne_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_ne_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.ne $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i1> @compare_ne_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_ne_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp ne <2 x i64> %x, %y %res = icmp ne <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
} }
; CHECK-LABEL: compare_sext_ne_v2i64: ; CHECK-LABEL: compare_sext_ne_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sext_ne_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_ne_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.ne $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i64> @compare_sext_ne_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_ne_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp ne <2 x i64> %x, %y %cmp = icmp ne <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -667,14 +679,20 @@ define <2 x i64> @compare_sext_ne_v2i64 (<2 x i64> %x, <2 x i64> %y) {
} }
; CHECK-LABEL: compare_slt_v2i64: ; CHECK-LABEL: compare_slt_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_slt_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_slt_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.lt_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i1> @compare_slt_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_slt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp slt <2 x i64> %x, %y %res = icmp slt <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
} }
; CHECK-LABEL: compare_sext_slt_v2i64: ; CHECK-LABEL: compare_sext_slt_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sext_slt_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_slt_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.lt_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i64> @compare_sext_slt_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_slt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp slt <2 x i64> %x, %y %cmp = icmp slt <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -683,6 +701,7 @@ define <2 x i64> @compare_sext_slt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: compare_ult_v2i64: ; CHECK-LABEL: compare_ult_v2i64:
; SIMD128-NEXT: .functype compare_ult_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_ult_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128: i64.lt_u
define <2 x i1> @compare_ult_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_ult_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp ult <2 x i64> %x, %y %res = icmp ult <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
@ -690,6 +709,7 @@ define <2 x i1> @compare_ult_v2i64 (<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: compare_sext_ult_v2i64: ; CHECK-LABEL: compare_sext_ult_v2i64:
; SIMD128-NEXT: .functype compare_sext_ult_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_ult_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128: i64.lt_u
define <2 x i64> @compare_sext_ult_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_ult_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp ult <2 x i64> %x, %y %cmp = icmp ult <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -697,14 +717,20 @@ define <2 x i64> @compare_sext_ult_v2i64 (<2 x i64> %x, <2 x i64> %y) {
} }
; CHECK-LABEL: compare_sle_v2i64: ; CHECK-LABEL: compare_sle_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sle_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sle_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.le_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i1> @compare_sle_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_sle_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp sle <2 x i64> %x, %y %res = icmp sle <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
} }
; CHECK-LABEL: compare_sext_sle_v2i64: ; CHECK-LABEL: compare_sext_sle_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sext_sle_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_sle_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.le_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i64> @compare_sext_sle_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_sle_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp sle <2 x i64> %x, %y %cmp = icmp sle <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -713,6 +739,7 @@ define <2 x i64> @compare_sext_sle_v2i64 (<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: compare_ule_v2i64: ; CHECK-LABEL: compare_ule_v2i64:
; SIMD128-NEXT: .functype compare_ule_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_ule_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128: i64.le_u
define <2 x i1> @compare_ule_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_ule_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp ule <2 x i64> %x, %y %res = icmp ule <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
@ -720,6 +747,7 @@ define <2 x i1> @compare_ule_v2i64 (<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: compare_sext_ule_v2i64: ; CHECK-LABEL: compare_sext_ule_v2i64:
; SIMD128-NEXT: .functype compare_sext_ule_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_ule_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128: i64.le_u
define <2 x i64> @compare_sext_ule_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_ule_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp ule <2 x i64> %x, %y %cmp = icmp ule <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -727,14 +755,20 @@ define <2 x i64> @compare_sext_ule_v2i64 (<2 x i64> %x, <2 x i64> %y) {
} }
; CHECK-LABEL: compare_sgt_v2i64: ; CHECK-LABEL: compare_sgt_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sgt_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sgt_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.gt_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i1> @compare_sgt_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_sgt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp sgt <2 x i64> %x, %y %res = icmp sgt <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
} }
; CHECK-LABEL: compare_sext_sgt_v2i64: ; CHECK-LABEL: compare_sext_sgt_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sext_sgt_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_sgt_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.gt_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i64> @compare_sext_sgt_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_sgt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp sgt <2 x i64> %x, %y %cmp = icmp sgt <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -743,6 +777,7 @@ define <2 x i64> @compare_sext_sgt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: compare_ugt_v2i64: ; CHECK-LABEL: compare_ugt_v2i64:
; SIMD128-NEXT: .functype compare_ugt_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_ugt_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128: i64.gt_u
define <2 x i1> @compare_ugt_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_ugt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp ugt <2 x i64> %x, %y %res = icmp ugt <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
@ -750,6 +785,7 @@ define <2 x i1> @compare_ugt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: compare_sext_ugt_v2i64: ; CHECK-LABEL: compare_sext_ugt_v2i64:
; SIMD128-NEXT: .functype compare_sext_ugt_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_ugt_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128: i64.gt_u
define <2 x i64> @compare_sext_ugt_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_ugt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp ugt <2 x i64> %x, %y %cmp = icmp ugt <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -757,14 +793,20 @@ define <2 x i64> @compare_sext_ugt_v2i64 (<2 x i64> %x, <2 x i64> %y) {
} }
; CHECK-LABEL: compare_sge_v2i64: ; CHECK-LABEL: compare_sge_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sge_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sge_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.ge_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i1> @compare_sge_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_sge_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp sge <2 x i64> %x, %y %res = icmp sge <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
} }
; CHECK-LABEL: compare_sext_sge_v2i64: ; CHECK-LABEL: compare_sext_sge_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-NEXT: .functype compare_sext_sge_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_sge_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i64x2.ge_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i64> @compare_sext_sge_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_sge_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp sge <2 x i64> %x, %y %cmp = icmp sge <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>
@ -773,6 +815,7 @@ define <2 x i64> @compare_sext_sge_v2i64 (<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: compare_uge_v2i64: ; CHECK-LABEL: compare_uge_v2i64:
; SIMD128-NEXT: .functype compare_uge_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_uge_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128: i64.ge_u
define <2 x i1> @compare_uge_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i1> @compare_uge_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%res = icmp uge <2 x i64> %x, %y %res = icmp uge <2 x i64> %x, %y
ret <2 x i1> %res ret <2 x i1> %res
@ -780,6 +823,7 @@ define <2 x i1> @compare_uge_v2i64 (<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: compare_sext_uge_v2i64: ; CHECK-LABEL: compare_sext_uge_v2i64:
; SIMD128-NEXT: .functype compare_sext_uge_v2i64 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: .functype compare_sext_uge_v2i64 (v128, v128) -> (v128){{$}}
; SIMD128: i64.ge_u
define <2 x i64> @compare_sext_uge_v2i64 (<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @compare_sext_uge_v2i64 (<2 x i64> %x, <2 x i64> %y) {
%cmp = icmp uge <2 x i64> %x, %y %cmp = icmp uge <2 x i64> %x, %y
%res = sext <2 x i1> %cmp to <2 x i64> %res = sext <2 x i1> %cmp to <2 x i64>

View File

@ -553,16 +553,6 @@ define <4 x i32> @trunc_sat_zero_unsigned_v4i32(<2 x double> %a) {
; ============================================================================== ; ==============================================================================
; 2 x i64 ; 2 x i64
; ============================================================================== ; ==============================================================================
; CHECK-LABEL: eq_v2i64:
; CHECK-NEXT: .functype eq_v2i64 (v128, v128) -> (v128){{$}}
; CHECK-NEXT: i64x2.eq $push[[R:[0-9]+]]=, $0, $1{{$}}
; CHECK-NEXT: return $pop[[R]]{{$}}
declare <2 x i64> @llvm.wasm.eq(<2 x i64>, <2 x i64>)
define <2 x i64> @eq_v2i64(<2 x i64> %x, <2 x i64> %y) {
%a = call <2 x i64> @llvm.wasm.eq(<2 x i64> %x, <2 x i64> %y)
ret <2 x i64> %a
}
; CHECK-LABEL: extend_low_s_v2i64: ; CHECK-LABEL: extend_low_s_v2i64:
; CHECK-NEXT: .functype extend_low_s_v2i64 (v128) -> (v128){{$}} ; CHECK-NEXT: .functype extend_low_s_v2i64 (v128) -> (v128){{$}}
; CHECK-NEXT: i64x2.extend_low_i32x4_s $push[[R:[0-9]+]]=, $0{{$}} ; CHECK-NEXT: i64x2.extend_low_i32x4_s $push[[R:[0-9]+]]=, $0{{$}}

View File

@ -299,33 +299,17 @@ define <2 x i64> @vselect_v2i64(<2 x i1> %c, <2 x i64> %x, <2 x i64> %y) {
ret <2 x i64> %res ret <2 x i64> %res
} }
define <2 x i64> @vselect_cmp_v2i64(<2 x i64> %a, <2 x i64> %b, define <2 x i64> @vselect_cmp_v2i64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: vselect_cmp_v2i64: ; CHECK-LABEL: vselect_cmp_v2i64:
; CHECK: .functype vselect_cmp_v2i64 (v128, v128, v128, v128) -> (v128) ; CHECK: .functype vselect_cmp_v2i64 (v128, v128, v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0: ; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 2 ; CHECK-NEXT: local.get 2
; CHECK-NEXT: local.get 3 ; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const -1
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 0 ; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.extract_lane 0
; CHECK-NEXT: local.get 1 ; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64x2.extract_lane 0 ; CHECK-NEXT: i64x2.lt_s
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: i64.select
; CHECK-NEXT: i64x2.splat
; CHECK-NEXT: i64.const -1
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.extract_lane 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64x2.extract_lane 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: i64.select
; CHECK-NEXT: i64x2.replace_lane 1
; CHECK-NEXT: v128.bitselect ; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return ; CHECK-NEXT: # fallthrough-return
<2 x i64> %x, <2 x i64> %y) {
%c = icmp slt <2 x i64> %a, %b %c = icmp slt <2 x i64> %a, %b
%res = select <2 x i1> %c, <2 x i64> %x, <2 x i64> %y %res = select <2 x i1> %c, <2 x i64> %x, <2 x i64> %y
ret <2 x i64> %res ret <2 x i64> %res

View File

@ -653,17 +653,23 @@ main:
# CHECK: i64x2.mul # encoding: [0xfd,0xd5,0x01] # CHECK: i64x2.mul # encoding: [0xfd,0xd5,0x01]
i64x2.mul i64x2.mul
# TODO: i64x2.eq # encoding: [0xfd,0xd6,0x01] # CHECK: i64x2.eq # encoding: [0xfd,0xd6,0x01]
i64x2.eq
# TODO: i64x2.ne # encoding: [0xfd,0xd7,0x01] # CHECK: i64x2.ne # encoding: [0xfd,0xd7,0x01]
i64x2.ne
# TODO: i64x2.lt_s # encoding: [0xfd,0xd8,0x01] # CHECK: i64x2.lt_s # encoding: [0xfd,0xd8,0x01]
i64x2.lt_s
# TODO: i64x2.gt_s # encoding: [0xfd,0xd9,0x01] # CHECK: i64x2.gt_s # encoding: [0xfd,0xd9,0x01]
i64x2.gt_s
# TODO: i64x2.le_s # encoding: [0xfd,0xda,0x01] # CHECK: i64x2.le_s # encoding: [0xfd,0xda,0x01]
i64x2.le_s
# TODO: i64x2.ge_s # encoding: [0xfd,0xdb,0x01] # CHECK: i64x2.ge_s # encoding: [0xfd,0xdb,0x01]
i64x2.ge_s
# CHECK: i64x2.extmul_low_i32x4_s # encoding: [0xfd,0xdc,0x01] # CHECK: i64x2.extmul_low_i32x4_s # encoding: [0xfd,0xdc,0x01]
i64x2.extmul_low_i32x4_s i64x2.extmul_low_i32x4_s