[clang] 4431d64 - Support ExtVectorType conditional operator

Min-Yih Hsu via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 2 09:36:09 PDT 2020


Author: Min-Yih Hsu
Date: 2020-06-02T16:35:42Z
New Revision: 4431d64c10cb681986e752420f1136f259daa5a7

URL: https://github.com/llvm/llvm-project/commit/4431d64c10cb681986e752420f1136f259daa5a7
DIFF: https://github.com/llvm/llvm-project/commit/4431d64c10cb681986e752420f1136f259daa5a7.diff

LOG: Support ExtVectorType conditional operator

Extension vectors now can be used in element-wise conditional selector.
For example:
```
R[i] = C[i]? A[i] : B[i]
```
This feature was previously only enabled in OpenCL C. Now it's also
available in C. Not that it has different behaviors than GNU vectors
(i.e. __vector_size__). Extension vectors selects on signdness of the
vector. GNU vectors on the other hand do normal bool conversions. Also,
this feature is not available in C++.

Differential Revision: https://reviews.llvm.org/D80574

Added: 
    

Modified: 
    clang/docs/LanguageExtensions.rst
    clang/lib/CodeGen/CGExprScalar.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/test/Sema/ext_vector_comparisons.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 2fbf5ea5eb01..d3d73bf238f9 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -478,7 +478,7 @@ bitwise operators &,|,^,~        yes     yes       yes         --
 !, &&, ||                        yes     --        yes [#]_    --
 ==, !=, >, <, >=, <=             yes     yes       yes         --
 =                                yes     yes       yes         yes
-:? [#]_                          yes     --        yes         --
+?: [#]_                          yes     --        yes         --
 sizeof                           yes     yes       yes         yes
 C-style cast                     yes     yes       yes         no
 reinterpret_cast                 yes     no        yes         no
@@ -489,9 +489,11 @@ const_cast                       no      no        no          no
 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 
diff erently. OpenCL selects based on signedness of
-  the condition operands, but GCC vectors use normal bool conversions (that is, != 0).
+.. [#] ternary operator(?:) has 
diff erent 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).
+  If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
+  And it selects base on signedness of the condition operands (OpenCL v1.1 s6.3.9).
 
 Matrix Types
 ============

diff  --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 028a2cf49c4d..b169462f535a 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4432,8 +4432,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
 
   // OpenCL: If the condition is a vector, we can treat this condition like
   // the select function.
-  if (CGF.getLangOpts().OpenCL
-      && condExpr->getType()->isVectorType()) {
+  if ((CGF.getLangOpts().OpenCL && condExpr->getType()->isVectorType()) ||
+      condExpr->getType()->isExtVectorType()) {
     CGF.incrementProfileCounter(E);
 
     llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2221f98b943a..5e8b1d8a37cc 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8078,7 +8078,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
 
   // The OpenCL operator with a vector condition is sufficiently
   // 
diff erent to merit its own checker.
-  if (getLangOpts().OpenCL && Cond.get()->getType()->isVectorType())
+  if ((getLangOpts().OpenCL && Cond.get()->getType()->isVectorType()) ||
+      Cond.get()->getType()->isExtVectorType())
     return OpenCLCheckVectorConditional(*this, Cond, LHS, RHS, QuestionLoc);
 
   // First, check the condition.

diff  --git a/clang/test/Sema/ext_vector_comparisons.c b/clang/test/Sema/ext_vector_comparisons.c
index 4c632a412f44..f1c292ff4a4d 100644
--- a/clang/test/Sema/ext_vector_comparisons.c
+++ b/clang/test/Sema/ext_vector_comparisons.c
@@ -28,3 +28,19 @@ static int4 test2() {
   return vec > vec;  // no-warning
   return vec >= vec; // no-warning
 }
+
+static int4 test3() {
+  int4 i0, i1;
+
+  return i0 > i1 ? i0 : i1; // no-error
+  return i0 ? i0 : i1;      // no-error
+}
+
+static float4 test4() {
+  float4 f0, f1;
+
+  // This would actually generate implicit casting warning
+  // under Weverything flag but we don't really care here
+  return f0 > f1 ? f0 : f1; // no-error
+  return f0 ? f0 : f1;      // expected-error {{used type 'float4' (vector of 4 'float' values) where floating point type is not allowed}}
+}


        


More information about the cfe-commits mailing list