yaxunl updated this revision to Diff 62966.
yaxunl added a comment.

Removed the old representation of sampler type by i32.


http://reviews.llvm.org/D21567

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/AST/OperationKinds.def
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Overload.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/CodeGen/CGOpenCLRuntime.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Index/USRGeneration.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaInit.cpp
  lib/Sema/SemaOverload.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/CodeGenOpenCL/opencl_types.cl
  test/CodeGenOpenCL/sampler.cl
  test/SemaOpenCL/sampler_t.cl
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -1466,6 +1466,7 @@
   case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
   case BuiltinType::OCLSampler:
+  case BuiltinType::OCLSamplerInit:
   case BuiltinType::OCLEvent:
   case BuiltinType::OCLClkEvent:
   case BuiltinType::OCLQueue:
Index: test/SemaOpenCL/sampler_t.cl
===================================================================
--- test/SemaOpenCL/sampler_t.cl
+++ test/SemaOpenCL/sampler_t.cl
@@ -13,6 +13,7 @@
   const sampler_t const_smp = 7;
   foo(glb_smp);
   foo(const_smp);
+  foo(argsmp);
   foo(5); // expected-error {{sampler_t variable required - got 'int'}}
   sampler_t sa[] = {argsmp, const_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}}
 }
Index: test/CodeGenOpenCL/sampler.cl
===================================================================
--- /dev/null
+++ test/CodeGenOpenCL/sampler.cl
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple spir-unknown-unknown -o - -O0 | FileCheck %s
+
+#define CLK_ADDRESS_CLAMP_TO_EDGE       2
+#define CLK_NORMALIZED_COORDS_TRUE      1
+#define CLK_FILTER_NEAREST              0x10
+#define CLK_FILTER_LINEAR               0x20
+
+constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
+
+// CHECK: %__sampler_initializer = type { i32, i32, i32 }
+// CHECK: %__sampler = type opaque
+// CHECK: [[glb_smp_init:@[-a-zA-Z$._][-a-zA-Z$._0-9]*]] = internal addrspace(2) constant %__sampler_initializer { i32 1, i32 1, i32 1 }
+// CHECK: @glb_smp = global %__sampler_initializer addrspace(2)* [[glb_smp_init]]
+// CHECK: [[smp_init:@[-a-zA-Z$._][-a-zA-Z$._0-9]*]] = internal addrspace(2) constant %__sampler_initializer { i32 1, i32 1, i32 0 }
+
+void fnc4smp(sampler_t s) {}
+// CHECK: define spir_func void @fnc4smp(%__sampler addrspace(2)* %
+
+kernel void foo() {
+  sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_NEAREST;
+  // CHECK-LABEL: define spir_kernel void @foo()
+  // CHECK: [[smp_ptr:%[A-Za-z0-9_\.]+]] = alloca %__sampler_initializer addrspace(2)*
+  // CHECK: store %__sampler_initializer addrspace(2)* [[smp_init]], %__sampler_initializer addrspace(2)** [[smp_ptr]]
+
+  fnc4smp(smp);
+  // CHECK: [[SINIT:%[0-9]+]] = load %__sampler_initializer addrspace(2)*, %__sampler_initializer addrspace(2)** [[smp_ptr]]
+  // CHECK: [[SAMP:%[0-9]+]] = call %__sampler addrspace(2)* @__translate_sampler_initializer(%__sampler_initializer addrspace(2)* [[SINIT]])
+  // CHECK: call spir_func void @fnc4smp(%__sampler addrspace(2)* [[SAMP]])
+
+  fnc4smp(glb_smp);
+  // CHECK: [[SINIT:%[0-9]+]] = load %__sampler_initializer addrspace(2)*, %__sampler_initializer addrspace(2)** @glb_smp
+  // CHECK: [[SAMP:%[0-9]+]] = call %__sampler addrspace(2)* @__translate_sampler_initializer(%__sampler_initializer addrspace(2)* [[SINIT]])
+  // CHECK: call spir_func void @fnc4smp(%__sampler addrspace(2)* [[SAMP]])
+}
Index: test/CodeGenOpenCL/opencl_types.cl
===================================================================
--- test/CodeGenOpenCL/opencl_types.cl
+++ test/CodeGenOpenCL/opencl_types.cl
@@ -1,39 +1,46 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 | FileCheck %s
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -o - -O0 | FileCheck %s
 
