Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit b49f706

Browse files
committed
[OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.
Summary: Enabling the compression of CLK_NULL_QUEUE to variable of type queue_t. Reviewers: Anastasia Subscribers: cfe-commits, yaxunl, bader Differential Revision: https://reviews.llvm.org/D27569 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290171 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 4e57f52 commit b49f706

14 files changed

+124
-1
lines changed

Diff for: include/clang/AST/OperationKinds.def

+3
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ CAST_OPERATION(BuiltinFnToFnPtr)
321321
// Convert a zero value for OpenCL event_t initialization.
322322
CAST_OPERATION(ZeroToOCLEvent)
323323

324+
// Convert a zero value for OpenCL queue_t initialization.
325+
CAST_OPERATION(ZeroToOCLQueue)
326+
324327
// Convert a pointer to a different address space.
325328
CAST_OPERATION(AddressSpaceConversion)
326329

Diff for: include/clang/Sema/Initialization.h

+5
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,8 @@ class InitializationSequence {
751751
SK_StdInitializerListConstructorCall,
752752
/// \brief Initialize an OpenCL sampler from an integer.
753753
SK_OCLSamplerInit,
754+
/// \brief Initialize queue_t from 0.
755+
SK_OCLZeroQueue,
754756
/// \brief Passing zero to a function where OpenCL event_t is expected.
755757
SK_OCLZeroEvent
756758
};
@@ -1148,6 +1150,9 @@ class InitializationSequence {
11481150
/// constant.
11491151
void AddOCLZeroEventStep(QualType T);
11501152

1153+
/// \brief Add a step to initialize an OpenCL queue_t from 0.
1154+
void AddOCLZeroQueueStep(QualType T);
1155+
11511156
/// \brief Add steps to unwrap a initializer list for a reference around a
11521157
/// single element and rewrap it at the end.
11531158
void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);

Diff for: include/clang/Sema/Overload.h

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ namespace clang {
8383
ICK_TransparentUnionConversion, ///< Transparent Union Conversions
8484
ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion
8585
ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10)
86+
ICK_Zero_Queue_Conversion, ///< Zero constant to queue
8687
ICK_C_Only_Conversion, ///< Conversions allowed in C, but not C++
8788
ICK_Incompatible_Pointer_Conversion, ///< C-only conversion between pointers
8889
/// with incompatible types

Diff for: lib/AST/ExprConstant.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -8340,6 +8340,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
83408340
case CK_IntegralComplexToFloatingComplex:
83418341
case CK_BuiltinFnToFnPtr:
83428342
case CK_ZeroToOCLEvent:
8343+
case CK_ZeroToOCLQueue:
83438344
case CK_NonAtomicToAtomic:
83448345
case CK_AddressSpaceConversion:
83458346
case CK_IntToOCLSampler:
@@ -8837,6 +8838,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
88378838
case CK_CopyAndAutoreleaseBlockObject:
88388839
case CK_BuiltinFnToFnPtr:
88398840
case CK_ZeroToOCLEvent:
8841+
case CK_ZeroToOCLQueue:
88408842
case CK_NonAtomicToAtomic:
88418843
case CK_AddressSpaceConversion:
88428844
case CK_IntToOCLSampler:

Diff for: lib/CodeGen/CGExprAgg.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
751751
case CK_CopyAndAutoreleaseBlockObject:
752752
case CK_BuiltinFnToFnPtr:
753753
case CK_ZeroToOCLEvent:
754+
case CK_ZeroToOCLQueue:
754755
case CK_AddressSpaceConversion:
755756
case CK_IntToOCLSampler:
756757
llvm_unreachable("cast kind invalid for aggregate types");

Diff for: lib/CodeGen/CGExprComplex.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
480480
case CK_CopyAndAutoreleaseBlockObject:
481481
case CK_BuiltinFnToFnPtr:
482482
case CK_ZeroToOCLEvent:
483+
case CK_ZeroToOCLQueue:
483484
case CK_AddressSpaceConversion:
484485
case CK_IntToOCLSampler:
485486
llvm_unreachable("invalid cast kind for complex value");

Diff for: lib/CodeGen/CGExprScalar.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,11 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
15931593
return llvm::Constant::getNullValue(ConvertType(DestTy));
15941594
}
15951595

