diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -215,7 +215,5 @@ TARGET_BUILTIN(__builtin_wasm_store32_lane, "vi*V4iIi", "n", "simd128") TARGET_BUILTIN(__builtin_wasm_store64_lane, "vLLi*V2LLiIi", "n", "simd128") -TARGET_BUILTIN(__builtin_wasm_eq_i64x2, "V2LLiV2LLiV2LLi", "nc", "simd128") - #undef BUILTIN #undef TARGET_BUILTIN diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -17400,12 +17400,6 @@ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_popcnt); 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_i16x8: case WebAssembly::BI__builtin_wasm_any_true_i32x4: diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -650,12 +650,6 @@ // 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) { return __builtin_wasm_any_true_i8x16(x); // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x) diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td --- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -294,13 +294,6 @@ [LLVMSubdivide2VectorType<0>], [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. def int_wasm_convert_low_signed : Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -186,9 +186,9 @@ for (auto T : {MVT::v4f32, MVT::v2f64}) setOperationAction(Op, T, Expand); - // Expand operations not supported for i64x2 vectors - for (unsigned CC = 0; CC < ISD::SETCC_INVALID; ++CC) - setCondCodeAction(static_cast(CC), MVT::v2i64, Custom); + // Unsigned comparison operations are unavailable for i64x2 vectors. + for (auto CC : {ISD::SETUGT, ISD::SETUGE, ISD::SETULT, ISD::SETULE}) + setCondCodeAction(CC, MVT::v2i64, Custom); // 64x2 conversions are not in the spec for (auto Op : @@ -1779,11 +1779,8 @@ SDValue WebAssemblyTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); - // The legalizer does not know how to expand the comparison modes of i64x2 - // vectors because no comparison modes are supported. We could solve this by - // 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. + // The legalizer does not know how to expand the unsupported comparison modes + // of i64x2 vectors, so we manually unroll them here. assert(Op->getOperand(0)->getSimpleValueType(0) == MVT::v2i64); SmallVector LHS, RHS; DAG.ExtractVectorElements(Op->getOperand(0), LHS); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -650,32 +650,38 @@ // Equality: eq let isCommutable = 1 in { defm EQ : SIMDConditionInt<"eq", SETEQ, 35>; +defm EQ : SIMDCondition; defm EQ : SIMDConditionFP<"eq", SETOEQ, 65>; } // isCommutable = 1 // Non-equality: ne let isCommutable = 1 in { defm NE : SIMDConditionInt<"ne", SETNE, 36>; +defm NE : SIMDCondition; defm NE : SIMDConditionFP<"ne", SETUNE, 66>; } // isCommutable = 1 // Less than: lt_s / lt_u / lt defm LT_S : SIMDConditionInt<"lt_s", SETLT, 37>; +defm LT_S : SIMDCondition; defm LT_U : SIMDConditionInt<"lt_u", SETULT, 38>; defm LT : SIMDConditionFP<"lt", SETOLT, 67>; // Greater than: gt_s / gt_u / gt defm GT_S : SIMDConditionInt<"gt_s", SETGT, 39>; +defm GT_S : SIMDCondition; defm GT_U : SIMDConditionInt<"gt_u", SETUGT, 40>; defm GT : SIMDConditionFP<"gt", SETOGT, 68>; // Less than or equal: le_s / le_u / le defm LE_S : SIMDConditionInt<"le_s", SETLE, 41>; +defm LE_S : SIMDCondition; defm LE_U : SIMDConditionInt<"le_u", SETULE, 42>; defm LE : SIMDConditionFP<"le", SETOLE, 69>; // Greater than or equal: ge_s / ge_u / ge defm GE_S : SIMDConditionInt<"ge_s", SETGE, 43>; +defm GE_S : SIMDCondition; defm GE_U : SIMDConditionInt<"ge_u", SETUGE, 44>; defm GE : SIMDConditionFP<"ge", SETOGE, 70>; @@ -692,14 +698,6 @@ def : Pat<(v2i64 (nodes[0] (v2f64 V128:$lhs), (v2f64 V128:$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 //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/WebAssembly/simd-comparisons.ll b/llvm/test/CodeGen/WebAssembly/simd-comparisons.ll --- a/llvm/test/CodeGen/WebAssembly/simd-comparisons.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-comparisons.ll @@ -637,14 +637,20 @@ } ; CHECK-LABEL: compare_eq_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %res = icmp eq <2 x i64> %x, %y ret <2 x i1> %res } ; CHECK-LABEL: compare_sext_eq_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %cmp = icmp eq <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -652,14 +658,20 @@ } ; CHECK-LABEL: compare_ne_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %res = icmp ne <2 x i64> %x, %y ret <2 x i1> %res } ; CHECK-LABEL: compare_sext_ne_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %cmp = icmp ne <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -667,14 +679,20 @@ } ; CHECK-LABEL: compare_slt_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %res = icmp slt <2 x i64> %x, %y ret <2 x i1> %res } ; CHECK-LABEL: compare_sext_slt_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %cmp = icmp slt <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -683,6 +701,7 @@ ; CHECK-LABEL: compare_ult_v2i64: ; 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) { %res = icmp ult <2 x i64> %x, %y ret <2 x i1> %res @@ -690,6 +709,7 @@ ; CHECK-LABEL: compare_sext_ult_v2i64: ; 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) { %cmp = icmp ult <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -697,14 +717,20 @@ } ; CHECK-LABEL: compare_sle_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %res = icmp sle <2 x i64> %x, %y ret <2 x i1> %res } ; CHECK-LABEL: compare_sext_sle_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %cmp = icmp sle <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -713,6 +739,7 @@ ; CHECK-LABEL: compare_ule_v2i64: ; 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) { %res = icmp ule <2 x i64> %x, %y ret <2 x i1> %res @@ -720,6 +747,7 @@ ; CHECK-LABEL: compare_sext_ule_v2i64: ; 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) { %cmp = icmp ule <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -727,14 +755,20 @@ } ; CHECK-LABEL: compare_sgt_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %res = icmp sgt <2 x i64> %x, %y ret <2 x i1> %res } ; CHECK-LABEL: compare_sext_sgt_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %cmp = icmp sgt <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -743,6 +777,7 @@ ; CHECK-LABEL: compare_ugt_v2i64: ; 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) { %res = icmp ugt <2 x i64> %x, %y ret <2 x i1> %res @@ -750,6 +785,7 @@ ; CHECK-LABEL: compare_sext_ugt_v2i64: ; 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) { %cmp = icmp ugt <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -757,14 +793,20 @@ } ; CHECK-LABEL: compare_sge_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %res = icmp sge <2 x i64> %x, %y ret <2 x i1> %res } ; CHECK-LABEL: compare_sext_sge_v2i64: +; NO-SIMD128-NOT: i64x2 ; 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) { %cmp = icmp sge <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> @@ -773,6 +815,7 @@ ; CHECK-LABEL: compare_uge_v2i64: ; 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) { %res = icmp uge <2 x i64> %x, %y ret <2 x i1> %res @@ -780,6 +823,7 @@ ; CHECK-LABEL: compare_sext_uge_v2i64: ; 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) { %cmp = icmp uge <2 x i64> %x, %y %res = sext <2 x i1> %cmp to <2 x i64> diff --git a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll --- a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll @@ -553,16 +553,6 @@ ; ============================================================================== ; 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-NEXT: .functype extend_low_s_v2i64 (v128) -> (v128){{$}} ; CHECK-NEXT: i64x2.extend_low_i32x4_s $push[[R:[0-9]+]]=, $0{{$}} diff --git a/llvm/test/CodeGen/WebAssembly/simd-select.ll b/llvm/test/CodeGen/WebAssembly/simd-select.ll --- a/llvm/test/CodeGen/WebAssembly/simd-select.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-select.ll @@ -299,33 +299,17 @@ 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: .functype vselect_cmp_v2i64 (v128, v128, v128, v128) -> (v128) ; CHECK-NEXT: # %bb.0: ; CHECK-NEXT: local.get 2 ; CHECK-NEXT: local.get 3 -; CHECK-NEXT: i64.const -1 -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 0 -; CHECK-NEXT: i64x2.extract_lane 0 ; CHECK-NEXT: local.get 1 -; CHECK-NEXT: i64x2.extract_lane 0 -; 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: i64x2.lt_s ; CHECK-NEXT: v128.bitselect ; CHECK-NEXT: # fallthrough-return - <2 x i64> %x, <2 x i64> %y) { %c = icmp slt <2 x i64> %a, %b %res = select <2 x i1> %c, <2 x i64> %x, <2 x i64> %y ret <2 x i64> %res diff --git a/llvm/test/MC/WebAssembly/simd-encodings.s b/llvm/test/MC/WebAssembly/simd-encodings.s --- a/llvm/test/MC/WebAssembly/simd-encodings.s +++ b/llvm/test/MC/WebAssembly/simd-encodings.s @@ -653,17 +653,23 @@ # CHECK: i64x2.mul # encoding: [0xfd,0xd5,0x01] 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] i64x2.extmul_low_i32x4_s