Index: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -87,7 +87,7 @@ setOperationAction(ISD::VACOPY, MVT::Other, Expand); setOperationAction(ISD::VAEND, MVT::Other, Expand); - for (auto T : {MVT::f32, MVT::f64}) { + for (auto T : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) { // Don't expand the floating-point types to constant pools. setOperationAction(ISD::ConstantFP, T, Legal); // Expand floating-point comparisons. Index: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td =================================================================== --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -145,6 +145,27 @@ )], "v128.not\t$dst, $vec", "v128.not", 62>; } +multiclass SIMDCondition simdop> { + defm _#vec_t : + SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128: $rhs), (outs), (ins), + [(set (out_t V128:$dst), + (setcc (vec_t V128:$lhs), (vec_t V128:$rhs), cond))], + vec#"."#name#"\t$dst, $lhs, $rhs", vec#"."#name, simdop>; +} +multiclass SIMDConditionInt baseInst, + int step = 1> { + defm "" : SIMDCondition; + defm "" : SIMDCondition; + defm "" : SIMDCondition; +} +multiclass SIMDConditionFP baseInst> { + defm "" : SIMDCondition; + defm "" : SIMDCondition; +} let Defs = [ARGUMENTS] in { defm "" : ConstVec; defm "" : SIMDNot; +let isCommutable = 1 in { +defm EQ : SIMDConditionInt<"eq", SETEQ, 72>; +defm EQ : SIMDConditionFP<"eq", SETOEQ, 75>; +defm NE : SIMDConditionInt<"ne", SETNE, 77>; +defm NE : SIMDConditionFP<"ne", SETUNE, 80>; +} // isCommutable = 1 + +defm LT_S : SIMDConditionInt<"lt_s", SETLT, 82, 2>; +defm LT_U : SIMDConditionInt<"lt_u", SETULT, 83, 2>; +defm LT : SIMDConditionFP<"lt", SETOLT, 88>; +defm LE_S : SIMDConditionInt<"le_s", SETLE, 90, 2>; +defm LE_U : SIMDConditionInt<"le_u", SETULE, 91, 2>; +defm LE : SIMDConditionFP<"le", SETOLE, 96>; +defm GT_S : SIMDConditionInt<"gt_s", SETGT, 98, 2>; +defm GT_U : SIMDConditionInt<"gt_u", SETUGT, 99, 2>; +defm GT : SIMDConditionFP<"gt", SETOGT, 104>; +defm GE_S : SIMDConditionInt<"ge_s", SETGE, 106, 2>; +defm GE_U : SIMDConditionInt<"ge_u", SETUGE, 107, 2>; +defm GE : SIMDConditionFP<"ge", SETOGE, 112>; + } // Defs = [ARGUMENTS] // Def load and store patterns from WebAssemblyInstrMemory.td for vector types @@ -295,6 +336,19 @@ } +// Lower float comparisons that don't care about NaN to standard +// WebAssembly float comparisons. These instructions are generated in +// the target-independent expansion of unordered comparisons and +// ordered ne. +def : Pat<(v4i32 (seteq (v4f32 V128:$lhs), (v4f32 V128:$rhs))), + (v4i32 (EQ_v4f32 (v4f32 V128:$lhs), (v4f32 V128:$rhs)))>; +def : Pat<(v4i32 (setne (v4f32 V128:$lhs), (v4f32 V128:$rhs))), + (v4i32 (NE_v4f32 (v4f32 V128:$lhs), (v4f32 V128:$rhs)))>; +def : Pat<(v2i64 (seteq (v2f64 V128:$lhs), (v2f64 V128:$rhs))), + (v2i64 (EQ_v2f64 (v2f64 V128:$lhs), (v2f64 V128:$rhs)))>; +def : Pat<(v2i64 (setne (v2f64 V128:$lhs), (v2f64 V128:$rhs))), + (v2i64 (NE_v2f64 (v2f64 V128:$lhs), (v2f64 V128:$rhs)))>; + // follow convention of making implicit expansions unsigned def : Pat<(i32 (vector_extract (v16i8 V128:$vec), (i32 LaneIdx16:$idx))), (EXTRACT_LANE_v16i8_u V128:$vec, (i32 LaneIdx16:$idx))>; Index: llvm/trunk/test/CodeGen/WebAssembly/simd-comparisons.ll =================================================================== --- llvm/trunk/test/CodeGen/WebAssembly/simd-comparisons.ll +++ llvm/trunk/test/CodeGen/WebAssembly/simd-comparisons.ll @@ -0,0 +1,644 @@ +; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-disable-explicit-locals -wasm-enable-unimplemented-simd -mattr=+simd128,+sign-ext --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128 +; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-disable-explicit-locals -mattr=+simd128,+sign-ext --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128-VM +; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-disable-explicit-locals -mattr=-simd128,+sign-ext --show-mc-encoding | FileCheck %s --check-prefixes CHECK,NO-SIMD128 + +; Test SIMD comparison operators + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +; CHECK-LABEL: compare_eq_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.eq $push0=, $0, $1 # encoding: [0xfd,0x48]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_eq_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp eq <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_ne_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.ne $push0=, $0, $1 # encoding: [0xfd,0x4d]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_ne_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp ne <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_slt_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.lt_s $push0=, $0, $1 # encoding: [0xfd,0x52]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_slt_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp slt <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_ult_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.lt_u $push0=, $0, $1 # encoding: [0xfd,0x53]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_ult_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp ult <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_sle_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.le_s $push0=, $0, $1 # encoding: [0xfd,0x5a]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_sle_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp sle <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_ule_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.le_u $push0=, $0, $1 # encoding: [0xfd,0x5b]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_ule_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp ule <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_sgt_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.gt_s $push0=, $0, $1 # encoding: [0xfd,0x62]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_sgt_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp sgt <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_ugt_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.gt_u $push0=, $0, $1 # encoding: [0xfd,0x63]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_ugt_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp ugt <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_sge_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.ge_s $push0=, $0, $1 # encoding: [0xfd,0x6a]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_sge_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp sge <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_uge_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.ge_u $push0=, $0, $1 # encoding: [0xfd,0x6b]{{$}} +; SIMD128: return $pop0 # +define <16 x i1> @compare_uge_v16i8 (<16 x i8> %x, <16 x i8> %y) { + %res = icmp uge <16 x i8> %x, %y + ret <16 x i1> %res +} + +; CHECK-LABEL: compare_eq_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.eq $push0=, $0, $1 # encoding: [0xfd,0x49]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_eq_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp eq <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_ne_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.ne $push0=, $0, $1 # encoding: [0xfd,0x4e]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_ne_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp ne <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_slt_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.lt_s $push0=, $0, $1 # encoding: [0xfd,0x54]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_slt_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp slt <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_ult_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.lt_u $push0=, $0, $1 # encoding: [0xfd,0x55]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_ult_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp ult <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_sle_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.le_s $push0=, $0, $1 # encoding: [0xfd,0x5c]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_sle_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp sle <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_ule_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.le_u $push0=, $0, $1 # encoding: [0xfd,0x5d]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_ule_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp ule <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_sgt_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.gt_s $push0=, $0, $1 # encoding: [0xfd,0x64]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_sgt_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp sgt <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_ugt_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.gt_u $push0=, $0, $1 # encoding: [0xfd,0x65]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_ugt_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp ugt <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_sge_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.ge_s $push0=, $0, $1 # encoding: [0xfd,0x6c]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_sge_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp sge <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_uge_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.ge_u $push0=, $0, $1 # encoding: [0xfd,0x6d]{{$}} +; SIMD128: return $pop0 # +define <8 x i1> @compare_uge_v8i16 (<8 x i16> %x, <8 x i16> %y) { + %res = icmp uge <8 x i16> %x, %y + ret <8 x i1> %res +} + +; CHECK-LABEL: compare_eq_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.eq $push0=, $0, $1 # encoding: [0xfd,0x4a]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_eq_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp eq <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ne_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.ne $push0=, $0, $1 # encoding: [0xfd,0x4f]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_ne_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp ne <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_slt_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.lt_s $push0=, $0, $1 # encoding: [0xfd,0x56]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_slt_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp slt <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ult_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.lt_u $push0=, $0, $1 # encoding: [0xfd,0x57]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_ult_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp ult <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_sle_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.le_s $push0=, $0, $1 # encoding: [0xfd,0x5e]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_sle_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp sle <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ule_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.le_u $push0=, $0, $1 # encoding: [0xfd,0x5f]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_ule_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp ule <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_sgt_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.gt_s $push0=, $0, $1 # encoding: [0xfd,0x66]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_sgt_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp sgt <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ugt_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.gt_u $push0=, $0, $1 # encoding: [0xfd,0x67]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_ugt_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp ugt <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_sge_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.ge_s $push0=, $0, $1 # encoding: [0xfd,0x6e]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_sge_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp sge <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_uge_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.ge_u $push0=, $0, $1 # encoding: [0xfd,0x6f]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_uge_v4i32 (<4 x i32> %x, <4 x i32> %y) { + %res = icmp uge <4 x i32> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_oeq_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.eq $push0=, $0, $1 # encoding: [0xfd,0x4b]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_oeq_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp oeq <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ogt_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.gt $push0=, $0, $1 # encoding: [0xfd,0x68]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_ogt_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp ogt <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_oge_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.ge $push0=, $0, $1 # encoding: [0xfd,0x70]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_oge_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp oge <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_olt_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.lt $push0=, $0, $1 # encoding: [0xfd,0x58]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_olt_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp olt <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ole_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.le $push0=, $0, $1 # encoding: [0xfd,0x60]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_ole_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp ole <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_one_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.ne +define <4 x i1> @compare_one_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp one <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ord_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.eq +define <4 x i1> @compare_ord_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp ord <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ueq_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.eq +define <4 x i1> @compare_ueq_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp ueq <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ugt_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.le +define <4 x i1> @compare_ugt_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp ugt <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_uge_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.lt +define <4 x i1> @compare_uge_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp uge <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ult_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.ge +define <4 x i1> @compare_ult_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp ult <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_ule_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.gt +define <4 x i1> @compare_ule_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp ule <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_une_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.ne $push0=, $0, $1 # encoding: [0xfd,0x50]{{$}} +; SIMD128: return $pop0 # +define <4 x i1> @compare_une_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp une <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_uno_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.ne +define <4 x i1> @compare_uno_v4f32 (<4 x float> %x, <4 x float> %y) { + %res = fcmp uno <4 x float> %x, %y + ret <4 x i1> %res +} + +; CHECK-LABEL: compare_oeq_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.eq $push0=, $0, $1 # encoding: [0xfd,0x4c]{{$}} +; SIMD128: return $pop0 # +define <2 x i1> @compare_oeq_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp oeq <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_ogt_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.gt $push0=, $0, $1 # encoding: [0xfd,0x69]{{$}} +; SIMD128: return $pop0 # +define <2 x i1> @compare_ogt_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp ogt <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_oge_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.ge $push0=, $0, $1 # encoding: [0xfd,0x71]{{$}} +; SIMD128: return $pop0 # +define <2 x i1> @compare_oge_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp oge <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_olt_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.lt $push0=, $0, $1 # encoding: [0xfd,0x59]{{$}} +; SIMD128: return $pop0 # +define <2 x i1> @compare_olt_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp olt <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_ole_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.le $push0=, $0, $1 # encoding: [0xfd,0x61]{{$}} +; SIMD128: return $pop0 # +define <2 x i1> @compare_ole_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp ole <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_one_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.ne +define <2 x i1> @compare_one_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp one <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_ord_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.eq +define <2 x i1> @compare_ord_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp ord <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_ueq_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.eq +define <2 x i1> @compare_ueq_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp ueq <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_ugt_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.le +define <2 x i1> @compare_ugt_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp ugt <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_uge_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.lt +define <2 x i1> @compare_uge_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp uge <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_ult_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.ge +define <2 x i1> @compare_ult_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp ult <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_ule_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.gt +define <2 x i1> @compare_ule_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp ule <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_une_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.ne $push0=, $0, $1 # encoding: [0xfd,0x51]{{$}} +; SIMD128: return $pop0 # +define <2 x i1> @compare_une_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp une <2 x double> %x, %y + ret <2 x i1> %res +} + +; CHECK-LABEL: compare_uno_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.ne +define <2 x i1> @compare_uno_v2f64 (<2 x double> %x, <2 x double> %y) { + %res = fcmp uno <2 x double> %x, %y + ret <2 x i1> %res +}