ソースを参照

Treat min10float and min12int as min16float and min16int in AST (#509)

Currently we had separate built in types for min10float and min12int types that will be promoted to min16float and min16int during codegen time. There can be a potential problem with this such as redefinition of functions with min10float or min16float as function parameters, but Sema cannot recognize their redefinitions. This change is to fix so that we promote these lower min precision types to higher min precision types on AST level so that we can easily handle errors.
Young Kim 8 年 前
コミット
93af33644e

+ 27 - 1
tools/clang/include/clang/AST/HlslTypes.h

@@ -421,6 +421,32 @@ bool TryParseVectorShorthand(
   _Out_     HLSLScalarType* parsedType,
   _Out_     int* elementCount);
 
-}
+_Success_(return != false)
+bool TryParseScalar(
+  _In_count_(typenameLen)
+  const char* typeName,
+  size_t typeNameLen,
+  _Out_     HLSLScalarType *parsedType
+);
+
+_Success_(return != false)
+bool TryParseAny(
+  _In_count_(typenameLen)
+  const char* typeName,
+  size_t typeNameLen,
+  _Out_ HLSLScalarType *parsedType,
+  _Out_ int *rowCount,
+  _Out_ int *colCount
+);
+
+_Success_(return != false)
+bool TryParseMatrixOrVectorDimension(
+  _In_count_(typeNameLen)
+  const char *typeName,
+  size_t typeNameLen,
+  _Out_opt_ int *rowCount,
+  _Out_opt_ int *colCount
+);
 
+} // end hlsl namespace
 #endif

+ 0 - 2
tools/clang/include/clang/Basic/TokenKinds.def

@@ -501,8 +501,6 @@ KEYWORD(precise                     , KEYHLSL)
 KEYWORD(shared                      , KEYHLSL)
 KEYWORD(groupshared                 , KEYHLSL)
 KEYWORD(discard                     , KEYHLSL)
-KEYWORD(min10float                  , KEYHLSL)
-KEYWORD(min12int                    , KEYHLSL)
 KEYWORD(snorm                       , KEYHLSL)
 KEYWORD(unorm                       , KEYHLSL)
 KEYWORD(point                       , KEYHLSL)

+ 1 - 0
tools/clang/include/clang/Sema/Sema.h

@@ -8987,6 +8987,7 @@ private:
 
   // HLSL Change Starts
   bool DiagnoseHLSLDecl(Declarator& D, DeclContext* DC, TypeSourceInfo* TInfo, bool isParameter);
+  bool DiagnoseHLSLLookup(const LookupResult &R);
   void TransferUnusualAttributes(Declarator& D, NamedDecl* NewDecl);
   // HLSL Change Ends
 

+ 177 - 48
tools/clang/lib/AST/ASTContextHLSL.cpp

@@ -50,7 +50,6 @@ static const bool VirtualFalse = false;           // whether the base class is d
 static const bool BaseClassFalse = false;         // whether the base class is declared as 'class' (vs. 'struct')
 
 /// <summary>Names of HLSLScalarType enumeration values, in matching order to HLSLScalarType.</summary>
