Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h	(revision 190056)
+++ include/clang/Basic/TargetInfo.h	(working copy)
@@ -354,11 +354,11 @@
   unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
 
   /// \brief Return the "preferred" register width on this target.
-  uint64_t getRegisterWidth() const {
+  unsigned getRegisterWidth() const {
     // Currently we assume the register width on the target matches the pointer
     // width, we can introduce a new variable for this if/when some target wants
     // it.
-    return LongWidth; 
+    return PointerWidth;
   }
 
   /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro,
Index: lib/Basic/TargetInfo.cpp
===================================================================
--- lib/Basic/TargetInfo.cpp	(revision 190056)
+++ lib/Basic/TargetInfo.cpp	(working copy)
@@ -232,6 +240,37 @@
     UseBitFieldTypeAlignment = false;
   if (Opts.ShortWChar)
     WCharType = UnsignedShort;
+
+#if 1
+  if (Opts.OpenCL) {
+    // OpenCL C requires specific widths for types, irrespective of
+    // what these normally are for the target.
+    // We also define long long and long double here, although the
+    // OpenCL standard only mentions these as "reserved".
+    IntWidth = IntAlign = 32;
+    LongWidth = LongAlign = 64;
+    LongLongWidth = LongLongAlign = 128;
+    HalfWidth = HalfAlign = 16;
+    FloatWidth = FloatAlign = 32;
+    DoubleWidth = DoubleAlign = 64;
+    LongDoubleWidth = LongDoubleAlign = 128;
+    
+    assert(PointerWidth == 32 || PointerWidth == 64);
+    bool is32BitArch = PointerWidth == 32;
+    SizeType = is32BitArch ? UnsignedInt : UnsignedLong;
+    PtrDiffType = is32BitArch ? SignedInt : SignedLong;
+    IntPtrType = is32BitArch ? SignedInt : SignedLong;
+    
+    IntMaxType = SignedLongLong;
+    UIntMaxType = UnsignedLongLong;
+    Int64Type = SignedLong;
+
+    HalfFormat = &llvm::APFloat::IEEEhalf;
+    FloatFormat = &llvm::APFloat::IEEEsingle;
+    DoubleFormat = &llvm::APFloat::IEEEdouble;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+  }
+#endif
 }
 
 //===----------------------------------------------------------------------===//
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp	(revision 190056)
+++ lib/Frontend/CompilerInvocation.cpp	(working copy)
@@ -1274,7 +1274,7 @@
   Opts.Blocks = Args.hasArg(OPT_fblocks);
   Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional);
   Opts.Modules = Args.hasArg(OPT_fmodules);
-  Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
+  Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char);
   Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar);
   Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
   Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
@@ -1285,7 +1285,7 @@
   Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
   Opts.AccessControl = !Args.hasArg(OPT_fno_access_control);
   Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
-  Opts.MathErrno = Args.hasArg(OPT_fmath_errno);
+  Opts.MathErrno = !Opts.OpenCL && Args.hasArg(OPT_fmath_errno);
   Opts.InstantiationDepth =
       getLastArgIntValue(Args, OPT_ftemplate_depth, 256, Diags);
   Opts.ConstexprCallDepth =
Index: test/CodeGenOpenCL/signed-char.cl
===================================================================
--- test/CodeGenOpenCL/signed-char.cl	(revision 0)
+++ test/CodeGenOpenCL/signed-char.cl	(working copy)
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+#define STATIC_ASSERT(x) { int a[(x) ? 1 : -1]; }
+
+void test1() {
+  STATIC_ASSERT((char)((char)0 - (char)1) < (char)0);
+}
Index: test/CodeGenOpenCL/type-sizes.cl
===================================================================
--- test/CodeGenOpenCL/type-sizes.cl	(revision 0)
+++ test/CodeGenOpenCL/type-sizes.cl	(working copy)
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+#pragma OPENCL EXTENSION cles_khr_int64 : enable
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+#define STATIC_ASSERT(x) { int a[(x) ? 1 : -1]; }
+
+void test1() {
+  STATIC_ASSERT(sizeof(char) == 1);
+  STATIC_ASSERT(sizeof(short) == 2);
+  STATIC_ASSERT(sizeof(int) == 4);
+  STATIC_ASSERT(sizeof(long) == 8);
+  // STATIC_ASSERT(sizeof(long long) == 16);
+  STATIC_ASSERT(sizeof(half) == 2);
+  STATIC_ASSERT(sizeof(float) == 4);
+  STATIC_ASSERT(sizeof(double) == 8);
+  // STATIC_ASSERT(sizeof(long double) == 16);
+}
