[PATCH] D80979: [clang] Implement VectorType logic not operator.

JunMa via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 1 22:45:25 PDT 2020


junparser created this revision.
junparser added reviewers: erichkeane, aaron.ballman, rjmccall.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

As title. This patch implement unary operator ! of vector type.

TestPlan: check-clang


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D80979

Files:
  clang/docs/LanguageExtensions.rst
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/vector.c
  clang/test/Sema/vector-gcc-compat.cpp


Index: clang/test/Sema/vector-gcc-compat.cpp
===================================================================
--- clang/test/Sema/vector-gcc-compat.cpp
+++ clang/test/Sema/vector-gcc-compat.cpp
@@ -83,7 +83,7 @@
   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;
Index: clang/test/CodeGen/vector.c
===================================================================
--- clang/test/CodeGen/vector.c
+++ clang/test/CodeGen/vector.c
@@ -80,3 +80,19 @@
 
 // CHECK: define void @lax_vector_compare2(<2 x i32>* {{.*sret.*}}, i64 {{.*}}, i64 {{.*}})
 // CHECK: icmp eq <2 x i32>
+
+vec_int1 lax_vector_logic_not1(int x, vec_int1 y) {
+  y = x != y;
+  return y;
+}
+
+// CHECK: define i32 @lax_vector_logic_not1(i32 {{.*}}, i32 {{.*}})
+// CHECK: icmp ne i32
+
+vec_int2 lax_vector_logic_not2(long long x, vec_int2 y) {
+  y = x != y;
+  return y;
+}
+
+// CHECK: define void @lax_vector_logic_not2(<2 x i32>* {{.*sret.*}}, i64 {{.*}}, i64 {{.*}})
+// CHECK: icmp ne <2 x i32>
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14436,12 +14436,19 @@
           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());
     }
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -2742,7 +2742,9 @@
 
 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;
Index: clang/docs/LanguageExtensions.rst
===================================================================
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -475,7 +475,7 @@
 +,--,*,/,%                       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 @@
 
 See also :ref:`langext-__builtin_shufflevector`, :ref:`langext-__builtin_convertvector`.
 
-.. [#] unary operator ! is not implemented, however && and || are.
 .. [#] While OpenCL and GCC vectors both implement the comparison operator(?:) as a
   'select', they operate somewhat differently. OpenCL selects based on signedness of
   the condition operands, but GCC vectors use normal bool conversions (that is, != 0).


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80979.267788.patch
Type: text/x-patch
Size: 4386 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200602/8d3adab8/attachment.bin>


More information about the cfe-commits mailing list