-static
 const char* HLSLScalarTypeNames[] = {
   "<unknown>",
   "bool",
@@ -73,6 +72,105 @@ const char* HLSLScalarTypeNames[] = {
 
 static_assert(HLSLScalarTypeCount == _countof(HLSLScalarTypeNames), "otherwise scalar constants are not aligned");
 
+static HLSLScalarType FindScalarTypeByName(const char *typeName, const size_t typeLen) {
+  // skipped HLSLScalarType: unknown, literal int, literal float
+  switch (typeLen) {
+    case 3: // int
+      if (typeName[0] == 'i') {
+        if (strncmp(typeName, "int", 3))
+          break;
+        return HLSLScalarType_int;
+      }
+      break;
+    case 4: // bool, uint, half
+      if (typeName[0] == 'b') {
+        if (strncmp(typeName, "bool", 4))
+          break;
+        return HLSLScalarType_bool;
+      }
+      else if (typeName[0] == 'u') {
+        if (strncmp(typeName, "uint", 4))
+          break;
+        return HLSLScalarType_uint;
+      }
+      else if (typeName[0] == 'h') {
+        if (strncmp(typeName, "half", 4))
+          break;
+        return HLSLScalarType_half;
+      }
+      break;
+    case 5: // dword, float
+      if (typeName[0] == 'd') {
+        if (strncmp(typeName, "dword", 5))
+          break;
+        return HLSLScalarType_dword;
+      }
+      else if (typeName[0] == 'f') {
+        if (strncmp(typeName, "float", 5))
+          break;
+        return HLSLScalarType_float;
+      }
+      break;
+    case 6: // double
+      if (typeName[0] == 'd') {
+        if (strncmp(typeName, "double", 6))
+          break;
+        return HLSLScalarType_double;
+      }
+      break;
+    case 7: // int64_t
+      if (typeName[0] == 'i' && typeName[1] == 'n') {
+        if (strncmp(typeName, "int64_t", 7))
+          break;
+        return HLSLScalarType_int64;
+      }
+      break;
+    case 8: // min12int, min16int, uint64_t
+      if (typeName[0] == 'm' && typeName[1] == 'i') {
+        if (typeName[4] == '2') {
+          if (strncmp(typeName, "min12int", 8))
+            break;
+          return HLSLScalarType_int_min12;
+        }
+        else if (typeName[4] == '6') {
+          if (strncmp(typeName, "min16int", 8))
+            break;
+          return HLSLScalarType_int_min16;
+        }
+      }
+      if (typeName[0] == 'u' && typeName[1] == 'i') {
+        if (strncmp(typeName, "uint64_t", 8))
+          break;
+        return HLSLScalarType_uint64;
+      }
+      break;
+    case 9: // min16uint
+      if (typeName[0] == 'm' && typeName[1] == 'i') {
+        if (strncmp(typeName, "min16uint", 9))
+          break;
+        return HLSLScalarType_uint_min16;
+      }
+      break;
+    case 10: // min10float, min16float
+      if (typeName[0] == 'm' && typeName[1] == 'i') {
+        if (typeName[4] == '0') {
+          if (strncmp(typeName, "min10float", 10))
+            break;
+          return HLSLScalarType_float_min10;
+        }
+        if (typeName[4] == '6') {
+          if (strncmp(typeName, "min16float", 10))
+            break;
+          return HLSLScalarType_float_min16;
+        }
+      }
+      break;
+    default:
+      break;
+  }
+  return HLSLScalarType_unknown;
+}
+
 /// <summary>Provides the primitive type for lowering matrix types to IR.</summary>
 static
 CanQualType GetHLSLObjectHandleType(ASTContext& context)
@@ -791,34 +889,15 @@ bool hlsl::TryParseMatrixShorthand(
   // x is a literal 'x' character.
   // PrimitiveType is one of the HLSLScalarTypeNames values.
   //
-
-  // TODO: binary-search or build a switch table for type name of matrix identifiers
-
-  // At least *something*RxC characters necessary, where something is at least 'int'
-  const size_t MinValidLen = 3 + 3;
-  if (typeNameLen >= MinValidLen) {
-    // The trailing parts are less expensive to parse, so start with those.
-    if (TryParseColOrRowChar(typeName[typeNameLen - 1], colCount) &&
-      typeName[typeNameLen - 2] == 'x' &&
-      TryParseColOrRowChar(typeName[typeNameLen - 3], rowCount)) {
-      for (HLSLScalarType index = HLSLScalarType_minvalid;
-           index <= HLSLScalarType_max;
-           index = (HLSLScalarType)(index + 1)) {
-        // Shorten the compared character to make sure that the suffix isn't considered.
-        if (strncmp(HLSLScalarTypeNames[index], typeName, typeNameLen - 3) == 0) {
-          // Make sure the whole scalar type matches.
-          if (strlen(HLSLScalarTypeNames[index]) == typeNameLen - 3) {
-            *parsedType = index;
-            return true;
-          }
-          else {
-            return false;
-          }
-        }
-      }
+  if (TryParseMatrixOrVectorDimension(typeName, typeNameLen, rowCount, colCount) &&
+    *rowCount != 0 && *colCount != 0) {
+    // compare scalar component
+    HLSLScalarType type = FindScalarTypeByName(typeName, typeNameLen-3);
+    if (type!= HLSLScalarType_unknown) {
+      *parsedType = type;
+      return true;
     }
   }
-
   // Unable to parse.
   return false;
 }
@@ -832,32 +911,82 @@ bool hlsl::TryParseVectorShorthand(
   int* elementCount
   )
 {
-  // TODO: binary-search or build a switch table for type name of vector identifiers
-
   // At least *something*N characters necessary, where something is at least 'int'
-  const size_t MinValidLen = 1 + 3;
+  if (TryParseColOrRowChar(typeName[typeNameLen - 1], elementCount)) {
+    // compare scalar component
+    HLSLScalarType type = FindScalarTypeByName(typeName, typeNameLen-1);
+    if (type!= HLSLScalarType_unknown) {
+      *parsedType = type;
+      return true;
+    }
+  }
+  // Unable to parse.
+  return false;
+}
+
+/// <summary>Parses a hlsl scalar type (e.g min16float, uint3x4) </summary>
+_Use_decl_annotations_
+bool hlsl::TryParseScalar(
+  _In_count_(typenameLen)
+            const char* typeName,
+            size_t typeNameLen,
+  _Out_     HLSLScalarType *parsedType
+) {
+  HLSLScalarType type = FindScalarTypeByName(typeName, typeNameLen);
+  if (type!= HLSLScalarType_unknown) {
+    *parsedType = type;
+    return true;
+  }
+  return false; // unable to parse
+}
+
+/// <summary>Parse any (scalar, vector, matrix) hlsl types (e.g float, int3x4, uint2) </summary>
+_Use_decl_annotations_
+bool hlsl::TryParseAny(
+  _In_count_(typenameLen)
+  const char* typeName,
+  size_t typeNameLen,
+  _Out_ HLSLScalarType *parsedType,
+  int *rowCount,
+  int *colCount
+) {
+  // at least 'int'
+  const size_t MinValidLen = 3;
   if (typeNameLen >= MinValidLen) {
-    // The trailing part is less expensive to parse, so start with that.
-    if (TryParseColOrRowChar(typeName[typeNameLen - 1], elementCount)) {
-      for (HLSLScalarType index = HLSLScalarType_minvalid;
-        index <= HLSLScalarType_max;
-        index = (HLSLScalarType)(index + 1)) {
-        // Shorten the compared character to make sure that the suffix isn't considered.
-        if (strncmp(HLSLScalarTypeNames[index], typeName, typeNameLen - 1) == 0) {
-          // Make sure the whole scalar type matches.
-          if (strlen(HLSLScalarTypeNames[index]) == typeNameLen - 1) {
-            *parsedType = index;
-            return true;
-          }
-          else {
-            return false;
-          }
-        }
-      }
+    TryParseMatrixOrVectorDimension(typeName, typeNameLen, rowCount, colCount);
+    int suffixLen = *colCount == 0 ? 0 :
+                    *rowCount == 0 ? 1 : 3;
+    HLSLScalarType type = FindScalarTypeByName(typeName, typeNameLen-suffixLen);
+    if (type!= HLSLScalarType_unknown) {
+      *parsedType = type;
+      return true;
     }
   }
+  return false;
+}
 
-  // Unable to parse.
+/// <summary>Parse any kind of dimension for vector or matrix (e.g 4,3 in int4x3).
+/// If it's a matrix type, rowCount and colCount will be nonzero. If it's a vector type, colCount is 0.
+/// Otherwise both rowCount and colCount is 0. Returns true if either matrix or vector dimensions detected. </summary>
+_Use_decl_annotations_
+bool hlsl::TryParseMatrixOrVectorDimension(
+    _In_count_(typeNameLen)
+    const char *typeName,
+    size_t typeNameLen,
+    _Out_opt_ int *rowCount,
+    _Out_opt_ int *colCount
+) {
+  *rowCount = 0;
+  *colCount = 0;
+  size_t MinValidLen = 3; // at least int
+  if (typeNameLen > MinValidLen) {
+    if (TryParseColOrRowChar(typeName[typeNameLen - 1], colCount)) {
+      // Try parse matrix
+      if (typeName[typeNameLen - 2] == 'x')
+        TryParseColOrRowChar(typeName[typeNameLen - 3], rowCount);
+      return true;
+    }
+  }
   return false;
 }
 

+ 0 - 22
tools/clang/lib/Parse/ParseDecl.cpp

@@ -3882,19 +3882,6 @@ HLSLReservedKeyword:
                                      DiagID, Policy);
       break;
     // HLSL Change Starts
-    case tok::kw_min10float:
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_min10float, Loc, PrevSpec,
-                                     DiagID, Policy);
-      if (!isInvalid)
-        Diag(Tok, diag::warn_hlsl_minprecision_promotion) << "min10float" << "min16float";
-      break;
-    case tok::kw_min12int:
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_min12int, Loc, PrevSpec,
-                                     DiagID, Policy);
-      if (!isInvalid)
-        Diag(Tok, diag::warn_hlsl_minprecision_promotion) << "min12int" << "min16int";
-      break;
-    // HLSL Change Ends
     case tok::kw_half:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
                                      DiagID, Policy);
@@ -4970,11 +4957,6 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
     // enum-specifier
   case tok::kw_enum:
 
-    // HLSL Change Starts - HLSL types
-  case tok::kw_min10float:
-  case tok::kw_min12int:
-    // HLSL Change Ends
-
     // typedef-name
   case tok::annot_typename:
     return true;
@@ -5060,8 +5042,6 @@ bool Parser::isTypeSpecifierQualifier() {
   case tok::annot_typename:
 
     // HLSL Change Starts
-  case tok::kw_min10float:
-  case tok::kw_min12int:
   case tok::kw_column_major:
   case tok::kw_row_major:
   case tok::kw_snorm:
@@ -5168,8 +5148,6 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
   case tok::kw_noperspective:
   case tok::kw_sample:
   case tok::kw_centroid:
-  case tok::kw_min10float:
-  case tok::kw_min12int:
   case tok::kw_column_major:
   case tok::kw_row_major:
   case tok::kw_snorm:

+ 0 - 2
tools/clang/lib/Parse/ParseExpr.cpp

@@ -1212,8 +1212,6 @@ HLSLReservedKeyword:
   case tok::kw___int64:
   case tok::kw___int128:
   // HLSL Change Starts
-  case tok::kw_min10float:
-  case tok::kw_min12int:
   case tok::kw_column_major:
   case tok::kw_row_major:
   case tok::kw_snorm:

+ 0 - 10
tools/clang/lib/Parse/ParseExprCXX.cpp

@@ -1905,16 +1905,6 @@ HLSLReservedKeyword:
     if (getLangOpts().HLSL) { goto HLSLReservedKeyword; } // HLSL Change - reserved for HLSL
     DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy);
     break;
-    // HLSL Change Starts
-  case tok::kw_min10float:
-    DS.SetTypeSpecType(DeclSpec::TST_min10float, Loc, PrevSpec, DiagID, Policy);
-    Diag(Tok, diag::warn_hlsl_minprecision_promotion) << "min10float" << "min16float";
-    break;
-  case tok::kw_min12int:
-    DS.SetTypeSpecType(DeclSpec::TST_min12int, Loc, PrevSpec, DiagID, Policy);
-    Diag(Tok, diag::warn_hlsl_minprecision_promotion) << "min12int" << "min16int";
-    break;
-    // HLSL Change Ends
   case tok::kw_half:
     DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID, Policy);
     break;

+ 0 - 12
tools/clang/lib/Parse/ParseTentative.cpp

@@ -960,8 +960,6 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
   case tok::kw___int64:
   case tok::kw___int128:
   // HLSL Change Starts
-  case tok::kw_min10float:
-  case tok::kw_min12int:
   case tok::kw_column_major:
   case tok::kw_row_major:
   case tok::kw_snorm:
@@ -1457,10 +1455,6 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
   case tok::kw_long:
   case tok::kw___int64:
   case tok::kw___int128:
-  // HLSL Change Starts
-  case tok::kw_min10float:
-  case tok::kw_min12int:
-  // HLSL Change Ends
   case tok::kw_signed:
   case tok::kw_unsigned:
   case tok::kw_half:
@@ -1561,12 +1555,6 @@ bool Parser::isCXXDeclarationSpecifierAType() {
   case tok::kw___unknown_anytype:
     return true;
 
-  // HLSL Change Starts
-  case tok::kw_min10float:
-  case tok::kw_min12int:
-    return true;
-  // HLSL Change Ends
-
   case tok::kw_auto:
     return getLangOpts().CPlusPlus11;
 

+ 0 - 6
tools/clang/lib/Sema/SemaDecl.cpp

@@ -114,12 +114,6 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
   case tok::kw___underlying_type:
     return true;
 
-  // HLSL Change Starts
-  case tok::kw_min10float:
-  case tok::kw_min12int:
-    return true;
-  // HLSL Change Ends
-
   case tok::annot_typename:
   case tok::kw_char16_t:
   case tok::kw_char32_t:

+ 129 - 56
tools/clang/lib/Sema/SemaHLSL.cpp

@@ -622,6 +622,8 @@ using namespace clang;
 using namespace clang::sema;
 using namespace hlsl;
 
+extern const char *HLSLScalarTypeNames[];
+
 static const int FirstTemplateDepth = 0;
 static const int FirstParamPosition = 0;
 static const bool ExplicitConversionFalse = false;// a conversion operation is not the result of an explicit cast
@@ -2379,6 +2381,22 @@ namespace hlsl {
   };
 }
 
