/* Logical operators must have a result type of bool. */
return false;
- case EXP::lessOrEqual:
- case EXP::lessThan:
- case EXP::greaterOrEqual:
- case EXP::greaterThan:
- case EXP::equal:
- case EXP::notEqual:
case EXP::identity:
case EXP::notIdentity:
/* Comparison operators must have a result type of bool. */
case INTRINSIC_SHUFFLEVECTOR:
case INTRINSIC_CONVERTVECTOR:
case INTRINSIC_BLENDVECTOR:
- case INTRINSIC_EQUALMASK:
- case INTRINSIC_NOTEQUALMASK:
- case INTRINSIC_GREATERMASK:
- case INTRINSIC_GREATEREQUALMASK:
case INTRINSIC_VLOAD8:
case INTRINSIC_VLOAD16:
case INTRINSIC_VLOAD32:
return false;
}
-
- case INTRINSIC_EQUALMASK:
- case INTRINSIC_NOTEQUALMASK:
- case INTRINSIC_GREATERMASK:
- case INTRINSIC_GREATEREQUALMASK:
- {
- /* Expects the signature:
- vector(T) equalMask(vector(T), vector(T));
- vector(T) notEqualMask(vector(T), vector(T));
- vector(T) greaterMask(vector(T), vector(T));
- vector(T) greateOrEqualMask(vector(T), vector(T)); */
- gcc_assert (call_expr_nargs (callexp) == 2);
-
- tree vec0 = TREE_TYPE (CALL_EXPR_ARG (callexp, 0));
- tree vec1 = TREE_TYPE (CALL_EXPR_ARG (callexp, 1));
- if (!VECTOR_TYPE_P (TREE_TYPE (callexp))
- || !VECTOR_TYPE_P (vec0)
- || !VECTOR_TYPE_P (vec1)
- || TYPE_MAIN_VARIANT (vec0) != TYPE_MAIN_VARIANT (vec1))
- return warn_mismatched_return_type (callexp, "__vector(T)");
-
- return false;
- }
}
/* Generic mismatch warning if it hasn't already been handled. */
return modify_expr (result, value);
}
-/* Expand a front-end intrinsic call to a vector comparison intrinsic, which is
- either a call to equalMask(), notEqualMask(), greaterMask(), or
- greaterOrEqualMask(). These intrinsics take two arguments, the signature to
- which can be either:
-
- vector(T) equalMask(vector(T) vec0, vector(T) vec1);
- vector(T) notEqualMask(vector(T) vec0, vector(T) vec1);
- vector(T) greaterMask(vector(T) vec0, vector(T) vec1);
- vector(T) greaterOrEqualMask(vector(T) vec0, vector(T) vec1);
-
- This performs an element-wise comparison between two vectors VEC0 and VEC1,
- returning a vector with signed integral elements. */
-
-static tree
-expand_intrinsic_vec_cond (tree_code code, tree callexp)
-{
- tree vec0 = CALL_EXPR_ARG (callexp, 0);
- tree vec1 = CALL_EXPR_ARG (callexp, 1);
- tree type = TREE_TYPE (callexp);
-
- tree cmp = fold_build2_loc (EXPR_LOCATION (callexp), code,
- truth_type_for (type), vec0, vec1);
- return fold_build3_loc (EXPR_LOCATION (callexp), VEC_COND_EXPR, type, cmp,
- build_minus_one_cst (type), build_zero_cst (type));
-}
-
/* Expand a front-end instrinsic call to convertvector(). This takes one
argument, the signature to which is:
case INTRINSIC_BLENDVECTOR:
return expand_intrinsic_vec_blend (callexp);
- case INTRINSIC_EQUALMASK:
- return expand_intrinsic_vec_cond (EQ_EXPR, callexp);
-
- case INTRINSIC_NOTEQUALMASK:
- return expand_intrinsic_vec_cond (NE_EXPR, callexp);
-
- case INTRINSIC_GREATERMASK:
- return expand_intrinsic_vec_cond (GT_EXPR, callexp);
-
- case INTRINSIC_GREATEREQUALMASK:
- return expand_intrinsic_vec_cond (GE_EXPR, callexp);
-
default:
gcc_unreachable ();
}
"gcc.simd", "F@1TZ@1V")
DEF_D_BUILTIN (INTRINSIC_BLENDVECTOR, BUILT_IN_NONE, "blendvector", "gcc.simd",
"F@2V0@2V1@1MZ@2V0")
-DEF_D_BUILTIN (INTRINSIC_EQUALMASK, BUILT_IN_NONE, "equalMask", "gcc.simd",
- "F@1V@1VZ@1V")
-DEF_D_BUILTIN (INTRINSIC_NOTEQUALMASK, BUILT_IN_NONE, "notEqualMask",
- "gcc.simd", "F@1V@1VZ@1V")
-DEF_D_BUILTIN (INTRINSIC_GREATERMASK, BUILT_IN_NONE, "greaterMask", "gcc.simd",
- "F@1V@1VZ@1V")
-DEF_D_BUILTIN (INTRINSIC_GREATEREQUALMASK, BUILT_IN_NONE,
- "greaterOrEqualMask", "gcc.simd", "F@1V@1VZ@1V")
#undef DEF_D_BUILTIN
#undef DEF_CTFE_BUILTIN
blendvector!(byte16, byte16, byte16)(0, 0, 0);
}
-void test_comparison()
-{
- equalMask!int(0, 0); // { dg-warning "mismatch in return type" }
- equalMask!double(0, 0); // { dg-warning "mismatch in return type" }
- equalMask!int4(0, 0);
- equalMask!short8(0, 0);
- equalMask!float4(0, 0);
- equalMask!byte16(0, 0);
- equalMask!fake4(f, f); // { dg-warning "mismatch in return type" }
-
- notEqualMask!int(0, 0); // { dg-warning "mismatch in return type" }
- notEqualMask!double(0, 0); // { dg-warning "mismatch in return type" }
- notEqualMask!int4(0, 0);
- notEqualMask!short8(0, 0);
- notEqualMask!float4(0, 0);
- notEqualMask!byte16(0, 0);
- notEqualMask!fake4(f, f); // { dg-warning "mismatch in return type" }
-
- greaterMask!int(0, 0); // { dg-warning "mismatch in return type" }
- greaterMask!double(0, 0); // { dg-warning "mismatch in return type" }
- greaterMask!int4(0, 0);
- greaterMask!short8(0, 0);
- greaterMask!float4(0, 0);
- greaterMask!byte16(0, 0);
- greaterMask!fake4(f, f); // { dg-warning "mismatch in return type" }
-
- greaterOrEqualMask!int(0, 0); // { dg-warning "mismatch in return type" }
- greaterOrEqualMask!double(0, 0); // { dg-warning "mismatch in return type" }
- greaterOrEqualMask!int4(0, 0);
- greaterOrEqualMask!short8(0, 0);
- greaterOrEqualMask!float4(0, 0);
- greaterOrEqualMask!byte16(0, 0);
- greaterOrEqualMask!fake4(f, f); // { dg-warning "mismatch in return type" }
-}
-
// The following declarations of the simd intrinsics are without any guards
// to verify `d/intrinsics.cc` is doing checks to prevent invalid lowerings.
V loadUnaligned(V)(const V*);
V convertvector(V, T)(T);
V0 blendvector(V0, V1, M)(V0, V1, M);
-
-V equalMask(V)(V, V);
-V notEqualMask(V)(V, V);
-V greaterMask(V)(V, V);
-V greaterOrEqualMask(V)(V, V);
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
static assert(!__traits(compiles, v1 << 1));
static assert(!__traits(compiles, v1 >> 1));
static assert(!__traits(compiles, v1 >>> 1));
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
static assert(!__traits(compiles, v1 << 1));
static assert(!__traits(compiles, v1 >> 1));
static assert(!__traits(compiles, v1 >>> 1));
* assert(c.array == [0, 0, -1, -1]);
* ---
*/
-V equalMask(V)(V op1, V op2) if (isVectorType!V);
+V equalMask(V)(V op1, V op2) if (isVectorType!V)
+{
+ return op1 == op2;
+}
/// Ditto
-V notEqualMask(V)(V op1, V op2) if (isVectorType!V);
+V notEqualMask(V)(V op1, V op2) if (isVectorType!V)
+{
+ return op1 != op2;
+}
/// Ditto
-V greaterMask(V)(V op1, V op2) if (isVectorType!V);
+V greaterMask(V)(V op1, V op2) if (isVectorType!V)
+{
+ return op1 > op2;
+}
/// Ditto
-V greaterOrEqualMask(V)(V op1, V op2) if (isVectorType!V);
+V greaterOrEqualMask(V)(V op1, V op2) if (isVectorType!V)
+{
+ return op1 >= op2;
+}
/**
* Perform an element-wise logical comparison between two vectors, producing
*/
V notMask(V)(V op1) if (isVectorType!V)
{
- return equalMask(op1, 0);
+ return op1 == 0;
}
/// Ditto
V andAndMask(V)(V op1, V op2) if (isVectorType!V)
{
- return notEqualMask(op1, 0) & notEqualMask(op2, 0);
+ return (op1 != 0) & (op2 != 0);
}
/// Ditto
V orOrMask(V)(V op1, V op2) if (isVectorType!V)
{
- return notEqualMask(op1, 0) | notEqualMask(op2, 0);
+ return (op1 != 0) | (op2 != 0);
}
// Private helper templates.