-constant sampler_t glb_smp = 7;
-// CHECK: constant i32 7
+#define CLK_ADDRESS_CLAMP_TO_EDGE       2
+#define CLK_NORMALIZED_COORDS_TRUE      1
+#define CLK_FILTER_NEAREST              0x10
+#define CLK_FILTER_LINEAR               0x20
+
+constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE|CLK_NORMALIZED_COORDS_TRUE|CLK_FILTER_NEAREST;
+// CHECK: [[SAMP1:.+]] = internal addrspace(2) constant %__sampler_initializer { i32 1, i32 1, i32 0 }
+// CHECK: glb_smp = global %__sampler_initializer addrspace(2)* [[SAMP1]]
+// CHECK: [[SAMP2:.+]] = internal addrspace(2) constant %__sampler_initializer { i32 1, i32 1, i32 1 }
 
 void fnc1(image1d_t img) {}
-// CHECK: @fnc1(%opencl.image1d_ro_t*
+// CHECK: @fnc1(%opencl.image1d_ro_t addrspace(1)*
 
 void fnc1arr(image1d_array_t img) {}
-// CHECK: @fnc1arr(%opencl.image1d_array_ro_t*
+// CHECK: @fnc1arr(%opencl.image1d_array_ro_t addrspace(1)*
 
 void fnc1buff(image1d_buffer_t img) {}
-// CHECK: @fnc1buff(%opencl.image1d_buffer_ro_t*
+// CHECK: @fnc1buff(%opencl.image1d_buffer_ro_t addrspace(1)*
 
 void fnc2(image2d_t img) {}
-// CHECK: @fnc2(%opencl.image2d_ro_t*
+// CHECK: @fnc2(%opencl.image2d_ro_t addrspace(1)*
 
 void fnc2arr(image2d_array_t img) {}
-// CHECK: @fnc2arr(%opencl.image2d_array_ro_t*
+// CHECK: @fnc2arr(%opencl.image2d_array_ro_t addrspace(1)*
 
 void fnc3(image3d_t img) {}
-// CHECK: @fnc3(%opencl.image3d_ro_t*
+// CHECK: @fnc3(%opencl.image3d_ro_t addrspace(1)*
 
 void fnc4smp(sampler_t s) {}
-// CHECK-LABEL: define {{.*}}void @fnc4smp(i32
+// CHECK-LABEL: define {{.*}}void @fnc4smp(%__sampler addrspace(2)*
 
 kernel void foo(image1d_t img) {
-  sampler_t smp = 5;
-  // CHECK: alloca i32
+  sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE|CLK_NORMALIZED_COORDS_TRUE|CLK_FILTER_LINEAR;
+  // CHECK: alloca %__sampler_initializer addrspace(2)*
   event_t evt;
   // CHECK: alloca %opencl.event_t*
-  // CHECK: store i32 5,
+  // CHECK: store %__sampler_initializer addrspace(2)* [[SAMP2]],
   fnc4smp(smp);
-  // CHECK: call {{.*}}void @fnc4smp(i32
+  // CHECK: call {{.*}}void @fnc4smp(%__sampler addrspace(2)*
   fnc4smp(glb_smp);
-  // CHECK: call {{.*}}void @fnc4smp(i32
+  // CHECK: call {{.*}}void @fnc4smp(%__sampler addrspace(2)*
 }
 
 void __attribute__((overloadable)) bad1(image1d_t b, image2d_t c, image2d_t d) {}
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -341,6 +341,8 @@
       case CK_AnyPointerToBlockPointerCast:
       case CK_ObjCObjectLValueCast:
       case CK_ZeroToOCLEvent:
+      case CK_IntToOCLSamplerInitializer:
+      case CK_OCLSamplerInitializerToSampler:
       case CK_LValueBitCast: {
         // Delegate to SValBuilder to process.
         SVal V = state->getSVal(Ex, LCtx);
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6087,6 +6087,9 @@
     case PREDEF_TYPE_SAMPLER_ID:
       T = Context.OCLSamplerTy;
       break;
+    case PREDEF_TYPE_SAMPLER_INIT_ID:
+      T = Context.OCLSamplerInitTy;
+      break;
     case PREDEF_TYPE_EVENT_ID:
       T = Context.OCLEventTy;
       break;
Index: lib/Serialization/ASTCommon.cpp
===================================================================
--- lib/Serialization/ASTCommon.cpp
+++ lib/Serialization/ASTCommon.cpp
@@ -138,6 +138,9 @@
   case BuiltinType::OCLSampler:
     ID = PREDEF_TYPE_SAMPLER_ID;
     break;
+  case BuiltinType::OCLSamplerInit:
+    ID = PREDEF_TYPE_SAMPLER_ID;
+    break;
   case BuiltinType::OCLEvent:
     ID = PREDEF_TYPE_EVENT_ID;
     break;
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -1738,7 +1738,11 @@
              From->EvaluateKnownConstInt(S.getASTContext()) == 0) {
     SCS.Second = ICK_Zero_Event_Conversion;
     FromType = ToType;
-  } else {
+  } else if (ToType->isSamplerT() && From->getType()->isSamplerInitT()) {
+    SCS.Second = ICK_Sampler_Conversion;
+    FromType = ToType;
+  }
+  else {
     // No second conversion required.
     SCS.Second = ICK_Identity;
   }
@@ -5105,6 +5109,7 @@
   case ICK_TransparentUnionConversion:
   case ICK_Writeback_Conversion:
   case ICK_Zero_Event_Conversion:
+  case ICK_Sampler_Conversion:
   case ICK_C_Only_Conversion:
     return false;
 
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -4886,7 +4886,8 @@
                                         QualType DestType,
                                         Expr *Initializer) {
   if (!S.getLangOpts().OpenCL || !DestType->isSamplerT() ||
-    !Initializer->isIntegerConstantExpr(S.getASTContext()))
+      (!Initializer->isIntegerConstantExpr(S.Context) &&
+      !Initializer->getType()->isSamplerInitT()))
     return false;
 
   Sequence.AddOCLSamplerInitStep(DestType);
@@ -6904,19 +6905,27 @@
     }
 
     case SK_OCLSamplerInit: {
-      assert(Step->Type->isSamplerT() && 
-             "Sampler initialization on non-sampler type.");
-
-      QualType SourceType = CurInit.get()->getType();
-
+      Expr *Init = CurInit.get();
+      QualType SourceType = Init->getType();
       if (Entity.isParameterKind()) {
-        if (!SourceType->isSamplerT())
+        if (SourceType->isSamplerInitT()) {
+          Init->setValueKind(VK_RValue);
+          CurInit = S.ImpCastExprToType(Init, Step->Type,
+                                        CK_OCLSamplerInitializerToSampler);
+        } else if (!SourceType->isSamplerT())
           S.Diag(Kind.getLocation(), diag::err_sampler_argument_required)
             << SourceType;
-      } else if (Entity.getKind() != InitializedEntity::EK_Variable) {
-        llvm_unreachable("Invalid EntityKind!");
+      } else {
+        if (!Init->isConstantInitializer(S.Context, false))
+          S.Diag(Kind.getLocation(),
+                 diag::err_sampler_initializer_not_constant);
+        if (!SourceType->isIntegerType() ||
+            32 != S.Context.getIntWidth(SourceType))
+          S.Diag(Kind.getLocation(), diag::err_sampler_initializer_not_integer)
+            << SourceType;
+        CurInit = S.ImpCastExprToType(Init, S.Context.OCLSamplerInitTy,
+                                      CK_IntToOCLSamplerInitializer);
       }
-
       break;
     }
     case SK_OCLZeroEvent: {
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -3698,6 +3698,11 @@
                              From->getValueKind()).get();
     break;
 
+  case ICK_Sampler_Conversion:
+    From = ImpCastExprToType(From, ToType,
+                             CK_OCLSamplerInitializerToSampler).get();
+    break;
+
   case ICK_Lvalue_To_Rvalue:
   case ICK_Array_To_Pointer:
   case ICK_Function_To_Pointer:
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -7582,6 +7582,16 @@
     }
   }
 