+/// <summary>Creates a Typedef in the specified ASTContext.</summary>
+static
+TypedefDecl *CreateGlobalTypedef(ASTContext* context, const char* ident, QualType baseType)
+{
+  DXASSERT_NOMSG(context != nullptr);
+  DXASSERT_NOMSG(ident != nullptr);
+  DXASSERT_NOMSG(!baseType.isNull());
+
+  DeclContext* declContext = context->getTranslationUnitDecl();
+  TypeSourceInfo* typeSource = context->getTrivialTypeSourceInfo(baseType);
+  TypedefDecl* decl = TypedefDecl::Create(*context, declContext, NoLoc, NoLoc, &context->Idents.get(ident), typeSource);
+  declContext->addDecl(decl);
+  decl->setImplicit(true);
+  return decl;
+}
+
 class HLSLExternalSource : public ExternalSemaSource {
 private:
   // Inner types.
@@ -2410,6 +2428,9 @@ private:
   // Scalar types indexed by HLSLScalarType.
   QualType m_scalarTypes[HLSLScalarTypeCount];
 
+  // Scalar types already built.
+  TypedefDecl* m_scalarTypeDefs[HLSLScalarTypeCount];
+
   // Matrix types already built indexed by type, row-count, col-count. Should probably move to a sparse map. Instrument to figure out best initial size.
   QualType m_matrixTypes[HLSLScalarTypeCount][4][4];
 
@@ -2420,6 +2441,9 @@ private:
   QualType m_vectorTypes[HLSLScalarTypeCount][4];
   TypedefDecl* m_vectorTypedefs[HLSLScalarTypeCount][4];
 
+  // BuiltinType for each scalar type.
+  QualType m_baseTypes[HLSLScalarTypeCount];
+
   // Built-in object types declarations, indexed by basic kind constant.
   CXXRecordDecl* m_objectTypeDecls[_countof(g_ArBasicKindsAsTypes)];
   // Map from object decl to the object index.
@@ -2430,6 +2454,9 @@ private:
 
   UsedIntrinsicStore m_usedIntrinsics;
 
+  /// <summary>Add all base QualTypes for each hlsl scalar types.</summary>
+  void AddBaseTypes();
+
   /// <summary>Adds all supporting declarations to reference scalar types.</summary>
   void AddHLSLScalarTypes();
 
@@ -2913,8 +2940,7 @@ private:
                    colCount >= 0 && colCount <= 4);
     TypedefDecl *qts = m_vectorTypedefs[scalarType][colCount - 1];
     if (qts == nullptr) {
-
-        QualType type = LookupVectorType(scalarType, colCount);
+      QualType type = LookupVectorType(scalarType, colCount);
       qts = CreateVectorSpecializationShorthand(*m_context, type, scalarType,
                                                 colCount);
       m_vectorTypedefs[scalarType][colCount - 1] = qts;
@@ -2933,6 +2959,9 @@ public:
     memset(m_matrixShorthandTypes, 0, sizeof(m_matrixShorthandTypes));
     memset(m_vectorTypes, 0, sizeof(m_vectorTypes));
     memset(m_vectorTypedefs, 0, sizeof(m_vectorTypedefs));
+    memset(m_scalarTypes, 0, sizeof(m_scalarTypes));
+    memset(m_scalarTypeDefs, 0, sizeof(m_scalarTypeDefs));
+    memset(m_baseTypes, 0, sizeof(m_baseTypes));
   }
 
   ~HLSLExternalSource() { }
@@ -2969,10 +2998,23 @@ public:
     return m_sema;
   }
 
+  TypedefDecl* LookupScalarType(HLSLScalarType scalarType) {
+    if (m_scalarTypes[scalarType].isNull()) {
+      m_scalarTypeDefs[scalarType] = CreateGlobalTypedef(m_context, HLSLScalarTypeNames[scalarType], m_baseTypes[scalarType]);
+      m_scalarTypes[scalarType] = m_context->getTypeDeclType(m_scalarTypeDefs[scalarType]);
+    }
+    DXASSERT(m_scalarTypeDefs[scalarType], "Otherwise we did not build scalar types correctly.");
+    return m_scalarTypeDefs[scalarType];
+  }
+
   QualType LookupMatrixType(HLSLScalarType scalarType, unsigned int rowCount, unsigned int colCount)
   {
     QualType qt = m_matrixTypes[scalarType][rowCount - 1][colCount - 1];
     if (qt.isNull()) {
+      // lazy initialization of scalar types 
+      if (m_scalarTypes[scalarType].isNull()) {
+        LookupScalarType(scalarType);
+      }
       qt = GetOrCreateMatrixSpecialization(*m_context, m_sema, m_matrixTemplateDecl, m_scalarTypes[scalarType], rowCount, colCount);
       m_matrixTypes[scalarType][rowCount - 1][colCount - 1] = qt;
     }
@@ -2983,12 +3025,39 @@ public:
   {
     QualType qt = m_vectorTypes[scalarType][colCount - 1];
     if (qt.isNull()) {
+      if (m_scalarTypes[scalarType].isNull()) {
+        LookupScalarType(scalarType);
+      }
       qt = GetOrCreateVectorSpecialization(*m_context, m_sema, m_vectorTemplateDecl, m_scalarTypes[scalarType], colCount);
       m_vectorTypes[scalarType][colCount - 1] = qt;
     }
     return qt;
   }
 
+  void WarnMinPrecision(HLSLScalarType type, SourceLocation loc) {
+    // TODO: enalbe this once we introduce precise master option
+    bool isMinPrecisionAllowed = true;
+    if (type == HLSLScalarType_int_min12) {
+      const char *PromotedType = isMinPrecisionAllowed? "min16int" : "int16";
+      m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion) << "min12int" << PromotedType;
+    }
+    else if (type == HLSLScalarType_float_min10) {
+      const char *PromotedType =  isMinPrecisionAllowed? "min16float" : "half";
+      m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion) << "min10float" << PromotedType;
+    }
+    if (!isMinPrecisionAllowed) {
+      if (type == HLSLScalarType_float_min16) {
+        m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion) << "min16float" << "half";
+      }
+      else if (type == HLSLScalarType_int_min16) {
+        m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion) << "min16int" << "int16";
+      }
+      else if (type == HLSLScalarType_uint_min16) {
+        m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion) << "min16uint" << "uint16";
+      }
+    }
+  }
+
   bool LookupUnqualified(LookupResult &R, Scope *S) override
   {
     const DeclarationNameInfo declName = R.getLookupNameInfo();
@@ -3008,32 +3077,26 @@ public:
     HLSLScalarType parsedType;
     int rowCount;
     int colCount;
-    if (TryParseMatrixShorthand(nameIdentifier.data(), nameIdentifier.size(), &parsedType, &rowCount, &colCount)) {
-      assert(parsedType != HLSLScalarType_unknown && "otherwise, TryParseMatrixShorthand should not have succeeded");
-      QualType qt = LookupMatrixType(parsedType, rowCount, colCount);
-      if (parsedType == HLSLScalarType_int_min12)
-        m_sema->Diag(R.getNameLoc(), diag::warn_hlsl_sema_minprecision_promotion) << "min12int" << "min16int";
-      else if (parsedType == HLSLScalarType_float_min10)
-        m_sema->Diag(R.getNameLoc(), diag::warn_hlsl_sema_minprecision_promotion) << "min10float" << "min16float";
-
-      TypedefDecl* qts = LookupMatrixShorthandType(parsedType, rowCount, colCount);
-
-      R.addDecl(qts);
-      return true;
-    } else if (TryParseVectorShorthand(nameIdentifier.data(), nameIdentifier.size(), &parsedType, &colCount)) {
-      assert(parsedType != HLSLScalarType_unknown && "otherwise, TryParseVectorShorthand should not have succeeded");
-      QualType qt = LookupVectorType(parsedType, colCount);
-      if (parsedType == HLSLScalarType_int_min12)
-        m_sema->Diag(R.getNameLoc(), diag::warn_hlsl_sema_minprecision_promotion) << "min12int" << "min16int";
-      else if (parsedType == HLSLScalarType_float_min10)
-        m_sema->Diag(R.getNameLoc(), diag::warn_hlsl_sema_minprecision_promotion) << "min10float" << "min16float";
-
-      TypedefDecl *qts = LookupVectorShorthandType(parsedType, colCount);
 
-      R.addDecl(qts);
+    // Try parsing hlsl scalar types that is not initialized at AST time.
+    if (TryParseAny(nameIdentifier.data(), nameIdentifier.size(), &parsedType, &rowCount, &colCount)) {
+      assert(parsedType != HLSLScalarType_unknown && "otherwise, TryParseHLSLScalarType should not have succeeded.");
+      if (rowCount == 0 && colCount == 0) { // scalar
+        TypedefDecl *typeDecl = LookupScalarType(parsedType);
+        R.addDecl(typeDecl);
+      }
+      else if (rowCount == 0) { // vector
+        QualType qt = LookupVectorType(parsedType, colCount);
+        TypedefDecl *qts = LookupVectorShorthandType(parsedType, colCount);
+        R.addDecl(qts);
+      }
+      else { // matrix
+        QualType qt = LookupMatrixType(parsedType, rowCount, colCount);
+        TypedefDecl* qts = LookupMatrixShorthandType(parsedType, rowCount, colCount);
+        R.addDecl(qts);
+      }
       return true;
     }
-
     return false;
   }
 
@@ -3603,7 +3666,7 @@ public:
                                SourceLocation(), &context.Idents.get("hlsl"),
                                /*PrevDecl*/ nullptr);
     m_hlslNSDecl->setImplicit();