1596+
case CK_ZeroToOCLQueue: {
1597+
assert(DestTy->isQueueT() && "CK_ZeroToOCLQueue cast on non queue_t type");
1598+
return llvm::Constant::getNullValue(ConvertType(DestTy));
1599+
}
1600+
15961601
case CK_IntToOCLSampler:
15971602
return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
15981603

Diff for: lib/Sema/SemaExpr.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -9635,6 +9635,18 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
96359635
return ResultTy;
96369636
}
96379637

9638+
if (getLangOpts().OpenCLVersion >= 200) {
9639+
if (LHSIsNull && RHSType->isQueueT()) {
9640+
LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
9641+
return ResultTy;
9642+
}
9643+
9644+
if (LHSType->isQueueT() && RHSIsNull) {
9645+
RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
9646+
return ResultTy;
9647+
}
9648+
}
9649+
96389650
return InvalidOperands(Loc, LHS, RHS);
96399651
}
96409652

Diff for: lib/Sema/SemaExprCXX.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -3878,6 +3878,12 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
38783878
From->getValueKind()).get();
38793879
break;
38803880

3881+
case ICK_Zero_Queue_Conversion:
3882+
From = ImpCastExprToType(From, ToType,
3883+
CK_ZeroToOCLQueue,
3884+
From->getValueKind()).get();
3885+
break;
3886+
38813887
case ICK_Lvalue_To_Rvalue:
38823888
case ICK_Array_To_Pointer:
38833889
case ICK_Function_To_Pointer:

Diff for: lib/Sema/SemaInit.cpp