+  if (LHSType->isSamplerT() && RHSType->isIntegerType()) {
+    Kind = CK_IntToOCLSamplerInitializer;
+    return Compatible;
+  }
+
+  if (LHSType->isSpecificBuiltinType(BuiltinType::OCLSamplerInit) &&
+      RHSType->isSamplerT()) {
+    Kind = CK_OCLSamplerInitializerToSampler;
+    return Compatible;
+  }
   return Incompatible;
 }
 
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -10305,6 +10305,9 @@
       var->setInvalidDecl();
       return;
     }
+
+    if (var->getType()->isSamplerT())
+      var->setType(Context.OCLSamplerInitTy);
   }
 
   // In Objective-C, don't allow jumps past the implicit initialization of a
Index: lib/Index/USRGeneration.cpp
===================================================================
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -635,6 +635,7 @@
         case BuiltinType::OCLNDRange:
         case BuiltinType::OCLReserveID:
         case BuiltinType::OCLSampler:
+        case BuiltinType::OCLSamplerInit:
           IgnoreResults = true;
           return;
         case BuiltinType::ObjCId:
Index: lib/Edit/RewriteObjCFoundationAPI.cpp
===================================================================
--- lib/Edit/RewriteObjCFoundationAPI.cpp
+++ lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1076,6 +1076,8 @@
     case CK_CopyAndAutoreleaseBlockObject:
     case CK_BuiltinFnToFnPtr:
     case CK_ZeroToOCLEvent:
+    case CK_IntToOCLSamplerInitializer:
+    case CK_OCLSamplerInitializerToSampler:
       return false;
 
     case CK_BooleanToSignedIntegral:
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -2560,6 +2560,7 @@
     case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
     case BuiltinType::OCLSampler:
+    case BuiltinType::OCLSamplerInit:
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
Index: lib/CodeGen/CodeGenTypes.cpp
===================================================================
--- lib/CodeGen/CodeGenTypes.cpp
+++ lib/CodeGen/CodeGenTypes.cpp
@@ -469,6 +469,7 @@
     case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
     case BuiltinType::OCLSampler:
+    case BuiltinType::OCLSamplerInit:
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1145,6 +1145,12 @@
 
   llvm::SanitizerStatReport &getSanStats();
 
+  llvm::Constant*
+  createIntToSamplerConversion(const Expr *E,
+                               CodeGenFunction *CGF,
+                               llvm::GlobalVariable *InsertBefore = nullptr,
+                               StringRef Name = "");
+
 private:
   llvm::Constant *
   GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D,
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -4288,3 +4288,58 @@
 
   return *SanStats;
 }
+llvm::Constant*
+CodeGenModule::createIntToSamplerConversion(const Expr *E,
+                                            CodeGenFunction *CGF,
+                                            llvm::GlobalVariable *InsertBefore,
+                                            StringRef Name) {
+  llvm::Constant *C = EmitConstantExpr(E, E->getType(), CGF);
+  assert(C && "Sampler must be initialized by constant");
+  assert(isa<llvm::ConstantInt>(C) && "Sampler must be initialized by integer");
+
+  llvm::StructType*
+    ConstSamplerTy = TheModule.getTypeByName("__sampler_initializer");
+  if (!ConstSamplerTy ) {
+    llvm::Type* Elements[] = {Int32Ty, Int32Ty, Int32Ty};
+    ConstSamplerTy = llvm::StructType::create(VMContext, Elements,
+                                              "__sampler_initializer");
+  }
+  const llvm::ConstantInt *CI = static_cast<llvm::ConstantInt*>(C);
+  const uint64_t SamplerValue = CI->getValue().getZExtValue();
+  // 32-bit value of sampler's initializer is interpreted as
+  // bit-field with the following structure:
+  // |unspecified|Filter|Addressing Mode| Normalized Coords|
+  // |31        6|5    4|3             1|                 0|
+  // This structure corresponds to values of sampler properties from opencl.h
+  // Mapping these bits to values defined by SPIR-V specification.
+  unsigned NormalizedCoords = 0x01 & SamplerValue;
+  unsigned AddressingMode  = (0x0E & SamplerValue) >> 1;
+  unsigned FilterMode      = (0x30 & SamplerValue) >> 4;
+  // In SPIR sampler's filter bits are defined as the following
+  // #define CLK_FILTER_NEAREST 0x10
+  // #define CLK_FILTER_LINEAR 0x20
+  // corresponding to 1 and 2 in bits 4-5.
+  // SPIR-V defines sampler filter mode enum as: nearest=0, linear=1,
+  // Therefore, to convert FilterMode from SPIR to SPIR-V,
+  // FilterMode value must be decremented
+  if (FilterMode == 1 || FilterMode == 2)
+    --FilterMode;
+   else
+    getDiags().Report(Context.getFullLoc(E->getLocStart()),
+      diag::warn_sampler_initializer_invalid_bits) << "Filter Mode";
+  if (AddressingMode > 4)
+    getDiags().Report(Context.getFullLoc(E->getLocStart()),
+      diag::warn_sampler_initializer_invalid_bits) << "Addressing Mode";
+
+  llvm::Constant *Initializer = llvm::ConstantStruct::get(ConstSamplerTy,
+    llvm::ConstantInt::get(Int32Ty, AddressingMode),
+    llvm::ConstantInt::get(Int32Ty, NormalizedCoords),
+    llvm::ConstantInt::get(Int32Ty, FilterMode),
+    nullptr);
+  auto AS = Context.getTargetAddressSpace(LangAS::opencl_constant);
+  return new llvm::GlobalVariable(TheModule, ConstSamplerTy, true,
+                                  llvm::GlobalVariable::InternalLinkage,
+                                  Initializer, Name + ".sampler.init",
+                                  InsertBefore,
+                                  llvm::GlobalVariable::NotThreadLocal, AS);
+}
Index: lib/CodeGen/CGOpenCLRuntime.cpp
===================================================================
--- lib/CodeGen/CGOpenCLRuntime.cpp
+++ lib/CodeGen/CGOpenCLRuntime.cpp
@@ -47,7 +47,18 @@
         ImgAddrSpc);
 #include "clang/Basic/OpenCLImageTypes.def"
   case BuiltinType::OCLSampler:
-    return llvm::IntegerType::get(Ctx, 32);
+    return llvm::PointerType::get(llvm::StructType::create(
+                           Ctx, "__sampler"),
+                           CGM.getContext().getTargetAddressSpace(
+                           LangAS::opencl_constant));
+  case BuiltinType::OCLSamplerInit: {
+    auto Int32Ty = llvm::IntegerType::get(Ctx, 32);
+    llvm::Type* Elements[] = {Int32Ty, Int32Ty, Int32Ty};
+    return llvm::PointerType::get(llvm::StructType::create(
+                           Ctx, Elements, "__sampler_initializer"),
+                           CGM.getContext().getTargetAddressSpace(
+                           LangAS::opencl_constant));
+    }
   case BuiltinType::OCLEvent:
     return llvm::PointerType::get(llvm::StructType::create(
                            Ctx, "opencl.event_t"), 0);
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -1573,8 +1573,25 @@
     return llvm::Constant::getNullValue(ConvertType(DestTy));
   }
 
+  case CK_IntToOCLSamplerInitializer:
+    return CGF.CGM.createIntToSamplerConversion(E, &CGF);
+
+  case CK_OCLSamplerInitializerToSampler: {
+    auto SampInit = Visit(E);
+    auto SamplerTy = CGF.CGM.getModule().getTypeByName("__sampler");
+    if(!SamplerTy)
+      SamplerTy = llvm::StructType::create(VMContext, "__sampler");
+
+    auto AS = CGF.getContext().getTargetAddressSpace(LangAS::opencl_constant);
+    auto FTy = llvm::FunctionType::get(llvm::PointerType::get(SamplerTy, AS),
+                                       {SampInit->getType()}, false);
+    return CGF.Builder.CreateCall(
+      CGF.CGM.CreateRuntimeFunction(FTy, "__translate_sampler_initializer"),
+                                    {SampInit});
   }
 
+  } // end of switch
+
   llvm_unreachable("unknown scalar cast");
 }
 
Index: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -690,6 +690,12 @@
     case CK_ConstructorConversion:
       return C;
 
+    case CK_IntToOCLSamplerInitializer:
+      return CGM.createIntToSamplerConversion(subExpr, CGF);
+
+    case CK_OCLSamplerInitializerToSampler:
+      llvm_unreachable("saw dependent cast!");
+
     case CK_Dependent: llvm_unreachable("saw dependent cast!");
 
     case CK_BuiltinFnToFnPtr:
Index: lib/CodeGen/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -484,6 +484,8 @@
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
   case CK_AddressSpaceConversion:
+  case CK_IntToOCLSamplerInitializer:
+  case CK_OCLSamplerInitializerToSampler:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_FloatingRealToComplex:
Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp
+++ lib/CodeGen/CGExprAgg.cpp
@@ -750,6 +750,8 @@
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
   case CK_AddressSpaceConversion:
+  case CK_IntToOCLSamplerInitializer:
+  case CK_OCLSamplerInitializerToSampler:
     llvm_unreachable("cast kind invalid for aggregate types");
   }
 }
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -3584,6 +3584,8 @@
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_AddressSpaceConversion:
+  case CK_IntToOCLSamplerInitializer:
+  case CK_OCLSamplerInitializerToSampler:
     return EmitUnsupportedLValue(E, "unexpected cast lvalue");
 
   case CK_Dependent:
Index: lib/CodeGen/CGDebugInfo.h
===================================================================
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -67,6 +67,8 @@
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
   llvm::DIType *SingletonId = nullptr;
 #include "clang/Basic/OpenCLImageTypes.def"
+  llvm::DIType *OCLSamplerDITy = nullptr;
+  llvm::DIType *OCLSamplerInitDITy = nullptr;
   llvm::DIType *OCLEventDITy = nullptr;
   llvm::DIType *OCLClkEventDITy = nullptr;
   llvm::DIType *OCLQueueDITy = nullptr;
Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -476,9 +476,11 @@
                                     SingletonId);
 #include "clang/Basic/OpenCLImageTypes.def"
   case BuiltinType::OCLSampler:
-    return DBuilder.createBasicType(
-        "opencl_sampler_t", CGM.getContext().getTypeSize(BT),
-        CGM.getContext().getTypeAlign(BT), llvm::dwarf::DW_ATE_unsigned);
+    return getOrCreateStructPtrType("opencl_sampler_t",
+                                    OCLSamplerInitDITy);
+  case BuiltinType::OCLSamplerInit:
+    return getOrCreateStructPtrType("opencl_sampler_initializer_t",
+                                    OCLSamplerInitDITy);
   case BuiltinType::OCLEvent:
     return getOrCreateStructPtrType("opencl_event_t", OCLEventDITy);
   case BuiltinType::OCLClkEvent:
Index: lib/AST/TypeLoc.cpp
===================================================================
--- lib/AST/TypeLoc.cpp
+++ lib/AST/TypeLoc.cpp
@@ -338,6 +338,7 @@
   case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
   case BuiltinType::OCLSampler:
+  case BuiltinType::OCLSamplerInit:
   case BuiltinType::OCLEvent:
   case BuiltinType::OCLClkEvent:
   case BuiltinType::OCLQueue:
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -2595,6 +2595,8 @@
 #include "clang/Basic/OpenCLImageTypes.def"
   case OCLSampler:
     return "sampler_t";
+  case OCLSamplerInit:
+    return "samper_initializer_t";
   case OCLEvent:
     return "event_t";
   case OCLClkEvent:
@@ -3570,6 +3572,7 @@
     case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
     case BuiltinType::OCLSampler:
+    case BuiltinType::OCLSamplerInit:
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
Index: lib/AST/NSAPI.cpp
===================================================================
--- lib/AST/NSAPI.cpp
+++ lib/AST/NSAPI.cpp
@@ -450,6 +450,7 @@
   case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
   case BuiltinType::OCLSampler:
+  case BuiltinType::OCLSamplerInit:
   case BuiltinType::OCLEvent:
   case BuiltinType::OCLClkEvent:
   case BuiltinType::OCLQueue:
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -1732,6 +1732,10 @@
     Out << "PA";
     mangleArtificalTagType(TTK_Struct, "ocl_sampler");
     break;
+  case BuiltinType::OCLSamplerInit:
+    Out << "PA";
+    mangleArtificalTagType(TTK_Struct, "ocl_sampler_init");
+    break;
   case BuiltinType::OCLEvent:
     Out << "PA";
     mangleArtificalTagType(TTK_Struct, "ocl_event");
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -2127,6 +2127,9 @@
   case BuiltinType::OCLSampler:
     Out << "11ocl_sampler";
     break;