-
+    AddBaseTypes();
     AddHLSLScalarTypes();
 
     AddHLSLVectorTemplate(*m_context, &m_vectorTemplateDecl);
@@ -4350,42 +4413,36 @@ QualType GetFirstElementType(QualType type)
   return QualType();
 }
 
-/// <summary>Creates a Typedef in the specified ASTContext.</summary>
-static
-QualType CreateGlobalTypedef(ASTContext* context, const char* ident, QualType baseType)
+void HLSLExternalSource::AddBaseTypes()
 {
-  DXASSERT_NOMSG(context != nullptr);
-  DXASSERT_NOMSG(ident != nullptr);
-  DXASSERT_NOMSG(!baseType.isNull());
-
-  DeclContext* declContext = context->getTranslationUnitDecl();
-  TypeSourceInfo* typeSource = context->getTrivialTypeSourceInfo(baseType);
-  TypedefDecl* decl = TypedefDecl::Create(*context, declContext, NoLoc, NoLoc, &context->Idents.get(ident), typeSource);
-  declContext->addDecl(decl);
-  decl->setImplicit(true);
-  return context->getTypeDeclType(decl);
+  DXASSERT(m_baseTypes[HLSLScalarType_unknown].isNull(), "otherwise unknown was initialized to an actual type");
+  m_baseTypes[HLSLScalarType_bool] = m_context->BoolTy;
+  m_baseTypes[HLSLScalarType_int] = m_context->IntTy;
+  m_baseTypes[HLSLScalarType_uint] = m_context->UnsignedIntTy;
+  m_baseTypes[HLSLScalarType_dword] = m_context->UnsignedIntTy;
+  m_baseTypes[HLSLScalarType_half] = m_context->FloatTy;
+  m_baseTypes[HLSLScalarType_float] = m_context->FloatTy;
+  m_baseTypes[HLSLScalarType_double] = m_context->DoubleTy;
+  m_baseTypes[HLSLScalarType_float_min10] = m_context->HalfTy;
+  m_baseTypes[HLSLScalarType_float_min16] = m_context->HalfTy;
+  m_baseTypes[HLSLScalarType_int_min12] = m_context->ShortTy;
+  m_baseTypes[HLSLScalarType_int_min16] = m_context->ShortTy;
+  m_baseTypes[HLSLScalarType_uint_min16] = m_context->UnsignedShortTy;
+  m_baseTypes[HLSLScalarType_float_lit] = m_context->LitFloatTy;
+  m_baseTypes[HLSLScalarType_int_lit] = m_context->LitIntTy;
+  m_baseTypes[HLSLScalarType_int64] = m_context->LongLongTy;
+  m_baseTypes[HLSLScalarType_uint64] = m_context->UnsignedLongLongTy;
 }
 
 void HLSLExternalSource::AddHLSLScalarTypes()
 {
   DXASSERT(m_scalarTypes[HLSLScalarType_unknown].isNull(), "otherwise unknown was initialized to an actual type");
-
-  m_scalarTypes[HLSLScalarType_bool] = m_context->BoolTy;
-  m_scalarTypes[HLSLScalarType_int] = m_context->IntTy;
-  m_scalarTypes[HLSLScalarType_uint] = CreateGlobalTypedef(m_context, "uint", m_context->UnsignedIntTy);
-  m_scalarTypes[HLSLScalarType_dword] = CreateGlobalTypedef(m_context, "dword", m_context->UnsignedIntTy);
-  m_scalarTypes[HLSLScalarType_half] = CreateGlobalTypedef(m_context, "half", m_context->FloatTy);
-  m_scalarTypes[HLSLScalarType_float] = m_context->FloatTy;
-  m_scalarTypes[HLSLScalarType_double] = m_context->DoubleTy;
-  m_scalarTypes[HLSLScalarType_float_min10] = m_context->Min10FloatTy;
-  m_scalarTypes[HLSLScalarType_float_min16] = CreateGlobalTypedef(m_context, "min16float", m_context->HalfTy);
-  m_scalarTypes[HLSLScalarType_int_min12] = m_context->Min12IntTy;
-  m_scalarTypes[HLSLScalarType_int_min16] = CreateGlobalTypedef(m_context, "min16int", m_context->ShortTy);
-  m_scalarTypes[HLSLScalarType_uint_min16] = CreateGlobalTypedef(m_context, "min16uint", m_context->UnsignedShortTy);
-  m_scalarTypes[HLSLScalarType_float_lit] = m_context->LitFloatTy;
-  m_scalarTypes[HLSLScalarType_int_lit] = m_context->LitIntTy;
-  m_scalarTypes[HLSLScalarType_int64] = CreateGlobalTypedef(m_context, "int64_t", m_context->LongLongTy);
-  m_scalarTypes[HLSLScalarType_uint64] = CreateGlobalTypedef(m_context, "uint64_t", m_context->UnsignedLongLongTy);
+  m_scalarTypes[HLSLScalarType_bool] = m_baseTypes[HLSLScalarType_bool];
+  m_scalarTypes[HLSLScalarType_int] = m_baseTypes[HLSLScalarType_int];
+  m_scalarTypes[HLSLScalarType_float] = m_baseTypes[HLSLScalarType_float];
+  m_scalarTypes[HLSLScalarType_double] = m_baseTypes[HLSLScalarType_double];
+  m_scalarTypes[HLSLScalarType_float_lit] = m_baseTypes[HLSLScalarType_float_lit];
+  m_scalarTypes[HLSLScalarType_int_lit] = m_baseTypes[HLSLScalarType_int_lit];
 }
 
 FunctionDecl* HLSLExternalSource::AddSubscriptSpecialization(
@@ -10778,6 +10835,22 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
   return result;
 }
 
