r175734 - Add support to Sema and CodeGen for floating point vector types in OpenCL.
Joey Gouly
joey.gouly at arm.com
Thu Feb 21 03:49:56 PST 2013
Author: joey
Date: Thu Feb 21 05:49:56 2013
New Revision: 175734
URL: http://llvm.org/viewvc/llvm-project?rev=175734&view=rev
Log:
Add support to Sema and CodeGen for floating point vector types in OpenCL.
Added:
cfe/trunk/test/CodeGenOpenCL/logical-ops.cl
cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.1.cl
cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.2.cl
Modified:
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=175734&r1=175733&r2=175734&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Feb 21 05:49:56 2013
@@ -1636,12 +1636,15 @@ Value *ScalarExprEmitter::VisitUnaryNot(
}
Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
-
// Perform vector logical not on comparison with zero vector.
if (E->getType()->isExtVectorType()) {
Value *Oper = Visit(E->getSubExpr());
Value *Zero = llvm::Constant::getNullValue(Oper->getType());
- Value *Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");
+ Value *Result;
+ if (Oper->getType()->isFPOrFPVectorTy())
+ Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp");
+ else
+ Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");
return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
}
@@ -2668,16 +2671,20 @@ Value *ScalarExprEmitter::VisitBinAssign
}
Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
-
// Perform vector logical and on comparisons with zero vectors.
if (E->getType()->isVectorType()) {
Value *LHS = Visit(E->getLHS());
Value *RHS = Visit(E->getRHS());
Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
- LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
- RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
+ if (LHS->getType()->isFPOrFPVectorTy()) {
+ LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
+ RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
+ } else {
+ LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
+ RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
+ }
Value *And = Builder.CreateAnd(LHS, RHS);
- return Builder.CreateSExt(And, Zero->getType(), "sext");
+ return Builder.CreateSExt(And, ConvertType(E->getType()), "sext");
}
llvm::Type *ResTy = ConvertType(E->getType());
@@ -2735,16 +2742,20 @@ Value *ScalarExprEmitter::VisitBinLAnd(c
}
Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
-
// Perform vector logical or on comparisons with zero vectors.
if (E->getType()->isVectorType()) {
Value *LHS = Visit(E->getLHS());
Value *RHS = Visit(E->getRHS());
Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
- LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
- RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
+ if (LHS->getType()->isFPOrFPVectorTy()) {
+ LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
+ RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
+ } else {
+ LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
+ RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
+ }
Value *Or = Builder.CreateOr(LHS, RHS);
- return Builder.CreateSExt(Or, Zero->getType(), "sext");
+ return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext");
}
llvm::Type *ResTy = ConvertType(E->getType());
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=175734&r1=175733&r2=175734&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb 21 05:49:56 2013
@@ -7446,7 +7446,10 @@ QualType Sema::CheckVectorLogicalOperand
// Ensure that either both operands are of the same vector type, or
// one operand is of a vector type and the other is of its element type.
QualType vType = CheckVectorOperands(LHS, RHS, Loc, false);
- if (vType.isNull() || vType->isFloatingType())
+ if (vType.isNull())
+ return InvalidOperands(Loc, LHS, RHS);
+ if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 &&
+ vType->hasFloatingRepresentation())
return InvalidOperands(Loc, LHS, RHS);
return GetSignedVectorType(LHS.get()->getType());
@@ -7522,8 +7525,17 @@ inline QualType Sema::CheckLogicalOperan
RHS.get()->getLocEnd()));
}
}
-
+
if (!Context.getLangOpts().CPlusPlus) {
+ // OpenCL v1.1 s6.3.g: The logical operators and (&&), or (||) do
+ // not operate on the built-in scalar and vector float types.
+ if (Context.getLangOpts().OpenCL &&
+ Context.getLangOpts().OpenCLVersion < 120) {
+ if (LHS.get()->getType()->isFloatingType() ||
+ RHS.get()->getType()->isFloatingType())
+ return InvalidOperands(Loc, LHS, RHS);
+ }
+
LHS = UsualUnaryConversions(LHS.take());
if (LHS.isInvalid())
return QualType();
@@ -8849,7 +8861,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(So
case UO_Not: // bitwise complement
Input = UsualUnaryConversions(Input.take());
- if (Input.isInvalid()) return ExprError();
+ if (Input.isInvalid())
+ return ExprError();
resultType = Input.get()->getType();
if (resultType->isDependentType())
break;
@@ -8857,12 +8870,22 @@ ExprResult Sema::CreateBuiltinUnaryOp(So
if (resultType->isComplexType() || resultType->isComplexIntegerType())
// C99 does not support '~' for complex conjugation.
Diag(OpLoc, diag::ext_integer_complement_complex)
- << resultType << Input.get()->getSourceRange();
+ << resultType << Input.get()->getSourceRange();
else if (resultType->hasIntegerRepresentation())
break;
- else {
+ else if (resultType->isExtVectorType()) {
+ if (Context.getLangOpts().OpenCL) {
+ // OpenCL v1.1 s6.3.f: The bitwise operator not (~) does not operate
+ // on vector float types.
+ QualType T = resultType->getAs<ExtVectorType>()->getElementType();
+ if (!T->isIntegerType())
+ return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+ << resultType << Input.get()->getSourceRange());
+ }
+ break;
+ } else {
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
- << resultType << Input.get()->getSourceRange());
+ << resultType << Input.get()->getSourceRange());
}
break;
@@ -8887,8 +8910,24 @@ ExprResult Sema::CreateBuiltinUnaryOp(So
// operand contextually converted to bool.
Input = ImpCastExprToType(Input.take(), Context.BoolTy,
ScalarTypeToBooleanCastKind(resultType));
+ } else if (Context.getLangOpts().OpenCL &&
+ Context.getLangOpts().OpenCLVersion < 120) {
+ // OpenCL v1.1 6.3.h: The logical operator not (!) does not
+ // operate on scalar float types.
+ if (!resultType->isIntegerType())
+ return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+ << resultType << Input.get()->getSourceRange());
}
} else if (resultType->isExtVectorType()) {
+ if (Context.getLangOpts().OpenCL &&
+ Context.getLangOpts().OpenCLVersion < 120) {
+ // OpenCL v1.1 6.3.h: The logical operator not (!) does not
+ // operate on vector float types.
+ QualType T = resultType->getAs<ExtVectorType>()->getElementType();
+ if (!T->isIntegerType())
+ 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;
Added: cfe/trunk/test/CodeGenOpenCL/logical-ops.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/logical-ops.cl?rev=175734&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/logical-ops.cl (added)
+++ cfe/trunk/test/CodeGenOpenCL/logical-ops.cl Thu Feb 21 05:49:56 2013
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL1.2 -O1 | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+typedef int int4 __attribute((ext_vector_type(4)));
+typedef long long4 __attribute((ext_vector_type(4)));
+typedef float float4 __attribute((ext_vector_type(4)));
+typedef double double4 __attribute((ext_vector_type(4)));
+
+// CHECK: floatops
+kernel void floatops(global int4 *out, global float4 *fout) {
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+ out[0] = (float4)(1, 1, 1, 1) && 1.0f;
+ // CHECK: store <4 x i32> zeroinitializer
+ out[1] = (float4)(0, 0, 0, 0) && (float4)(0, 0, 0, 0);
+
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+ out[2] = (float4)(0, 0, 0, 0) || (float4)(1, 1, 1, 1);
+ // CHECK: store <4 x i32> zeroinitializer
+ out[3] = (float4)(0, 0, 0, 0) || 0.0f;
+
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+ out[4] = !(float4)(0, 0, 0, 0);
+ // CHECK: store <4 x i32> zeroinitializer
+ out[5] = !(float4)(1, 2, 3, 4);
+ // CHECK: store <4 x i32> <i32 -1, i32 0, i32 -1, i32 0>
+ out[6] = !(float4)(0, 1, 0, 1);
+ // CHECK: store <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
+ fout[0] = (float4)(!0.0f);
+ // CHECK: store <4 x float> zeroinitializer
+ fout[1] = (float4)(!1.0f);
+}
+
+// CHECK: doubleops
+kernel void doubleops(global long4 *out, global double4 *dout) {
+ // CHECK: store <4 x i64> <i64 -1, i64 -1, i64 -1, i64 -1>
+ out[0] = (double4)(1, 1, 1, 1) && 1.0;
+ // CHECK: store <4 x i64> zeroinitializer
+ out[1] = (double4)(0, 0, 0, 0) && (double4)(0, 0, 0, 0);
+
+ // CHECK: store <4 x i64> <i64 -1, i64 -1, i64 -1, i64 -1>
+ out[2] = (double4)(0, 0, 0, 0) || (double4)(1, 1, 1, 1);
+ // CHECK: store <4 x i64> zeroinitializer
+ out[3] = (double4)(0, 0, 0, 0) || 0.0f;
+
+ // CHECK: store <4 x i64> <i64 -1, i64 -1, i64 -1, i64 -1>
+ out[4] = !(double4)(0, 0, 0, 0);
+ // CHECK: store <4 x i64> zeroinitializer
+ out[5] = !(double4)(1, 2, 3, 4);
+ // CHECK: store <4 x i64> <i64 -1, i64 0, i64 -1, i64 0>
+ out[6] = !(double4)(0, 1, 0, 1);
+ // CHECK: store <4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
+ dout[0] = (double4)(!0.0f);
+ // CHECK: store <4 x double> zeroinitializer
+ dout[1] = (double4)(!1.0f);
+}
Added: cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.1.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.1.cl?rev=175734&view=auto
==============================================================================
--- cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.1.cl (added)
+++ cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.1.cl Thu Feb 21 05:49:56 2013
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -verify -cl-std=CL1.1
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+typedef __attribute__((ext_vector_type(4))) float float4;
+typedef __attribute__((ext_vector_type(4))) double double4;
+typedef __attribute__((ext_vector_type(4))) int int4;
+typedef __attribute__((ext_vector_type(4))) long long4;
+
+kernel void float_ops() {
+ int flaf = 0.0f && 0.0f; // expected-error {{invalid operands}}
+ int flof = 0.0f || 0.0f; // expected-error {{invalid operands}}
+ float fbaf = 0.0f & 0.0f; // expected-error {{invalid operands}}
+ float fbof = 0.0f | 0.0f; // expected-error {{invalid operands}}
+ float fbxf = 0.0f ^ 0.0f; // expected-error {{invalid operands}}
+ int flai = 0.0f && 0; // expected-error {{invalid operands}}
+ int floi = 0.0f || 0; // expected-error {{invalid operands}}
+ float ibaf = 0 & 0.0f; // expected-error {{invalid operands}}
+ float ibof = 0 | 0.0f; // expected-error {{invalid operands}}
+ float bnf = ~0.0f; // expected-error {{invalid argument type}}
+ float lnf = !0.0f; // expected-error {{invalid argument type}}
+}
+
+kernel void vec_float_ops() {
+ float4 f4 = (float4)(0, 0, 0, 0);
+ int4 f4laf = f4 && 0.0f; // expected-error {{invalid operands}}
+ int4 f4lof = f4 || 0.0f; // expected-error {{invalid operands}}
+ float4 f4baf = f4 & 0.0f; // expected-error {{invalid operands}}
+ float4 f4bof = f4 | 0.0f; // expected-error {{invalid operands}}
+ float4 f4bxf = f4 ^ 0.0f; // expected-error {{invalid operands}}
+ float bnf4 = ~f4; // expected-error {{invalid argument type}}
+ int4 lnf4 = !f4; // expected-error {{invalid argument type}}
+}
+
+kernel void double_ops() {
+ int flaf = 0.0 && 0.0; // expected-error {{invalid operands}}
+ int flof = 0.0 || 0.0; // expected-error {{invalid operands}}
+ double fbaf = 0.0 & 0.0; // expected-error {{invalid operands}}
+ double fbof = 0.0 | 0.0; // expected-error {{invalid operands}}
+ double fbxf = 0.0 ^ 0.0; // expected-error {{invalid operands}}
+ int flai = 0.0 && 0; // expected-error {{invalid operands}}
+ int floi = 0.0 || 0; // expected-error {{invalid operands}}
+ double ibaf = 0 & 0.0; // expected-error {{invalid operands}}
+ double ibof = 0 | 0.0; // expected-error {{invalid operands}}
+ double bnf = ~0.0; // expected-error {{invalid argument type}}
+ double lnf = !0.0; // expected-error {{invalid argument type}}
+}
+
+kernel void vec_double_ops() {
+ double4 f4 = (double4)(0, 0, 0, 0);
+ long4 f4laf = f4 && 0.0; // expected-error {{invalid operands}}
+ long4 f4lof = f4 || 0.0; // expected-error {{invalid operands}}
+ double4 f4baf = f4 & 0.0; // expected-error {{invalid operands}}
+ double4 f4bof = f4 | 0.0; // expected-error {{invalid operands}}
+ double4 f4bxf = f4 ^ 0.0; // expected-error {{invalid operands}}
+ double bnf4 = ~f4; // expected-error {{invalid argument type}}
+ long4 lnf4 = !f4; // expected-error {{invalid argument type}}
+}
Added: cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.2.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.2.cl?rev=175734&view=auto
==============================================================================
--- cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.2.cl (added)
+++ cfe/trunk/test/SemaOpenCL/invalid-logical-ops-1.2.cl Thu Feb 21 05:49:56 2013
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -verify -cl-std=CL1.2
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+typedef __attribute__((ext_vector_type(4))) float float4;
+typedef __attribute__((ext_vector_type(4))) double double4;
+typedef __attribute__((ext_vector_type(4))) int int4;
+typedef __attribute__((ext_vector_type(4))) long long4;
+
+kernel void float_ops() {
+ int flaf = 0.0f && 0.0f;
+ int flof = 0.0f || 0.0f;
+ float fbaf = 0.0f & 0.0f; // expected-error {{invalid operands}}
+ float fbof = 0.0f | 0.0f; // expected-error {{invalid operands}}
+ float fbxf = 0.0f ^ 0.0f; // expected-error {{invalid operands}}
+ int flai = 0.0f && 0;
+ int floi = 0.0f || 0;
+ float ibaf = 0 & 0.0f; // expected-error {{invalid operands}}
+ float ibof = 0 | 0.0f; // expected-error {{invalid operands}}
+ float bnf = ~0.0f;// expected-error {{invalid argument type}}
+ float lnf = !0.0f;
+}
+
+kernel void vec_float_ops() {
+ float4 f4 = (float4)(0, 0, 0, 0);
+ int4 f4laf = f4 && 0.0f;
+ int4 f4lof = f4 || 0.0f;
+ float4 f4baf = f4 & 0.0f; // expected-error {{invalid operands}}
+ float4 f4bof = f4 | 0.0f; // expected-error {{invalid operands}}
+ float4 f4bxf = f4 ^ 0.0f; // expected-error {{invalid operands}}
+ float bnf4 = ~f4; // expected-error {{invalid argument type}}
+ int4 lnf4 = !f4;
+}
+
+kernel void double_ops() {
+ int flaf = 0.0 && 0.0;
+ int flof = 0.0 || 0.0;
+ double fbaf = 0.0 & 0.0; // expected-error {{invalid operands}}
+ double fbof = 0.0 | 0.0; // expected-error {{invalid operands}}
+ double fbxf = 0.0 ^ 0.0; // expected-error {{invalid operands}}
+ int flai = 0.0 && 0;
+ int floi = 0.0 || 0;
+ double ibaf = 0 & 0.0; // expected-error {{invalid operands}}
+ double ibof = 0 | 0.0; // expected-error {{invalid operands}}
+ double bnf = ~0.0; // expected-error {{invalid argument type}}
+ double lnf = !0.0;
+}
+
+kernel void vec_double_ops() {
+ double4 f4 = (double4)(0, 0, 0, 0);
+ long4 f4laf = f4 && 0.0;
+ long4 f4lof = f4 || 0.0;
+ double4 f4baf = f4 & 0.0; // expected-error {{invalid operands}}
+ double4 f4bof = f4 | 0.0; // expected-error {{invalid operands}}
+ double4 f4bxf = f4 ^ 0.0; // expected-error {{invalid operands}}
+ double bnf4 = ~f4; // expected-error {{invalid argument type}}
+ long4 lnf4 = !f4;
+}
More information about the cfe-commits
mailing list