+  case BuiltinType::OCLSamplerInit:
+    Out << "16ocl_sampler_init";
+    break;
   case BuiltinType::OCLEvent:
     Out << "9ocl_event";
     break;
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -6416,6 +6416,7 @@
     case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
     case BuiltinType::OCLSampler:
+    case BuiltinType::OCLSamplerInit:
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
@@ -8035,6 +8036,8 @@
   case CK_ZeroToOCLEvent:
   case CK_NonAtomicToAtomic:
   case CK_AddressSpaceConversion:
+  case CK_IntToOCLSamplerInitializer:
+  case CK_OCLSamplerInitializerToSampler:
     llvm_unreachable("invalid cast kind for integral value");
 
   case CK_BitCast:
@@ -8526,6 +8529,8 @@
   case CK_ZeroToOCLEvent:
   case CK_NonAtomicToAtomic:
   case CK_AddressSpaceConversion:
+  case CK_IntToOCLSamplerInitializer:
+  case CK_OCLSamplerInitializerToSampler:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_LValueToRValue:
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1570,6 +1570,8 @@
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
   case CK_ZeroToOCLEvent:
+  case CK_IntToOCLSamplerInitializer:
+  case CK_OCLSamplerInitializerToSampler:
     assert(!getType()->isBooleanType() && "unheralded conversion to bool");
     goto CheckNoBasePath;
 
@@ -2748,7 +2750,9 @@
         CE->getCastKind() == CK_ToUnion ||
         CE->getCastKind() == CK_ConstructorConversion ||
         CE->getCastKind() == CK_NonAtomicToAtomic ||
-        CE->getCastKind() == CK_AtomicToNonAtomic)
+        CE->getCastKind() == CK_AtomicToNonAtomic ||
+        CE->getCastKind() == CK_IntToOCLSamplerInitializer ||
+        CE->getCastKind() == CK_OCLSamplerInitializerToSampler)
       return CE->getSubExpr()->isConstantInitializer(Ctx, false, Culprit);
 
     break;
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -1091,6 +1091,7 @@
 #include "clang/Basic/OpenCLImageTypes.def"
 
     InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler);
+    InitBuiltinType(OCLSamplerInitTy, BuiltinType::OCLSamplerInit);
     InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
     InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent);
     InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
@@ -1661,11 +1662,18 @@
       Width = Target->getPointerWidth(0); 
       Align = Target->getPointerAlign(0);
       break;
-    case BuiltinType::OCLSampler:
-      // Samplers are modeled as integers.
-      Width = Target->getIntWidth();
-      Align = Target->getIntAlign();
+    case BuiltinType::OCLSampler: {
+      auto AS = getTargetAddressSpace(LangAS::opencl_constant);
+      Width = Target->getPointerWidth(AS);
+      Align = Target->getPointerAlign(AS);
       break;
+    }
+    case BuiltinType::OCLSamplerInit: {
+      auto AS = getTargetAddressSpace(LangAS::opencl_constant);
+      Width = Target->getPointerWidth(AS);
+      Align = Target->getPointerAlign(AS);
+      break;
+    }
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
@@ -5512,6 +5520,7 @@
     case BuiltinType::OCLNDRange:
     case BuiltinType::OCLReserveID:
     case BuiltinType::OCLSampler:
+    case BuiltinType::OCLSamplerInit:
     case BuiltinType::Dependent:
 #define BUILTIN_TYPE(KIND, ID)
 #define PLACEHOLDER_TYPE(KIND, ID) \
Index: include/clang/Serialization/ASTBitCodes.h
===================================================================
--- include/clang/Serialization/ASTBitCodes.h
+++ include/clang/Serialization/ASTBitCodes.h
@@ -796,6 +796,8 @@
       PREDEF_TYPE_OMP_ARRAY_SECTION = 43,
       /// \brief The '__float128' type
       PREDEF_TYPE_FLOAT128_ID = 44,
+      /// \brief Internal OpenCL sampler initializer type
+      PREDEF_TYPE_SAMPLER_INIT_ID = 45,
       /// \brief OpenCL image types with auto numeration
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
       PREDEF_TYPE_##Id##_ID,