+// Diagnose HLSL types on lookup
+bool Sema::DiagnoseHLSLLookup(const LookupResult &R) {
+  const DeclarationNameInfo declName = R.getLookupNameInfo();
+  IdentifierInfo* idInfo = declName.getName().getAsIdentifierInfo();
+  if (idInfo) {
+    StringRef nameIdentifier = idInfo->getName();
+    HLSLScalarType parsedType;
+    int rowCount, colCount;
+    if (TryParseAny(nameIdentifier.data(), nameIdentifier.size(), &parsedType, &rowCount, &colCount)) {
+      HLSLExternalSource *hlslExternalSource = HLSLExternalSource::FromSema(this);
+      hlslExternalSource->WarnMinPrecision(parsedType, R.getNameLoc());
+    }
+  }
+  return true;
+}
+
 static QualType getUnderlyingType(QualType Type)
 {
   while (const TypedefType *TD = dyn_cast<TypedefType>(Type))

+ 4 - 1
tools/clang/lib/Sema/SemaTemplate.cpp

@@ -309,7 +309,10 @@ void Sema::LookupTemplateName(LookupResult &Found,
   } else {
     // Perform unqualified name lookup in the current scope.
     LookupName(Found, S);
-    
+    // HLSL Change: Diagnose on lookup level. Currently this is used to throw warnings for minprecision promotion
+    if (getLangOpts().HLSL)
+      DiagnoseHLSLLookup(Found);
+    // HLSL Change End
     if (!ObjectType.isNull())
       AllowFunctionTemplatesInLookup = false;
   }

+ 23 - 8
tools/clang/test/HLSL/functions.hlsl

@@ -62,19 +62,19 @@ float_arr_2 arr_return() {
 #endif
 
 bool fn_bool() {
-  float a [ 2 ] ; 
-  a [ 0 ] = 1 - 2 ; 
-  a [ 1 ] = 2 + 3 ; 
-  float b1 , b2 ; 
+  float a [ 2 ] ;
+  a [ 0 ] = 1 - 2 ;
+  a [ 1 ] = 2 + 3 ;
+  float b1 , b2 ;
   b1 = min(a[0], a[1]);
   b2 = max(a[0], a[1]);
-  return ( a [ 1 ] < b1 || b2 < a [ 0 ] ) ; 
+  return ( a [ 1 ] < b1 || b2 < a [ 0 ] ) ;
 }
 
 struct Texture2DArrayFloat {
   Texture2DArray<float> tex;
   SamplerState smp;
-  
+
   float SampleLevel(float2 coord, float arrayIndex, float level)
   {
     return tex.SampleLevel(smp, float3 (coord, arrayIndex), level);
@@ -219,6 +219,21 @@ void fn_uint_oload3(uint u) { }
 void fn_uint_oload3(inout uint u) { }
 void fn_uint_oload3(out uint u) { }
 
+// function redefinitions
+void fn_redef(min10float x) {}      /* expected-note {{previous definition is here}} expected-warning {{min10float is promoted to min16float}} */
+void fn_redef(min16float x) {}      /* expected-error {{redefinition of 'fn_redef'}} */
+
+
+void fn_redef2(min12int x) {}       /* expected-note {{previous definition is here}} expected-warning {{min12int is promoted to min16int}} */
+void fn_redef2(min16int x) {}       /* expected-error {{redefinition of 'fn_redef2'}} */
+
+void fn_redef3(half x) {}           /* expected-note {{previous definition is here}} */
+void fn_redef3(float x) {}          /* expected-error {{redefinition of 'fn_redef3'}} */
+
+typedef min16int My16Int;
+void fn_redef4(min16int x) {}       /* expected-note {{previous definition is here}} */
+void fn_redef4(My16Int x) {}        /* expected-error {{redefinition of 'fn_redef4'}} */
+
 void inout_calls() {
   uint u = 1;
 
@@ -255,7 +270,7 @@ void cs_main() {
   fn_float_arr(arr2);
 
   fn_inout_separate(f2);
-  
+
   f2 = arr2[0];
   f2 = arr2[arr2[0]];
   f2 = 0[arr2]; // expected-error {{HLSL does not support having the base of a subscript operator in brackets}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
@@ -271,4 +286,4 @@ void cs_main() {
 
   fn_float_arr_out(arr2);
   // arr2 = arr_return();
-}
+}

+ 1 - 1
tools/clang/test/HLSL/matrix-syntax.hlsl

@@ -72,7 +72,7 @@ void matrix_unsigned() {
    unsigned bool3x4 boolvector;   /* expected-error {{'bool' cannot be signed or unsigned}} fxc-error {{X3085: unsigned can not be used with type}} */
    unsigned half4x1 halfvector;   /* expected-error {{'float' cannot be signed or unsigned}} fxc-error {{X3085: unsigned can not be used with type}} */
    unsigned double1x2 doublevector;                           /* expected-error {{'double' cannot be signed or unsigned}} fxc-error {{X3085: unsigned can not be used with type}} */
-   unsigned min12int2x3 min12intvector;                       /* expected-error {{'min12int' cannot be signed or unsigned}} expected-warning {{min12int is promoted to min16int}} fxc-error {{X3085: unsigned can not be used with type}} */
+   unsigned min12int2x3 min12intvector;                       /* expected-warning {{min12int is promoted to min16int}} fxc-error {{X3085: unsigned can not be used with type}} */
    unsigned min16float3x4 min16floatvector;                   /* expected-error {{'min16float' cannot be signed or unsigned}} fxc-error {{X3085: unsigned can not be used with type}} */
 
 }

+ 10 - 10
tools/clang/test/HLSL/more-operators.hlsl

@@ -201,7 +201,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
     _Static_assert(std::is_same<int2, __decltype(-bool2_l)>::value, "");
     _Static_assert(std::is_same<float3, __decltype(-float3_l)>::value, "");
     _Static_assert(std::is_same<double4, __decltype(-double4_l)>::value, "");
-    _Static_assert(std::is_same<min10float1x2, __decltype(-min10float1x2_l)>::value, "");  
+    _Static_assert(std::is_same<min10float1x2, __decltype(-min10float1x2_l)>::value, "");      /* expected-warning {{min10float is promoted to min16float}} */
     _Static_assert(std::is_same<uint2x3, __decltype(-uint2x3_l)>::value, "");
     _Static_assert(std::is_same<min16uint4x4, __decltype(-min16uint4x4_l)>::value, "");
     _Static_assert(std::is_same<int3x2, __decltype(-int3x2_l)>::value, "");
@@ -223,7 +223,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
     _Static_assert(std::is_same<int2, __decltype(+bool2_l)>::value, "");
     _Static_assert(std::is_same<float3, __decltype(+float3_l)>::value, "");
     _Static_assert(std::is_same<double4, __decltype(+double4_l)>::value, "");
-    _Static_assert(std::is_same<min10float1x2, __decltype(+min10float1x2_l)>::value, "");  
+    _Static_assert(std::is_same<min10float1x2, __decltype(+min10float1x2_l)>::value, "");      /* expected-warning {{min10float is promoted to min16float}} */
     _Static_assert(std::is_same<uint2x3, __decltype(+uint2x3_l)>::value, "");
     _Static_assert(std::is_same<min16uint4x4, __decltype(+min16uint4x4_l)>::value, "");
     _Static_assert(std::is_same<int3x2, __decltype(+int3x2_l)>::value, "");
@@ -287,11 +287,11 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
     _Static_assert(std::is_same<double, __decltype(double_l--)>::value, "");
     _Static_assert(std::is_same<min16float&, __decltype(--min16float_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<min16float, __decltype(min16float_l--)>::value, "");
-    _Static_assert(std::is_same<min10float&, __decltype(--min10float_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}} expected-warning {{min10float is promoted to min16float}}
+    _Static_assert(std::is_same<min10float&, __decltype(--min10float_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} expected-warning {{min10float is promoted to min16float}} fxc-pass {{}}
     _Static_assert(std::is_same<min10float, __decltype(min10float_l--)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
     _Static_assert(std::is_same<min16int&, __decltype(--min16int_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<min16int, __decltype(min16int_l--)>::value, "");
-    _Static_assert(std::is_same<min12int&, __decltype(--min12int_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}  expected-warning {{min12int is promoted to min16int}}
+    _Static_assert(std::is_same<min12int&, __decltype(--min12int_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} expected-warning {{min12int is promoted to min16int}} fxc-pass {{}}
     _Static_assert(std::is_same<min12int, __decltype(min12int_l--)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
     _Static_assert(std::is_same<min16uint&, __decltype(--min16uint_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<min16uint, __decltype(min16uint_l--)>::value, "");
@@ -309,8 +309,8 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
     _Static_assert(std::is_same<float3, __decltype(float3_l--)>::value, "");
     _Static_assert(std::is_same<double4&, __decltype(--double4_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<double4, __decltype(double4_l--)>::value, "");
-    _Static_assert(std::is_same<min10float1x2&, __decltype(--min10float1x2_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
-    _Static_assert(std::is_same<min10float1x2, __decltype(min10float1x2_l--)>::value, "");  
+    _Static_assert(std::is_same<min10float1x2&, __decltype(--min10float1x2_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} expected-warning {{min10float is promoted to min16float}} fxc-pass {{}}
+    _Static_assert(std::is_same<min10float1x2, __decltype(min10float1x2_l--)>::value, "");      /* expected-warning {{min10float is promoted to min16float}} */
     _Static_assert(std::is_same<uint2x3&, __decltype(--uint2x3_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<uint2x3, __decltype(uint2x3_l--)>::value, "");
     _Static_assert(std::is_same<min16uint4x4&, __decltype(--min16uint4x4_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
@@ -331,11 +331,11 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
     _Static_assert(std::is_same<double, __decltype(double_l++)>::value, "");
     _Static_assert(std::is_same<min16float&, __decltype(++min16float_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<min16float, __decltype(min16float_l++)>::value, "");
-    _Static_assert(std::is_same<min10float&, __decltype(++min10float_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}} expected-warning {{min10float is promoted to min16float}}
+    _Static_assert(std::is_same<min10float&, __decltype(++min10float_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} expected-warning {{min10float is promoted to min16float}} fxc-pass {{}}
     _Static_assert(std::is_same<min10float, __decltype(min10float_l++)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
     _Static_assert(std::is_same<min16int&, __decltype(++min16int_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<min16int, __decltype(min16int_l++)>::value, "");
-    _Static_assert(std::is_same<min12int&, __decltype(++min12int_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}} expected-warning {{min12int is promoted to min16int}}
+    _Static_assert(std::is_same<min12int&, __decltype(++min12int_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} expected-warning {{min12int is promoted to min16int}} fxc-pass {{}}
     _Static_assert(std::is_same<min12int, __decltype(min12int_l++)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
     _Static_assert(std::is_same<min16uint&, __decltype(++min16uint_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<min16uint, __decltype(min16uint_l++)>::value, "");
@@ -353,8 +353,8 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
     _Static_assert(std::is_same<float3, __decltype(float3_l++)>::value, "");
     _Static_assert(std::is_same<double4&, __decltype(++double4_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<double4, __decltype(double4_l++)>::value, "");
-    _Static_assert(std::is_same<min10float1x2&, __decltype(++min10float1x2_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
-    _Static_assert(std::is_same<min10float1x2, __decltype(min10float1x2_l++)>::value, ""); 
+    _Static_assert(std::is_same<min10float1x2&, __decltype(++min10float1x2_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} expected-warning {{min10float is promoted to min16float}} fxc-pass {{}}
+    _Static_assert(std::is_same<min10float1x2, __decltype(min10float1x2_l++)>::value, "");  /* expected-warning {{min10float is promoted to min16float}} */
     _Static_assert(std::is_same<uint2x3&, __decltype(++uint2x3_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}
     _Static_assert(std::is_same<uint2x3, __decltype(uint2x3_l++)>::value, "");
     _Static_assert(std::is_same<min16uint4x4&, __decltype(++min16uint4x4_l)>::value, ""); // expected-error {{pointers are unsupported in HLSL}} fxc-pass {{}}

+ 7 - 7
tools/clang/test/HLSL/scalar-assignments.hlsl

@@ -133,11 +133,11 @@ min10float left99; dword right99; left99 = right99; // expected-warning {{conver
 min10float left100; half right100; left100 = right100; // expected-warning {{conversion from larger type 'half' to smaller type 'min10float', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
 min10float left101; float right101; left101 = right101; // expected-warning {{conversion from larger type 'float' to smaller type 'min10float', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
 min10float left102; double right102; left102 = right102; // expected-warning {{conversion from larger type 'double' to smaller type 'min10float', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
-min10float left103; min16float right103; left103 = right103; // expected-warning {{conversion from larger type 'min16float' to smaller type 'min10float', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
+min10float left103; min16float right103; left103 = right103; // fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
 min10float left104; min10float right104; left104 = right104;  // expected-warning {{min10float is promoted to min16float}} // expected-warning {{min10float is promoted to min16float}}
-min10float left105; min16int right105; left105 = right105; // expected-warning {{conversion from larger type 'min16int' to smaller type 'min10float', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
-min10float left106; min12int right106; left106 = right106; // expected-warning {{min12int is promoted to min16int}} expected-warning {{conversion from larger type 'min12int' to smaller type 'min10float', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
-min10float left107; min16uint right107; left107 = right107; // expected-warning {{conversion from larger type 'min16uint' to smaller type 'min10float', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
+min10float left105; min16int right105; left105 = right105; // fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
+min10float left106; min12int right106; left106 = right106; // expected-warning {{min12int is promoted to min16int}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
+min10float left107; min16uint right107; left107 = right107; // fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}} // expected-warning {{min10float is promoted to min16float}}
 min16int left108; bool right108; left108 = right108;
 min16int left109; int right109; left109 = right109; // expected-warning {{conversion from larger type 'int' to smaller type 'min16int', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
 min16int left110; uint right110; left110 = right110; // expected-warning {{conversion from larger type 'uint' to smaller type 'min16int', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
@@ -157,11 +157,11 @@ min12int left123; dword right123; left123 = right123; // expected-warning {{conv
 min12int left124; half right124; left124 = right124; // expected-warning {{conversion from larger type 'half' to smaller type 'min12int', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
 min12int left125; float right125; left125 = right125; // expected-warning {{conversion from larger type 'float' to smaller type 'min12int', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
 min12int left126; double right126; left126 = right126; // expected-warning {{conversion from larger type 'double' to smaller type 'min12int', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
-min12int left127; min16float right127; left127 = right127; // expected-warning {{conversion from larger type 'min16float' to smaller type 'min12int', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
+min12int left127; min16float right127; left127 = right127; // fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
 min12int left128; min10float right128; left128 = right128;  // expected-warning {{min10float is promoted to min16float}}  // expected-warning {{min12int is promoted to min16int}}
-min12int left129; min16int right129; left129 = right129; // expected-warning {{conversion from larger type 'min16int' to smaller type 'min12int', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
+min12int left129; min16int right129; left129 = right129; // fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
 min12int left130; min12int right130; left130 = right130;  // expected-warning {{min12int is promoted to min16int}}  // expected-warning {{min12int is promoted to min16int}}
-min12int left131; min16uint right131; left131 = right131; // expected-warning {{conversion from larger type 'min16uint' to smaller type 'min12int', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
+min12int left131; min16uint right131; left131 = right131; // fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}  // expected-warning {{min12int is promoted to min16int}}
 min16uint left132; bool right132; left132 = right132;
 min16uint left133; int right133; left133 = right133; // expected-warning {{conversion from larger type 'int' to smaller type 'min16uint', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
 min16uint left134; uint right134; left134 = right134; // expected-warning {{conversion from larger type 'uint' to smaller type 'min16uint', possible loss of data}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}

+ 30 - 164
tools/clang/test/HLSL/scalar-operators-assign.hlsl

@@ -31,21 +31,19 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
     float       floats      = 0;
     double      doubles     = 0;
     min16float  min16floats = 0;
-    min10float  min10floats = 0;  // expected-warning {{min10float is promoted to min16float}}
-    min16int    min16ints   = 0;
-    min12int    min12ints   = 0;  // expected-warning {{min12int is promoted to min16int}}
-    min16uint   min16uints  = 0;
-  
+    min10float  min10floats = 0;    min16int    min16ints   = 0;
+    min12int    min12ints   = 0;    min16uint   min16uints  = 0;
+
   //
   // Some error messages were changed from the fxc version to ease generating test cases
-  // 
+  //
   // signed integer remainder is not supported on minimum-precision types; Cast to int to use 32-bit division
   // *and*
   // signed division remainder is not supported on minimum-precision types; Cast to int to use 32-bit division
   // are both mapped to
   // signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division
   //
-  
+
   _Static_assert(std::is_same<bool, __decltype(bools = bools)>::value, "");
   _Static_assert(std::is_same<bool, __decltype(bools = ints)>::value, "");
   _Static_assert(std::is_same<bool, __decltype(bools = uints)>::value, "");
@@ -123,18 +121,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16float, __decltype(min16floats = min16ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats = min12ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats = min16uints)>::value, "");
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = bools)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = halfs)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = doubles)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = min16floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = min10floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = min16ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = min12ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats = min16uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min16int, __decltype(min16ints = bools)>::value, "");
+  _Static_assert(std::is_same<min10float, __decltype(min10floats = bools)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = uints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = halfs)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = doubles)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = min16floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = min10floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = min16ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = min12ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats = min16uints)>::value, "");  _Static_assert(std::is_same<min16int, __decltype(min16ints = bools)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints = ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints = uints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints = halfs)>::value, "");
@@ -145,18 +132,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16int, __decltype(min16ints = min16ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints = min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints = min16uints)>::value, "");
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = halfs)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = doubles)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = min16floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = min10floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = min16ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints = min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints = bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints = bools)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = uints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = halfs)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = doubles)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = min16floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = min10floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = min16ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = min12ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints = min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints = bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints = ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints = uints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints = halfs)>::value, "");
@@ -244,18 +220,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16float, __decltype(min16floats += min16ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats += min12ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats += min16uints)>::value, "");
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += bools)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += halfs)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += doubles)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += min16floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += min10floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += min16ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += min12ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats += min16uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min16int, __decltype(min16ints += bools)>::value, "");
+  _Static_assert(std::is_same<min10float, __decltype(min10floats += bools)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += uints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += halfs)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += doubles)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += min16floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += min10floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += min16ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += min12ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats += min16uints)>::value, "");  _Static_assert(std::is_same<min16int, __decltype(min16ints += bools)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints += ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints += uints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints += halfs)>::value, "");
@@ -266,18 +231,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16int, __decltype(min16ints += min16ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints += min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints += min16uints)>::value, "");
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += halfs)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += doubles)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += min16floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += min10floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += min16ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints += min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints += bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints += bools)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += uints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += halfs)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += doubles)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += min16floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += min10floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += min16ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += min12ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints += min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints += bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints += ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints += uints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints += halfs)>::value, "");
@@ -365,18 +319,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16float, __decltype(min16floats -= min16ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats -= min12ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats -= min16uints)>::value, "");
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= bools)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= halfs)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= doubles)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min16floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min10floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min16ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min12ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min16uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min16int, __decltype(min16ints -= bools)>::value, "");
+  _Static_assert(std::is_same<min10float, __decltype(min10floats -= bools)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= uints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= halfs)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= doubles)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min16floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min10floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min16ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min12ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats -= min16uints)>::value, "");  _Static_assert(std::is_same<min16int, __decltype(min16ints -= bools)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints -= ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints -= uints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints -= halfs)>::value, "");
@@ -387,18 +330,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16int, __decltype(min16ints -= min16ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints -= min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints -= min16uints)>::value, "");
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= halfs)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= doubles)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min16floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min10floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min16ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints -= bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints -= bools)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= uints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= halfs)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= doubles)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min16floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min10floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min16ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min12ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints -= min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints -= bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints -= ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints -= uints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints -= halfs)>::value, "");
@@ -486,18 +418,7 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16float, __decltype(min16floats /= min16ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats /= min12ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats /= min16uints)>::value, "");
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= bools)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= halfs)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= doubles)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min16floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min10floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min16ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min12ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min16uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  (min16ints /= bools); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
+  _Static_assert(std::is_same<min10float, __decltype(min10floats /= bools)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= uints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= halfs)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= doubles)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min16floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min10floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min16ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min12ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats /= min16uints)>::value, "");  (min16ints /= bools); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
   _Static_assert(std::is_same<min16int, __decltype(min16ints /= ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints /= uints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints /= halfs)>::value, "");
