r348083 - OpenCL: Extend argument promotion rules to vector types

Matt Arsenault via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 1 13:56:11 PST 2018


Author: arsenm
Date: Sat Dec  1 13:56:10 2018
New Revision: 348083

URL: http://llvm.org/viewvc/llvm-project?rev=348083&view=rev
Log:
OpenCL: Extend argument promotion rules to vector types

The spec is ambiguous on whether vector types are allowed to be
implicitly converted. The only legal context I think this can
be used for OpenCL is printf, where it seems necessary.

Added:
    cfe/trunk/test/CodeGenOpenCL/printf.cl
Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=348083&r1=348082&r2=348083&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Dec  1 13:56:10 2018
@@ -730,20 +730,33 @@ ExprResult Sema::DefaultArgumentPromotio
     return ExprError();
   E = Res.get();
 
+  QualType ScalarTy = Ty;
+  unsigned NumElts = 0;
+  if (const ExtVectorType *VecTy = Ty->getAs<ExtVectorType>()) {
+    NumElts = VecTy->getNumElements();
+    ScalarTy = VecTy->getElementType();
+  }
+
   // If this is a 'float'  or '__fp16' (CVR qualified or typedef)
   // promote to double.
   // Note that default argument promotion applies only to float (and
   // half/fp16); it does not apply to _Float16.
-  const BuiltinType *BTy = Ty->getAs<BuiltinType>();
+  const BuiltinType *BTy = ScalarTy->getAs<BuiltinType>();
   if (BTy && (BTy->getKind() == BuiltinType::Half ||
               BTy->getKind() == BuiltinType::Float)) {
     if (getLangOpts().OpenCL &&
         !getOpenCLOptions().isEnabled("cl_khr_fp64")) {
-        if (BTy->getKind() == BuiltinType::Half) {
-            E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get();
-        }
+      if (BTy->getKind() == BuiltinType::Half) {
+        QualType Ty = Context.FloatTy;
+        if (NumElts != 0)
+          Ty = Context.getExtVectorType(Ty, NumElts);
+        E = ImpCastExprToType(E, Ty, CK_FloatingCast).get();
+      }
     } else {
-      E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
+      QualType Ty = Context.DoubleTy;
+      if (NumElts != 0)
+        Ty = Context.getExtVectorType(Ty, NumElts);
+      E = ImpCastExprToType(E, Ty, CK_FloatingCast).get();
     }
   }
 

Added: cfe/trunk/test/CodeGenOpenCL/printf.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/printf.cl?rev=348083&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/printf.cl (added)
+++ cfe/trunk/test/CodeGenOpenCL/printf.cl Sat Dec  1 13:56:10 2018
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=-+cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=FP64,ALL %s
+// RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=-cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=NOFP64,ALL %s
+
+typedef __attribute__((ext_vector_type(2))) float float2;
+typedef __attribute__((ext_vector_type(2))) half half2;
+
+#ifdef cl_khr_fp64
+typedef __attribute__((ext_vector_type(2))) double double2;
+#endif
+
+int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2)));
+
+
+// ALL-LABEL: @test_printf_float2(
+// FP64: %conv = fpext <2 x float> %0 to <2 x double>
+// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %conv)
+
+// NOFP64:  call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0)
+kernel void test_printf_float2(float2 arg) {
+  printf("%v2f", arg);
+}
+
+// ALL-LABEL: @test_printf_half2(
+// FP64: %conv = fpext <2 x half> %0 to <2 x double>
+// FP64:  %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %conv) #2
+
+// NOFP64: %conv = fpext <2 x half> %0 to <2 x float>
+// NOFP64:  %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %conv) #2
+kernel void test_printf_half2(half2 arg) {
+  printf("%v2f", arg);
+}
+
+#ifdef cl_khr_fp64
+// FP64-LABEL: @test_printf_double2(
+// FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %0) #2
+kernel void test_printf_double2(double2 arg) {
+  printf("%v2f", arg);
+}
+#endif




More information about the cfe-commits mailing list