Index: include/clang/Sema/Overload.h
===================================================================
--- include/clang/Sema/Overload.h
+++ include/clang/Sema/Overload.h
@@ -84,6 +84,7 @@
     ICK_Writeback_Conversion,  ///< Objective-C ARC writeback conversion
     ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10)
     ICK_C_Only_Conversion,     ///< Conversions allowed in C, but not C++
+    ICK_Sampler_Conversion,    ///< Sampler initializer to sampler for OpenCL
     ICK_Num_Conversion_Kinds,  ///< The number of conversion kinds
   };
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -7862,6 +7862,12 @@
   "the event_t type can only be used with __private address space qualifier">;
 def err_expected_kernel_void_return_type : Error<
   "kernel must have void return type">;
+def err_sampler_initializer_not_integer : Error<
+  "sampler_t initialization requires 32-bit integer, not %0">;
+def warn_sampler_initializer_invalid_bits : Warning<
+  "Sampler initializer has invalid %0 bits">, InGroup<SpirCompat>;
+def err_sampler_initializer_not_constant : Error<
+  "sampler_t initialization requires compile time constant">;
 def err_sampler_argument_required : Error<
   "sampler_t variable required - got %0">;
 def err_wrong_sampler_addressspace: Error<
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -871,3 +871,7 @@
 def OptionIgnored : DiagGroup<"option-ignored">;
 
 def UnknownArgument : DiagGroup<"unknown-argument">;
+
+// A warning group for warnings about code that clang accepts when
+// compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
+def SpirCompat : DiagGroup<"spir-compat">;
\ No newline at end of file
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1738,6 +1738,7 @@
   bool isImageType() const;                     // Any OpenCL image type
 
   bool isSamplerT() const;                      // OpenCL sampler_t
+  bool isSamplerInitT() const;                  // Internal sampler_init_t
   bool isEventT() const;                        // OpenCL event_t
   bool isClkEventT() const;                     // OpenCL clk_event_t
   bool isQueueT() const;                        // OpenCL queue_t
@@ -5597,6 +5598,10 @@
   return isSpecificBuiltinType(BuiltinType::OCLSampler);
 }
 
+inline bool Type::isSamplerInitT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLSamplerInit);
+}
+
 inline bool Type::isEventT() const {
   return isSpecificBuiltinType(BuiltinType::OCLEvent);
 }
@@ -5630,7 +5635,8 @@
 
 inline bool Type::isOpenCLSpecificType() const {
   return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
-         isQueueT() || isNDRangeT() || isReserveIDT() || isPipeType();
+         isQueueT() || isNDRangeT() || isReserveIDT() || isPipeType() ||
+         isSamplerInitT();
 }
 
 inline bool Type::isTemplateTypeParmType() const {
Index: include/clang/AST/OperationKinds.def
===================================================================
--- include/clang/AST/OperationKinds.def
+++ include/clang/AST/OperationKinds.def
@@ -324,6 +324,11 @@
 // Convert a pointer to a different address space.
 CAST_OPERATION(AddressSpaceConversion)
 
+// Convert an integer initializer to an OpenCL sampler initializer.
+CAST_OPERATION(IntToOCLSamplerInitializer)
+
+// Convert an OpenCL sampler initializer to OpenCL sampler.
+CAST_OPERATION(OCLSamplerInitializerToSampler)
 
 //===- Binary Operations  -------------------------------------------------===//
 // Operators listed in order of precedence.
Index: include/clang/AST/BuiltinTypes.def
===================================================================
--- include/clang/AST/BuiltinTypes.def
+++ include/clang/AST/BuiltinTypes.def
@@ -160,6 +160,9 @@
 // OpenCL sampler_t.
 BUILTIN_TYPE(OCLSampler, OCLSamplerTy)
 
+// Internal OpenCL sampler initializer type.
+BUILTIN_TYPE(OCLSamplerInit, OCLSamplerInitTy)
+
 // OpenCL event_t.
 BUILTIN_TYPE(OCLEvent, OCLEventTy)
 
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -906,7 +906,7 @@
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
   CanQualType SingletonId;
 #include "clang/Basic/OpenCLImageTypes.def"
-  CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
+  CanQualType OCLSamplerTy, OCLSamplerInitTy, OCLEventTy, OCLClkEventTy;
   CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
   CanQualType OMPArraySectionTy;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to