@@ -509,17 +430,9 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   (min16ints /= min12ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
   _Static_assert(std::is_same<min16int, __decltype(min16ints /= min16uints)>::value, "");
   (min12ints /= bools); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints /= ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints /= uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints /= halfs)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints /= floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints /= doubles)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints /= min16floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints /= min10floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  (min12ints /= min16ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
+  _Static_assert(std::is_same<min12int, __decltype(min12ints /= ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints /= uints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints /= halfs)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints /= floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints /= doubles)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints /= min16floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints /= min10floats)>::value, "");  (min12ints /= min16ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
   (min12ints /= min12ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints /= min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints /= bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints /= min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints /= bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints /= ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints /= uints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints /= halfs)>::value, "");
@@ -607,18 +520,8 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16float, __decltype(min16floats %= min16ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats %= min12ints)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min16floats %= min16uints)>::value, "");
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= bools)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= ints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= uints)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= halfs)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
-  (min10floats %= doubles); // expected-error {{modulo cannot be used with doubles, cast to float first}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min16floats)>::value, "");    // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min10floats)>::value, "");   // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min16ints)>::value, "");   // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min12ints)>::value, "");   // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min16uints)>::value, "");   // expected-warning {{min10float is promoted to min16float}}
-  (min16ints %= bools); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
+  _Static_assert(std::is_same<min10float, __decltype(min10floats %= bools)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats %= ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats %= uints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats %= halfs)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats %= floats)>::value, "");  (min10floats %= doubles); // expected-error {{modulo cannot be used with doubles, cast to float first}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
+  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min16floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min10floats)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min16ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min12ints)>::value, "");  _Static_assert(std::is_same<min10float, __decltype(min10floats %= min16uints)>::value, "");  (min16ints %= bools); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
   _Static_assert(std::is_same<min16int, __decltype(min16ints %= ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints %= uints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints %= halfs)>::value, "");
