mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 22:30:13 +00:00
Reland D80979 [clang] Implement VectorType logic not operator
With a fix to use -triple %itanium_abi_triple Differential Revision: https://reviews.llvm.org/D80979
This commit is contained in:
parent
9982d48a92
commit
fc935fc35b
@ -475,7 +475,7 @@ unary operators +, -- yes yes yes --
|
||||
+,--,*,/,% yes yes yes --
|
||||
bitwise operators &,|,^,~ yes yes yes --
|
||||
>>,<< yes yes yes --
|
||||
!, &&, || yes -- yes [#]_ --
|
||||
!, &&, || yes -- yes --
|
||||
==, !=, >, <, >=, <= yes yes yes --
|
||||
= yes yes yes yes
|
||||
?: [#]_ yes -- yes --
|
||||
@ -488,7 +488,6 @@ const_cast no no no no
|
||||
|
||||
See also :ref:`langext-__builtin_shufflevector`, :ref:`langext-__builtin_convertvector`.
|
||||
|
||||
.. [#] unary operator ! is not implemented, however && and || are.
|
||||
.. [#] ternary operator(?:) has different behaviors depending on condition
|
||||
operand's vector type. If the condition is a GNU vector (i.e. __vector_size__),
|
||||
it's only available in C++ and uses normal bool conversions (that is, != 0).
|
||||
|
@ -2762,7 +2762,9 @@ Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
|
||||
|
||||
Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
|
||||
// Perform vector logical not on comparison with zero vector.
|
||||
if (E->getType()->isExtVectorType()) {
|
||||
if (E->getType()->isVectorType() &&
|
||||
E->getType()->castAs<VectorType>()->getVectorKind() ==
|
||||
VectorType::GenericVector) {
|
||||
Value *Oper = Visit(E->getSubExpr());
|
||||
Value *Zero = llvm::Constant::getNullValue(Oper->getType());
|
||||
Value *Result;
|
||||
|
@ -14481,12 +14481,19 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
|
||||
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
|
||||
<< resultType << Input.get()->getSourceRange());
|
||||
}
|
||||
// Vector logical not returns the signed variant of the operand type.
|
||||
resultType = GetSignedVectorType(resultType);
|
||||
break;
|
||||
} else if (Context.getLangOpts().CPlusPlus && resultType->isVectorType()) {
|
||||
const VectorType *VTy = resultType->castAs<VectorType>();
|
||||
if (VTy->getVectorKind() != VectorType::GenericVector)
|
||||
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
|
||||
<< resultType << Input.get()->getSourceRange());
|
||||
|
||||
// Vector logical not returns the signed variant of the operand type.
|
||||
resultType = GetSignedVectorType(resultType);
|
||||
break;
|
||||
} else {
|
||||
// FIXME: GCC's vector extension permits the usage of '!' with a vector
|
||||
// type in C++. We should allow that here too.
|
||||
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
|
||||
<< resultType << Input.get()->getSourceRange());
|
||||
}
|
||||
|
21
clang/test/CodeGen/vector.cpp
Normal file
21
clang/test/CodeGen/vector.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
typedef __attribute__((__vector_size__(16))) float float4;
|
||||
typedef __attribute__((__vector_size__(16))) int int4;
|
||||
typedef __attribute__((__vector_size__(16))) unsigned int uint4;
|
||||
|
||||
// CHECK: @_Z5test1Dv4_j
|
||||
int4 test1(uint4 V0) {
|
||||
// CHECK: [[CMP0:%.*]] = icmp eq <4 x i32> [[V0:%.*]], zeroinitializer
|
||||
// CHECK-NEXT: [[V1:%.*]] = sext <4 x i1> [[CMP0]] to <4 x i32>
|
||||
int4 V = !V0;
|
||||
return V;
|
||||
}
|
||||
|
||||
// CHECK: @_Z5test2Dv4_fS_
|
||||
int4 test2(float4 V0, float4 V1) {
|
||||
// CHECK: [[CMP0:%.*]] = fcmp oeq <4 x float> [[V0:%.*]], zeroinitializer
|
||||
// CHECK-NEXT: [[V1:%.*]] = sext <4 x i1> [[CMP0]] to <4 x i32>
|
||||
int4 V = !V0;
|
||||
return V;
|
||||
}
|
@ -83,7 +83,7 @@ void logicTest(void) {
|
||||
v2i64 v2i64_c = (v2i64){3, 1}; // expected-warning {{compound literals are a C99-specific feature}}
|
||||
v2i64 v2i64_r;
|
||||
|
||||
v2i64_r = !v2i64_a; // expected-error {{invalid argument type 'v2i64' (vector of 2 'long long' values) to unary expression}}
|
||||
v2i64_r = !v2i64_a;
|
||||
v2i64_r = ~v2i64_a;
|
||||
|
||||
v2i64_r = v2i64_a ? v2i64_b : v2i64_c;
|
||||
|
Loading…
Reference in New Issue
Block a user