myhsu updated this revision to Diff 267024.
myhsu added a comment.

Fix document section


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80574/new/

https://reviews.llvm.org/D80574

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

Index: clang/test/Sema/ext_vector_comparisons.c
===================================================================
--- clang/test/Sema/ext_vector_comparisons.c
+++ clang/test/Sema/ext_vector_comparisons.c
@@ -28,3 +28,19 @@
   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 {{arithmetic or pointer type is required}}
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -7480,6 +7480,13 @@
   // C99 6.5.15p2
   if (CondTy->isScalarType()) return false;
 
+  // Only ext vector is allowed
+  if (const auto *VecCondTy = Cond->getType()->getAs<ExtVectorType>()) {
+    QualType EleTy = VecCondTy->getElementType();
+    if (EleTy->isIntegerType())
+      return false;
+  }
+
   S.Diag(QuestionLoc, diag::err_typecheck_cond_expect_scalar)
     << CondTy << Cond->getSourceRange();
   return true;
@@ -7958,10 +7965,21 @@
 
   // Now check the two expressions.
   if (LHS.get()->getType()->isVectorType() ||
-      RHS.get()->getType()->isVectorType())
-    return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false,
-                               /*AllowBothBool*/true,
-                               /*AllowBoolConversions*/false);
+      RHS.get()->getType()->isVectorType()) {
+    QualType VecResTy = CheckVectorOperands(LHS, RHS, QuestionLoc,
+                                            /*isCompAssign*/ false,
+                                            /*AllowBothBool*/ true,
+                                            /*AllowBoolConversions*/ false);
+    // If the condition is ext vector, we're imposing OpenCL's rule wrt
+    // condition and result type.
+    QualType CondTy = Cond.get()->getType();
+    if (CondTy->isExtVectorType()) {
+      if (VecResTy.isNull() ||
+          checkVectorResult(*this, CondTy, VecResTy, QuestionLoc))
+        return QualType();
+    }
+    return VecResTy;
+  }
 
   QualType ResTy =
       UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional);
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -4431,8 +4431,8 @@
 
   // 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);
Index: clang/docs/LanguageExtensions.rst
===================================================================
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -478,7 +478,7 @@
 !, &&, ||                        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 @@
 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).
+.. [#] 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).
+  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.
 
 Matrix Types
 ============
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to