@@ -630,17 +533,10 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   (min16ints %= min12ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
   _Static_assert(std::is_same<min16int, __decltype(min16ints %= min16uints)>::value, "");
   (min12ints %= bools); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints %= ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints %= uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints %= halfs)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints %= floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  (min12ints %= doubles); // expected-error {{modulo cannot be used with doubles, cast to float first}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints %= min16floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints %= min10floats)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  (min12ints %= min16ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
+  _Static_assert(std::is_same<min12int, __decltype(min12ints %= ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints %= uints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints %= halfs)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints %= floats)>::value, "");  (min12ints %= doubles); // expected-error {{modulo cannot be used with doubles, cast to float first}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
+  _Static_assert(std::is_same<min12int, __decltype(min12ints %= min16floats)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints %= min10floats)>::value, "");  (min12ints %= min16ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
   (min12ints %= min12ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-pass {{}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints %= min16uints)>::value, "");   // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints %= bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints %= min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints %= bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints %= ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints %= uints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints %= halfs)>::value, "");
@@ -750,18 +646,12 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16int, __decltype(min16ints <<= min16ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints <<= min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints <<= min16uints)>::value, "");
-  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  (min12ints <<= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
+  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= bools)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= uints)>::value, "");  (min12ints <<= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints <<= floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints <<= doubles); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints <<= min16floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints <<= min10floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= min16ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints <<= bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= min16ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= min12ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints <<= min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints <<= bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints <<= ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints <<= uints)>::value, "");
   (min16uints <<= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
@@ -871,18 +761,12 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16int, __decltype(min16ints >>= min16ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints >>= min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints >>= min16uints)>::value, "");
-  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  (min12ints >>= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
+  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= bools)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= uints)>::value, "");  (min12ints >>= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints >>= floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints >>= doubles); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints >>= min16floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints >>= min10floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= min16ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints >>= bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= min16ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= min12ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints >>= min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints >>= bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints >>= ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints >>= uints)>::value, "");
   (min16uints >>= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
@@ -992,18 +876,12 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16int, __decltype(min16ints &= min16ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints &= min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints &= min16uints)>::value, "");
-  _Static_assert(std::is_same<min12int, __decltype(min12ints &= bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints &= ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints &= uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  (min12ints &= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
+  _Static_assert(std::is_same<min12int, __decltype(min12ints &= bools)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints &= ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints &= uints)>::value, "");  (min12ints &= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints &= floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints &= doubles); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints &= min16floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints &= min10floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints &= min16ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints &= min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints &= min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints &= bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints &= min16ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints &= min12ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints &= min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints &= bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints &= ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints &= uints)>::value, "");
   (min16uints &= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
@@ -1113,18 +991,12 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16int, __decltype(min16ints |= min16ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints |= min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints |= min16uints)>::value, "");
-  _Static_assert(std::is_same<min12int, __decltype(min12ints |= bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints |= ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints |= uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  (min12ints |= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
+  _Static_assert(std::is_same<min12int, __decltype(min12ints |= bools)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints |= ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints |= uints)>::value, "");  (min12ints |= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints |= floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints |= doubles); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints |= min16floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints |= min10floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints |= min16ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints |= min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints |= min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints |= bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints |= min16ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints |= min12ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints |= min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints |= bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints |= ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints |= uints)>::value, "");
   (min16uints |= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
@@ -1234,18 +1106,12 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16int, __decltype(min16ints ^= min16ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints ^= min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints ^= min16uints)>::value, "");
-  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  (min12ints ^= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
+  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= bools)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= uints)>::value, "");  (min12ints ^= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints ^= floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints ^= doubles); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints ^= min16floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   (min12ints ^= min10floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= min16ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= min16uints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min16uints ^= bools)>::value, "");
+  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= min16ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= min12ints)>::value, "");  _Static_assert(std::is_same<min12int, __decltype(min12ints ^= min16uints)>::value, "");  _Static_assert(std::is_same<min16uint, __decltype(min16uints ^= bools)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints ^= ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints ^= uints)>::value, "");
   (min16uints ^= halfs); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
@@ -1257,4 +1123,4 @@ float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   _Static_assert(std::is_same<min16uint, __decltype(min16uints ^= min12ints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints ^= min16uints)>::value, "");
 
-}
+}

+ 12 - 12
tools/clang/test/HLSL/scalar-operators.hlsl