+40-1
Original file line numberDiff line numberDiff line change
@@ -3077,6 +3077,7 @@ void InitializationSequence::Step::Destroy() {
30773077
case SK_StdInitializerListConstructorCall:
30783078
case SK_OCLSamplerInit:
30793079
case SK_OCLZeroEvent:
3080+
case SK_OCLZeroQueue:
30803081
break;
30813082

30823083
case SK_ConversionSequence:
@@ -3365,6 +3366,13 @@ void InitializationSequence::AddOCLZeroEventStep(QualType T) {
33653366
Steps.push_back(S);
33663367
}
33673368

3369+
void InitializationSequence::AddOCLZeroQueueStep(QualType T) {
3370+
Step S;
3371+
S.Kind = SK_OCLZeroQueue;
3372+
S.Type = T;
3373+
Steps.push_back(S);
3374+
}
3375+
33683376
void InitializationSequence::RewrapReferenceInitList(QualType T,
33693377
InitListExpr *Syntactic) {
33703378
assert(Syntactic->getNumInits() == 1 &&
@@ -5030,6 +5038,20 @@ static bool TryOCLZeroEventInitialization(Sema &S,
50305038
return true;
50315039
}
50325040

5041+
static bool TryOCLZeroQueueInitialization(Sema &S,
5042+
InitializationSequence &Sequence,
5043+
QualType DestType,
5044+
Expr *Initializer) {
5045+
if (!S.getLangOpts().OpenCL || S.getLangOpts().OpenCLVersion < 200 ||
5046+
!DestType->isQueueT() ||
5047+
!Initializer->isIntegerConstantExpr(S.getASTContext()) ||
5048+
(Initializer->EvaluateKnownConstInt(S.getASTContext()) != 0))
5049+
return false;
5050+
5051+
Sequence.AddOCLZeroQueueStep(DestType);
5052+
return true;
5053+
}
5054+
50335055
InitializationSequence::InitializationSequence(Sema &S,
50345056
const InitializedEntity &Entity,
50355057
const InitializationKind &Kind,
@@ -5292,6 +5314,9 @@ void InitializationSequence::InitializeFrom(Sema &S,
52925314
if (TryOCLZeroEventInitialization(S, *this, DestType, Initializer))
52935315
return;
52945316

5317+
if (TryOCLZeroQueueInitialization(S, *this, DestType, Initializer))
5318+
return;
5319+
52955320
// Handle initialization in C
52965321
AddCAssignmentStep(DestType);
52975322
MaybeProduceObjCObject(S, *this, Entity);
@@ -6529,7 +6554,8 @@ InitializationSequence::Perform(Sema &S,
65296554
case SK_ProduceObjCObject:
65306555
case SK_StdInitializerList:
65316556
case SK_OCLSamplerInit:
6532-
case SK_OCLZeroEvent: {
6557+
case SK_OCLZeroEvent:
6558+
case SK_OCLZeroQueue: {
65336559
assert(Args.size() == 1);
65346560
CurInit = Args[0];
65356561
if (!CurInit.get()) return ExprError();
@@ -7213,6 +7239,15 @@ InitializationSequence::Perform(Sema &S,
72137239
CurInit.get()->getValueKind());
72147240
break;
72157241
}
7242+
case SK_OCLZeroQueue: {
7243+
assert(Step->Type->isQueueT() &&
7244+
"Event initialization on non queue type.");
7245+
7246+
CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
7247+
CK_ZeroToOCLQueue,
7248+
CurInit.get()->getValueKind());
7249+
break;
7250+
}
72167251
}
72177252
}
72187253

@@ -8041,6 +8076,10 @@ void InitializationSequence::dump(raw_ostream &OS) const {
80418076
case SK_OCLZeroEvent:
80428077
OS << "OpenCL event_t from zero";
80438078
break;
8079+
8080+
case SK_OCLZeroQueue:
8081+
OS << "OpenCL queue_t from zero";
8082+
break;
80448083
}
80458084

80468085
OS << " [" << S->Type.getAsString() << ']';

Diff for: lib/Sema/SemaOverload.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,11 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
17851785
From->EvaluateKnownConstInt(S.getASTContext()) == 0) {
17861786
SCS.Second = ICK_Zero_Event_Conversion;
17871787
FromType = ToType;
1788+
} else if (ToType->isQueueT() &&
1789+
From->isIntegerConstantExpr(S.getASTContext()) &&
1790+
(From->EvaluateKnownConstInt(S.getASTContext()) == 0)) {
1791+
SCS.Second = ICK_Zero_Queue_Conversion;
1792+
FromType = ToType;
17881793
} else {
17891794
// No second conversion required.
17901795
SCS.Second = ICK_Identity;
@@ -5162,6 +5167,7 @@ static bool CheckConvertedConstantConversions(Sema &S,
51625167
case ICK_Function_Conversion:
51635168
case ICK_Integral_Promotion:
51645169
case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere.
5170+
case ICK_Zero_Queue_Conversion:
51655171
return true;
51665172

51675173
case ICK_Boolean_Conversion:

Diff for: test/CodeGenOpenCL/null_queue.cl

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -emit-llvm %s -o - | FileCheck %s
2+
extern queue_t get_default_queue();
3+
4+
bool compare() {
5+
return 0 == get_default_queue() &&
6+
get_default_queue() == 0;
7+
// CHECK: icmp eq %opencl.queue_t* null, %{{.*}}
8+
// CHECK: icmp eq %opencl.queue_t* %{{.*}}, null
9+
}
10+
11+
void func(queue_t q);
12+
13+
void init() {
14+
queue_t q = 0;
15+
func(0);
16+
// CHECK: store %opencl.queue_t* null, %opencl.queue_t** %q
17+
// CHECK: call void @func(%opencl.queue_t* null)
18+
}

Diff for: test/SemaOpenCL/null_queue.cl

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only
2+
extern queue_t get_default_queue();
3+
4+
bool compare() {
5+
return 1 == get_default_queue() && // expected-error{{invalid operands to binary expression ('int' and 'queue_t')}}
6+
get_default_queue() == 1; // expected-error{{invalid operands to binary expression ('queue_t' and 'int')}}
7+
}
8+
9+
void init() {
10+
queue_t q1 = 1; // expected-error{{initializing 'queue_t' with an expression of incompatible type 'int'}}
11+
queue_t q = 0;
12+
}

Diff for: test/SemaOpenCL/queue_t_overload.cl

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only
2+
3+
void __attribute__((overloadable)) foo(queue_t, __local char *); // expected-note {{candidate function not viable: no known conversion from 'int' to 'queue_t' for 1st argument}} // expected-note {{candidate function}}
4+
void __attribute__((overloadable)) foo(queue_t, __local float *); // expected-note {{candidate function not viable: no known conversion from 'int' to 'queue_t' for 1st argument}} // expected-note {{candidate function}}
5+
6+
void kernel ker(__local char *src1, __local float *src2, __global int *src3) {
7+
queue_t q;
8+
foo(q, src1);
9+
foo(0, src2);
10+
foo(q, src3); // expected-error {{call to 'foo' is ambiguous}}
11+
foo(1, src3); // expected-error {{no matching function for call to 'foo'}}
12+
}

0 commit comments

Comments
 (0)