@@ -33,7 +33,7 @@ float4 plain(float4 param4 : FOO) : FOO {
     _Static_assert(std::is_same<bool, __decltype(bools)>::value, "bool, __decltype(bools) failed");
     _Static_assert(std::is_same<bool, __decltype(bools < bools)>::value, "bool, __decltype(bools < bools) failed");
 
-  
+
     // float result = ints + floats;
     _Static_assert(std::is_same<min16uint, __decltype(min16ints  + min16uints)>::value, "");
 
@@ -41,23 +41,23 @@ float4 plain(float4 param4 : FOO) : FOO {
     // Two unsigned types will widen to widest type.
     _Static_assert(std::is_same<uint, __decltype(uints      + min16uints)>::value, "");
     _Static_assert(std::is_same<uint, __decltype(min16uints + uints     )>::value, "");
-    
+
     // Two signed types will widen to widest type, but remain minprecision if either is.
     _Static_assert(std::is_same<int, __decltype(ints      + min12ints)>::value, "");
     _Static_assert(std::is_same<int, __decltype(min12ints + ints     )>::value, "");
-    
+
     // Mixed signed-unsigned will widen to largest unsigned.
     _Static_assert(std::is_same<uint, __decltype(ints  + uints)>::value, "");
     _Static_assert(std::is_same<uint, __decltype(uints + ints )>::value, "");
     _Static_assert(std::is_same<min16uint, __decltype(min16ints  + min16uints)>::value, "");
     _Static_assert(std::is_same<min16uint, __decltype(min16uints + min16ints )>::value, "");
-    
+
     // Mixed integral/floating point will turn to floating-point.
     _Static_assert(std::is_same<float, __decltype(ints    + floats)>::value, "");
     _Static_assert(std::is_same<float, __decltype(uints   + floats)>::value, "");
     _Static_assert(std::is_same<double, __decltype(doubles + ints)>::value, "");
     _Static_assert(std::is_same<double, __decltype(uints   + doubles)>::value, "");
-    
+
     // For two floating-point types, they will widen to the largest one.
     _Static_assert(std::is_same<double, __decltype(doubles + floats)>::value, "");
     _Static_assert(std::is_same<double, __decltype(floats  + doubles)>::value, "");
@@ -69,7 +69,7 @@ float4 plain(float4 param4 : FOO) : FOO {
     _Static_assert(std::is_same<float , __decltype(min16floats + floats)>::value, "");
     _Static_assert(std::is_same<float , __decltype(floats      + min10floats)>::value, "");
     _Static_assert(std::is_same<float , __decltype(min10floats + floats)>::value, "");
-    
+
   // Generated by running and modifying %sdxroot%\windows\directx\dxg\HLSL\test\lib\HLSL\operators.js
   _Static_assert(std::is_same<int, __decltype(bools + bools)>::value, "");
   _Static_assert(std::is_same<int, __decltype(bools + ints)>::value, "");
@@ -299,9 +299,9 @@ float4 plain(float4 param4 : FOO) : FOO {
   _Static_assert(std::is_same<double, __decltype(min12ints - doubles)>::value, "");
   _Static_assert(std::is_same<min16float, __decltype(min12ints - min16floats)>::value, "");
   _Static_assert(std::is_same<min10float, __decltype(min12ints - min10floats)>::value, "");   // expected-warning {{min10float is promoted to min16float}}
-  _Static_assert(std::is_same<min16int, __decltype(min12ints - min16ints)>::value, ""); 
+  _Static_assert(std::is_same<min16int, __decltype(min12ints - min16ints)>::value, "");
   _Static_assert(std::is_same<min12int, __decltype(min12ints - min12ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
-  _Static_assert(std::is_same<min16uint, __decltype(min12ints - min16uints)>::value, ""); 
+  _Static_assert(std::is_same<min16uint, __decltype(min12ints - min16uints)>::value, "");
   _Static_assert(std::is_same<min16uint, __decltype(min16uints - bools)>::value, "");
   _Static_assert(std::is_same<uint, __decltype(min16uints - ints)>::value, "");
   _Static_assert(std::is_same<uint, __decltype(min16uints - uints)>::value, "");
@@ -422,10 +422,10 @@ float4 plain(float4 param4 : FOO) : FOO {
   _Static_assert(std::is_same<float, __decltype(min12ints / halfs)>::value, "");
   _Static_assert(std::is_same<float, __decltype(min12ints / floats)>::value, "");
   _Static_assert(std::is_same<double, __decltype(min12ints / doubles)>::value, "");
-  _Static_assert(std::is_same<min16float, __decltype(min12ints / min16floats)>::value, "");  
+  _Static_assert(std::is_same<min16float, __decltype(min12ints / min16floats)>::value, "");
   _Static_assert(std::is_same<min10float, __decltype(min12ints / min10floats)>::value, "");  // expected-warning {{min10float is promoted to min16float}}
   // X:\temp\Sfbl_grfx_dev_p\x86\chk\operators.js.hlsl(16,22-56): error X3706: signed integer division is not supported on minimum-precision types. Cast to int to use 32-bit division.;compilation failed; no code produced;
-  min12ints = (min12ints / min16ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} expected-warning {{conversion from larger type 'short' to smaller type 'min12int', possible loss of data}} fxc-error {{X3706: signed integer division is not supported on minimum-precision types. Cast to int to use 32-bit division.}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
+  min12ints = (min12ints / min16ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-error {{X3706: signed integer division is not supported on minimum-precision types. Cast to int to use 32-bit division.}} fxc-warning {{X3205: conversion from larger type to smaller, possible loss of data}}
   // X:\temp\Sfbl_grfx_dev_p\x86\chk\operators.js.hlsl(16,22-56): error X3706: signed integer division is not supported on minimum-precision types. Cast to int to use 32-bit division.;compilation failed; no code produced;
   min12ints = (min12ints / min12ints); // expected-error {{signed integer division is not supported on minimum-precision types, cast to int to use 32-bit division}} fxc-error {{X3706: signed integer division is not supported on minimum-precision types. Cast to int to use 32-bit division.}}
   _Static_assert(std::is_same<min16uint, __decltype(min12ints / min16uints)>::value, "");
@@ -1692,7 +1692,7 @@ float4 plain(float4 param4 : FOO) : FOO {
   // X:\temp\Sfbl_grfx_dev_p\x86\chk\operators.js.hlsl(16,22-59): error X3082: int or unsigned int type required;X:\temp\Sfbl_grfx_dev_p\x86\chk\operators.js.hlsl(16,12-60): error X3013: 'get_value': no matching 1 parameter function;compilation failed; no code produced
   min16ints = (min16ints >> min10floats); // expected-error {{int or unsigned int type required}} fxc-error {{X3082: int or unsigned int type required}}
   _Static_assert(std::is_same<min16int, __decltype(min16ints >> min16ints)>::value, "");
-  _Static_assert(std::is_same<min16int, __decltype(min16ints >> min12ints)>::value, "");  
+  _Static_assert(std::is_same<min16int, __decltype(min16ints >> min12ints)>::value, "");
   _Static_assert(std::is_same<min16int, __decltype(min16ints >> min16uints)>::value, "");
   _Static_assert(std::is_same<min12int, __decltype(min12ints >> bools)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
   _Static_assert(std::is_same<min12int, __decltype(min12ints >> ints)>::value, "");  // expected-warning {{min12int is promoted to min16int}}
@@ -2588,4 +2588,4 @@ float4 plain(float4 param4 : FOO) : FOO {
   _Static_assert(std::is_same<bool, __decltype(min16uints || min16uints)>::value, "");
 
   return param4;
-}
+}

+ 2 - 2
tools/clang/test/HLSL/vector-syntax.hlsl

@@ -101,7 +101,7 @@ void vector_unsigned() {
    unsigned bool3 boolvector;   /* expected-error {{'bool' cannot be signed or unsigned}} fxc-error {{X3085: unsigned can not be used with type}} */
    unsigned half4 halfvector;   /* expected-error {{'float' cannot be signed or unsigned}} fxc-error {{X3085: unsigned can not be used with type}} */
    unsigned double1 doublevector;                           /* expected-error {{'double' cannot be signed or unsigned}} fxc-error {{X3085: unsigned can not be used with type}} */
-   unsigned min12int2 min12intvector;                       /* expected-error {{'min12int' cannot be signed or unsigned}} expected-warning {{min12int is promoted to min16int}} fxc-error {{X3085: unsigned can not be used with type}} */
+   unsigned min12int2 min12intvector;                       /* expected-warning {{min12int is promoted to min16int}} fxc-error {{X3085: unsigned can not be used with type}} */
    unsigned min16float3 min16floatvector;                   /* expected-error {{'min16float' cannot be signed or unsigned}} fxc-error {{X3085: unsigned can not be used with type}} */
 }
 
@@ -180,4 +180,4 @@ float fn() {
 // float4 main(float4 param4 : FOO) : FOO {
 float4 plain(float4 param4 /* : FOO */) /*: FOO */{
   return fn();
-}
+}

+ 2 - 18
tools/clang/tools/libclang/CIndex.cpp

@@ -5584,30 +5584,14 @@ static bool IsHLSLBuiltInType(IdentifierInfo* ii)
   if (tokenKind == clang::tok::kw_bool ||
       tokenKind == clang::tok::kw_int ||
       tokenKind == clang::tok::kw_float ||
-      tokenKind == clang::tok::kw_double ||
-      tokenKind == clang::tok::kw_min10float ||
-      tokenKind == clang::tok::kw_min12int) {
-    return true;
-  }
-
-  // Other built-in types are simple typedefs.
-  if (ii->getName().equals("uint") ||
-      ii->getName().equals("dword") ||
-      ii->getName().equals("half")) {
+      tokenKind == clang::tok::kw_double) {
     return true;
   }
 
   // Vectors and matrices can be parsed with internal lookup tables.
   hlsl::HLSLScalarType scalarType;
   int count;
-  if (hlsl::TryParseMatrixShorthand(ii->getNameStart(), ii->getLength(), &scalarType, &count, &count)) {
-    return true;
-  }
-  if (hlsl::TryParseVectorShorthand(ii->getNameStart(), ii->getLength(), &scalarType, &count)) {
-    return true;
-  }
-
-  return false;
+  return hlsl::TryParseAny(ii->getNameStart(), ii->getLength(), &scalarType, &count, &count);
 }
 // HLSL Change Ends