[clang] Add clang_elementwise_builtin_alias (PR #86175)

Joshua Batista via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 26 11:01:02 PDT 2024


https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/86175

>From 5e10b1e42a20a39c9a3d5ff332591713511832c8 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 20 Mar 2024 13:24:07 -0700
Subject: [PATCH 1/7] make elemnetwise alias an alias of builtin alias

---
 clang/include/clang/Basic/Attr.td             |  9 ++++++++
 clang/include/clang/Basic/AttrDocs.td         | 22 +++++++++++++++++++
 .../clang/Basic/DiagnosticSemaKinds.td        |  3 ++-
 clang/lib/AST/Decl.cpp                        |  2 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h      |  2 ++
 5 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index fd7970d0451acd..160e8ef730ef92 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -759,6 +759,15 @@ def BuiltinAlias : Attr {
   let Documentation = [BuiltinAliasDocs];
 }
 
+def ElementwiseBuiltinAlias : Attr {
+  let Spellings = [CXX11<"clang", "elementwise_builtin_alias">,
+                   C23<"clang", "elementwise_builtin_alias">,
+                   GNU<"clang_elementwise_builtin_alias">];
+  let Args = [IdentifierArgument<"BuiltinName">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [ElementwiseBuiltinAliasDocs];
+}
+
 def ArmBuiltinAlias : InheritableAttr, TargetSpecificAttr<TargetAnyArm> {
   let Spellings = [Clang<"__clang_arm_builtin_alias">];
   let Args = [IdentifierArgument<"BuiltinName">];
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 2c07cd09b0d5b7..7ce83bc881f064 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5462,6 +5462,28 @@ for clang builtin functions.
   }];
 }
 
+def ElementwiseBuiltinAliasDocs : Documentation {
+  let Category = DocCatFunction;
+  let Heading = "clang::elementwise_builtin_alias, clang_elementwise_builtin_alias";
+  let Content = [{
+This attribute is used in the implementation of the C intrinsics.
+It allows the C intrinsic functions to be declared using the names defined
+in target builtins, and still be recognized as clang builtins equivalent to the
+underlying name. It also declares that the given C intrinsic can accept 
+vector arguments. For example, ``hlsl_intrinsics.h`` declares the function ``abs``
+with ``__attribute__((clang_elementwise_builtin_alias(__builtin_abs)))``.
+This ensures that both functions are recognized as that clang builtin,
+and in the latter case, the choice of which builtin to identify the
+function as can be deferred until after overload resolution. It also enables
+the ``abs`` function to take vector arguments.
+
+This attribute can only be used to set up the aliases for certain ARM/RISC-V
+C intrinsic functions; it is intended for use only inside ``arm_*.h`` and
+``riscv_*.h`` and is not a general mechanism for declaring arbitrary aliases
+for clang builtin functions.
+  }];
+}
+
 def PreferredNameDocs : Documentation {
   let Category = DocCatDecl;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c54105507753eb..1252d3804131a6 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4412,7 +4412,8 @@ def err_attribute_preferred_name_arg_invalid : Error<
   "a specialization of %1">;
 def err_attribute_builtin_alias : Error<
   "%0 attribute can only be applied to a ARM, HLSL or RISC-V builtin">;
-
+def err_attribute_elementwise_builtin_alias : Error<
+  "%0 attribute can only be applied to a ARM, HLSL or RISC-V builtin">;
 // called-once attribute diagnostics.
 def err_called_once_attribute_wrong_type : Error<
   "'called_once' attribute only applies to function-like parameters">;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 8626f04012f7d4..cb2c5cf6ceaf49 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3598,6 +3598,8 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
     BuiltinID = ABAA->getBuiltinName()->getBuiltinID();
   } else if (const auto *BAA = getAttr<BuiltinAliasAttr>()) {
     BuiltinID = BAA->getBuiltinName()->getBuiltinID();
+  } else if (const auto *EBAA = getAttr<ElementwiseBuiltinAliasAttr>()) {
+    BuiltinID = EBAA->getBuiltinName()->getBuiltinID();
   } else if (const auto *A = getAttr<BuiltinAttr>()) {
     BuiltinID = A->getID();
   }
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 45f8544392584e..b37c4d13b26e62 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -18,6 +18,8 @@ namespace hlsl {
 
 #define _HLSL_BUILTIN_ALIAS(builtin)                                           \
   __attribute__((clang_builtin_alias(builtin)))
+#define _HLSL_ELEMENTWISE_BUILTIN_ALIAS(builtin)                                           \
+  __attribute__((clang_elementwise_builtin_alias(builtin)))
 #define _HLSL_AVAILABILITY(environment, version)                               \
   __attribute__((availability(environment, introduced = version)))
 

>From 4cb34745b6d51e71fed1036009730f92cd4d36e9 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 20 Mar 2024 13:54:06 -0700
Subject: [PATCH 2/7] my alias is now a verified alias!

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 2 +-
 clang/lib/Sema/SemaDeclAttr.cpp          | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index b37c4d13b26e62..f646522e35e84c 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -99,7 +99,7 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
 double2 abs(double2);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
 double3 abs(double3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
+_HLSL_ELEMENTWISE_BUILTIN_ALIAS(__builtin_elementwise_abs)
 double4 abs(double4);
 
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index c00120b59d396e..4710bd61a78e14 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -9851,6 +9851,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
   case ParsedAttr::AT_BuiltinAlias:
     handleBuiltinAliasAttr(S, D, AL);
     break;
+  case ParsedAttr::AT_ElementwiseBuiltinAlias:
+    handleBuiltinAliasAttr(S, D, AL);
+    break;
 
   case ParsedAttr::AT_PreferredType:
     handlePreferredTypeAttr(S, D, AL);

>From 4c8ba70909906e13b8b997d406d3f4a0e006015b Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 20 Mar 2024 17:39:43 -0700
Subject: [PATCH 3/7] attempt to implement 1

---
 clang/lib/Sema/SemaChecking.cpp | 632 +++++++++++++++++---------------
 clang/lib/Sema/SemaDeclAttr.cpp |  31 +-
 2 files changed, 364 insertions(+), 299 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a5f42b630c3fa2..f60a38980549e9 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2240,317 +2240,353 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
     ICEArguments &= ~(1 << ArgNo);
   }
 
-  FPOptions FPO;
-  switch (BuiltinID) {
-  case Builtin::BI__builtin_cpu_supports:
-  case Builtin::BI__builtin_cpu_is:
-    if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall,
-                       Context.getAuxTargetInfo(), BuiltinID))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_cpu_init:
-    if (!Context.getTargetInfo().supportsCpuInit()) {
-      Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
-          << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
-      return ExprError();
+  // if the call has the elementwise attribute, then
+  // make sure that an elementwise expr is emitted.
+  if (FDecl->hasAttr(Attr::AT_ElementwiseBuiltinAlias)) {
+    switch (FDecl->getNumParams()) {
+    case 1: {
+      if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
+        return ExprError();
+
+      QualType ArgTy = TheCall->getArg(0)->getType();
+      if (checkFPMathBuiltinElementType(
+              *this, TheCall->getArg(0)->getBeginLoc(), ArgTy, 1))
+        return ExprError();
+      break;
     }
-    break;
-  case Builtin::BI__builtin___CFStringMakeConstantString:
-    // CFStringMakeConstantString is currently not implemented for GOFF (i.e.,
-    // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported
-    if (CheckBuiltinTargetNotInUnsupported(
-            *this, BuiltinID, TheCall,
-            {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
-      return ExprError();
-    assert(TheCall->getNumArgs() == 1 &&
-           "Wrong # arguments to builtin CFStringMakeConstantString");
-    if (CheckObjCString(TheCall->getArg(0)))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_ms_va_start:
-  case Builtin::BI__builtin_stdarg_start:
-  case Builtin::BI__builtin_va_start:
-    if (SemaBuiltinVAStart(BuiltinID, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__va_start: {
-    switch (Context.getTargetInfo().getTriple().getArch()) {
-    case llvm::Triple::aarch64:
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-      if (SemaBuiltinVAStartARMMicrosoft(TheCall))
+    case 2: {
+      if (SemaBuiltinElementwiseMath(TheCall))
+        return ExprError();
+
+      QualType ArgTy = TheCall->getArg(0)->getType();
+      if (checkFPMathBuiltinElementType(
+              *this, TheCall->getArg(0)->getBeginLoc(), ArgTy, 1) ||
+          checkFPMathBuiltinElementType(
+              *this, TheCall->getArg(1)->getBeginLoc(), ArgTy, 2))
         return ExprError();
       break;
-    default:
+    }
+    case 3: {
+      if (SemaBuiltinElementwiseTernaryMath(TheCall))
+        return ExprError();
+      break;
+    }
+    }
+
+    FPOptions FPO;
+    switch (BuiltinID) {
+    case Builtin::BI__builtin_cpu_supports:
+    case Builtin::BI__builtin_cpu_is:
+      if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall,
+                         Context.getAuxTargetInfo(), BuiltinID))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_cpu_init:
+      if (!Context.getTargetInfo().supportsCpuInit()) {
+        Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
+            << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
+        return ExprError();
+      }
+      break;
+    case Builtin::BI__builtin___CFStringMakeConstantString:
+      // CFStringMakeConstantString is currently not implemented for GOFF (i.e.,
+      // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported
+      if (CheckBuiltinTargetNotInUnsupported(
+              *this, BuiltinID, TheCall,
+              {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
+        return ExprError();
+      assert(TheCall->getNumArgs() == 1 &&
+             "Wrong # arguments to builtin CFStringMakeConstantString");
+      if (CheckObjCString(TheCall->getArg(0)))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_ms_va_start:
+    case Builtin::BI__builtin_stdarg_start:
+    case Builtin::BI__builtin_va_start:
       if (SemaBuiltinVAStart(BuiltinID, TheCall))
         return ExprError();
       break;
+    case Builtin::BI__va_start: {
+      switch (Context.getTargetInfo().getTriple().getArch()) {
+      case llvm::Triple::aarch64:
+      case llvm::Triple::arm:
+      case llvm::Triple::thumb:
+        if (SemaBuiltinVAStartARMMicrosoft(TheCall))
+          return ExprError();
+        break;
+      default:
+        if (SemaBuiltinVAStart(BuiltinID, TheCall))
+          return ExprError();
+        break;
+      }
+      break;
     }
-    break;
-  }
 
-  // The acquire, release, and no fence variants are ARM and AArch64 only.
-  case Builtin::BI_interlockedbittestandset_acq:
-  case Builtin::BI_interlockedbittestandset_rel:
-  case Builtin::BI_interlockedbittestandset_nf:
-  case Builtin::BI_interlockedbittestandreset_acq:
-  case Builtin::BI_interlockedbittestandreset_rel:
-  case Builtin::BI_interlockedbittestandreset_nf:
-    if (CheckBuiltinTargetInSupported(
-            *this, BuiltinID, TheCall,
-            {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
-      return ExprError();
-    break;
+    // The acquire, release, and no fence variants are ARM and AArch64 only.
+    case Builtin::BI_interlockedbittestandset_acq:
+    case Builtin::BI_interlockedbittestandset_rel:
+    case Builtin::BI_interlockedbittestandset_nf:
+    case Builtin::BI_interlockedbittestandreset_acq:
+    case Builtin::BI_interlockedbittestandreset_rel:
+    case Builtin::BI_interlockedbittestandreset_nf:
+      if (CheckBuiltinTargetInSupported(
+              *this, BuiltinID, TheCall,
+              {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
+        return ExprError();
+      break;
 
-  // The 64-bit bittest variants are x64, ARM, and AArch64 only.
-  case Builtin::BI_bittest64:
-  case Builtin::BI_bittestandcomplement64:
-  case Builtin::BI_bittestandreset64:
-  case Builtin::BI_bittestandset64:
-  case Builtin::BI_interlockedbittestandreset64:
-  case Builtin::BI_interlockedbittestandset64:
-    if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall,
-                                      {llvm::Triple::x86_64, llvm::Triple::arm,
-                                       llvm::Triple::thumb,
-                                       llvm::Triple::aarch64}))
-      return ExprError();
-    break;
+    // The 64-bit bittest variants are x64, ARM, and AArch64 only.
+    case Builtin::BI_bittest64:
+    case Builtin::BI_bittestandcomplement64:
+    case Builtin::BI_bittestandreset64:
+    case Builtin::BI_bittestandset64:
+    case Builtin::BI_interlockedbittestandreset64:
+    case Builtin::BI_interlockedbittestandset64:
+      if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall,
+                                        {llvm::Triple::x86_64,
+                                         llvm::Triple::arm, llvm::Triple::thumb,
+                                         llvm::Triple::aarch64}))
+        return ExprError();
+      break;
 
-  case Builtin::BI__builtin_set_flt_rounds:
-    if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall,
-                                      {llvm::Triple::x86, llvm::Triple::x86_64,
-                                       llvm::Triple::arm, llvm::Triple::thumb,
-                                       llvm::Triple::aarch64}))
-      return ExprError();
-    break;
+    case Builtin::BI__builtin_set_flt_rounds:
+      if (CheckBuiltinTargetInSupported(
+              *this, BuiltinID, TheCall,
+              {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
+               llvm::Triple::thumb, llvm::Triple::aarch64}))
+        return ExprError();
+      break;
 
-  case Builtin::BI__builtin_isgreater:
-  case Builtin::BI__builtin_isgreaterequal:
-  case Builtin::BI__builtin_isless:
-  case Builtin::BI__builtin_islessequal:
-  case Builtin::BI__builtin_islessgreater:
-  case Builtin::BI__builtin_isunordered:
-    if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_fpclassify:
-    if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_isfpclass:
-    if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_isfinite:
-  case Builtin::BI__builtin_isinf:
-  case Builtin::BI__builtin_isinf_sign:
-  case Builtin::BI__builtin_isnan:
-  case Builtin::BI__builtin_issignaling:
-  case Builtin::BI__builtin_isnormal:
-  case Builtin::BI__builtin_issubnormal:
-  case Builtin::BI__builtin_iszero:
-  case Builtin::BI__builtin_signbit:
-  case Builtin::BI__builtin_signbitf:
-  case Builtin::BI__builtin_signbitl:
-    if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_shufflevector:
-    return SemaBuiltinShuffleVector(TheCall);
-    // TheCall will be freed by the smart pointer here, but that's fine, since
-    // SemaBuiltinShuffleVector guts it, but then doesn't release it.
-  case Builtin::BI__builtin_prefetch:
-    if (SemaBuiltinPrefetch(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_alloca_with_align:
-  case Builtin::BI__builtin_alloca_with_align_uninitialized:
-    if (SemaBuiltinAllocaWithAlign(TheCall))
-      return ExprError();
-    [[fallthrough]];
-  case Builtin::BI__builtin_alloca:
-  case Builtin::BI__builtin_alloca_uninitialized:
-    Diag(TheCall->getBeginLoc(), diag::warn_alloca)
-        << TheCall->getDirectCallee();
-    break;
-  case Builtin::BI__arithmetic_fence:
-    if (SemaBuiltinArithmeticFence(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__assume:
-  case Builtin::BI__builtin_assume:
-    if (SemaBuiltinAssume(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_assume_aligned:
-    if (SemaBuiltinAssumeAligned(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_dynamic_object_size:
-  case Builtin::BI__builtin_object_size:
-    if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_longjmp:
-    if (SemaBuiltinLongjmp(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_setjmp:
-    if (SemaBuiltinSetjmp(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_classify_type:
-    if (checkArgCount(*this, TheCall, 1)) return true;
-    TheCall->setType(Context.IntTy);
-    break;
-  case Builtin::BI__builtin_complex:
-    if (SemaBuiltinComplex(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_constant_p: {
-    if (checkArgCount(*this, TheCall, 1)) return true;
-    ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));
-    if (Arg.isInvalid()) return true;
-    TheCall->setArg(0, Arg.get());
-    TheCall->setType(Context.IntTy);
-    break;
-  }
-  case Builtin::BI__builtin_launder:
-    return SemaBuiltinLaunder(*this, TheCall);
-  case Builtin::BI__sync_fetch_and_add:
-  case Builtin::BI__sync_fetch_and_add_1:
-  case Builtin::BI__sync_fetch_and_add_2:
-  case Builtin::BI__sync_fetch_and_add_4:
-  case Builtin::BI__sync_fetch_and_add_8:
-  case Builtin::BI__sync_fetch_and_add_16:
-  case Builtin::BI__sync_fetch_and_sub:
-  case Builtin::BI__sync_fetch_and_sub_1:
-  case Builtin::BI__sync_fetch_and_sub_2:
-  case Builtin::BI__sync_fetch_and_sub_4:
-  case Builtin::BI__sync_fetch_and_sub_8:
-  case Builtin::BI__sync_fetch_and_sub_16:
-  case Builtin::BI__sync_fetch_and_or:
-  case Builtin::BI__sync_fetch_and_or_1:
-  case Builtin::BI__sync_fetch_and_or_2:
-  case Builtin::BI__sync_fetch_and_or_4:
-  case Builtin::BI__sync_fetch_and_or_8:
-  case Builtin::BI__sync_fetch_and_or_16:
-  case Builtin::BI__sync_fetch_and_and:
-  case Builtin::BI__sync_fetch_and_and_1:
-  case Builtin::BI__sync_fetch_and_and_2:
-  case Builtin::BI__sync_fetch_and_and_4:
-  case Builtin::BI__sync_fetch_and_and_8:
-  case Builtin::BI__sync_fetch_and_and_16:
-  case Builtin::BI__sync_fetch_and_xor:
-  case Builtin::BI__sync_fetch_and_xor_1:
-  case Builtin::BI__sync_fetch_and_xor_2:
-  case Builtin::BI__sync_fetch_and_xor_4:
-  case Builtin::BI__sync_fetch_and_xor_8:
-  case Builtin::BI__sync_fetch_and_xor_16:
-  case Builtin::BI__sync_fetch_and_nand:
-  case Builtin::BI__sync_fetch_and_nand_1:
-  case Builtin::BI__sync_fetch_and_nand_2:
-  case Builtin::BI__sync_fetch_and_nand_4:
-  case Builtin::BI__sync_fetch_and_nand_8:
-  case Builtin::BI__sync_fetch_and_nand_16:
-  case Builtin::BI__sync_add_and_fetch:
-  case Builtin::BI__sync_add_and_fetch_1:
-  case Builtin::BI__sync_add_and_fetch_2:
-  case Builtin::BI__sync_add_and_fetch_4:
-  case Builtin::BI__sync_add_and_fetch_8:
-  case Builtin::BI__sync_add_and_fetch_16:
-  case Builtin::BI__sync_sub_and_fetch:
-  case Builtin::BI__sync_sub_and_fetch_1:
-  case Builtin::BI__sync_sub_and_fetch_2:
-  case Builtin::BI__sync_sub_and_fetch_4:
-  case Builtin::BI__sync_sub_and_fetch_8:
-  case Builtin::BI__sync_sub_and_fetch_16:
-  case Builtin::BI__sync_and_and_fetch:
-  case Builtin::BI__sync_and_and_fetch_1:
-  case Builtin::BI__sync_and_and_fetch_2:
-  case Builtin::BI__sync_and_and_fetch_4:
-  case Builtin::BI__sync_and_and_fetch_8:
-  case Builtin::BI__sync_and_and_fetch_16:
-  case Builtin::BI__sync_or_and_fetch:
-  case Builtin::BI__sync_or_and_fetch_1:
-  case Builtin::BI__sync_or_and_fetch_2:
-  case Builtin::BI__sync_or_and_fetch_4:
-  case Builtin::BI__sync_or_and_fetch_8:
-  case Builtin::BI__sync_or_and_fetch_16:
-  case Builtin::BI__sync_xor_and_fetch:
-  case Builtin::BI__sync_xor_and_fetch_1:
-  case Builtin::BI__sync_xor_and_fetch_2:
-  case Builtin::BI__sync_xor_and_fetch_4:
-  case Builtin::BI__sync_xor_and_fetch_8:
-  case Builtin::BI__sync_xor_and_fetch_16:
-  case Builtin::BI__sync_nand_and_fetch:
-  case Builtin::BI__sync_nand_and_fetch_1:
-  case Builtin::BI__sync_nand_and_fetch_2:
-  case Builtin::BI__sync_nand_and_fetch_4:
-  case Builtin::BI__sync_nand_and_fetch_8:
-  case Builtin::BI__sync_nand_and_fetch_16:
-  case Builtin::BI__sync_val_compare_and_swap:
-  case Builtin::BI__sync_val_compare_and_swap_1:
-  case Builtin::BI__sync_val_compare_and_swap_2:
-  case Builtin::BI__sync_val_compare_and_swap_4:
-  case Builtin::BI__sync_val_compare_and_swap_8:
-  case Builtin::BI__sync_val_compare_and_swap_16:
-  case Builtin::BI__sync_bool_compare_and_swap:
-  case Builtin::BI__sync_bool_compare_and_swap_1:
-  case Builtin::BI__sync_bool_compare_and_swap_2:
-  case Builtin::BI__sync_bool_compare_and_swap_4:
-  case Builtin::BI__sync_bool_compare_and_swap_8:
-  case Builtin::BI__sync_bool_compare_and_swap_16:
-  case Builtin::BI__sync_lock_test_and_set:
-  case Builtin::BI__sync_lock_test_and_set_1:
-  case Builtin::BI__sync_lock_test_and_set_2:
-  case Builtin::BI__sync_lock_test_and_set_4:
-  case Builtin::BI__sync_lock_test_and_set_8:
-  case Builtin::BI__sync_lock_test_and_set_16:
-  case Builtin::BI__sync_lock_release:
-  case Builtin::BI__sync_lock_release_1:
-  case Builtin::BI__sync_lock_release_2:
-  case Builtin::BI__sync_lock_release_4:
-  case Builtin::BI__sync_lock_release_8:
-  case Builtin::BI__sync_lock_release_16:
-  case Builtin::BI__sync_swap:
-  case Builtin::BI__sync_swap_1:
-  case Builtin::BI__sync_swap_2:
-  case Builtin::BI__sync_swap_4:
-  case Builtin::BI__sync_swap_8:
-  case Builtin::BI__sync_swap_16:
-    return SemaBuiltinAtomicOverloaded(TheCallResult);
-  case Builtin::BI__sync_synchronize:
-    Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst)
-        << TheCall->getCallee()->getSourceRange();
-    break;
-  case Builtin::BI__builtin_nontemporal_load:
-  case Builtin::BI__builtin_nontemporal_store:
-    return SemaBuiltinNontemporalOverloaded(TheCallResult);
-  case Builtin::BI__builtin_memcpy_inline: {
-    clang::Expr *SizeOp = TheCall->getArg(2);
-    // We warn about copying to or from `nullptr` pointers when `size` is
-    // greater than 0. When `size` is value dependent we cannot evaluate its
-    // value so we bail out.
-    if (SizeOp->isValueDependent())
+    case Builtin::BI__builtin_isgreater:
+    case Builtin::BI__builtin_isgreaterequal:
+    case Builtin::BI__builtin_isless:
+    case Builtin::BI__builtin_islessequal:
+    case Builtin::BI__builtin_islessgreater:
+    case Builtin::BI__builtin_isunordered:
+      if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_fpclassify:
+      if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_isfpclass:
+      if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_isfinite:
+    case Builtin::BI__builtin_isinf:
+    case Builtin::BI__builtin_isinf_sign:
+    case Builtin::BI__builtin_isnan:
+    case Builtin::BI__builtin_issignaling:
+    case Builtin::BI__builtin_isnormal:
+    case Builtin::BI__builtin_issubnormal:
+    case Builtin::BI__builtin_iszero:
+    case Builtin::BI__builtin_signbit:
+    case Builtin::BI__builtin_signbitf:
+    case Builtin::BI__builtin_signbitl:
+      if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_shufflevector:
+      return SemaBuiltinShuffleVector(TheCall);
+      // TheCall will be freed by the smart pointer here, but that's fine, since
+      // SemaBuiltinShuffleVector guts it, but then doesn't release it.
+    case Builtin::BI__builtin_prefetch:
+      if (SemaBuiltinPrefetch(TheCall))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_alloca_with_align:
+    case Builtin::BI__builtin_alloca_with_align_uninitialized:
+      if (SemaBuiltinAllocaWithAlign(TheCall))
+        return ExprError();
+      [[fallthrough]];
+    case Builtin::BI__builtin_alloca:
+    case Builtin::BI__builtin_alloca_uninitialized:
+      Diag(TheCall->getBeginLoc(), diag::warn_alloca)
+          << TheCall->getDirectCallee();
+      break;
+    case Builtin::BI__arithmetic_fence:
+      if (SemaBuiltinArithmeticFence(TheCall))
+        return ExprError();
+      break;
+    case Builtin::BI__assume:
+    case Builtin::BI__builtin_assume:
+      if (SemaBuiltinAssume(TheCall))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_assume_aligned:
+      if (SemaBuiltinAssumeAligned(TheCall))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_dynamic_object_size:
+    case Builtin::BI__builtin_object_size:
+      if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_longjmp:
+      if (SemaBuiltinLongjmp(TheCall))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_setjmp:
+      if (SemaBuiltinSetjmp(TheCall))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_classify_type:
+      if (checkArgCount(*this, TheCall, 1))
+        return true;
+      TheCall->setType(Context.IntTy);
+      break;
+    case Builtin::BI__builtin_complex:
+      if (SemaBuiltinComplex(TheCall))
+        return ExprError();
+      break;
+    case Builtin::BI__builtin_constant_p: {
+      if (checkArgCount(*this, TheCall, 1))
+        return true;
+      ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));
+      if (Arg.isInvalid())
+        return true;
+      TheCall->setArg(0, Arg.get());
+      TheCall->setType(Context.IntTy);
       break;
-    if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) {
-      CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
-      CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc());
     }
-    break;
-  }
-  case Builtin::BI__builtin_memset_inline: {
-    clang::Expr *SizeOp = TheCall->getArg(2);
-    // We warn about filling to `nullptr` pointers when `size` is greater than
-    // 0. When `size` is value dependent we cannot evaluate its value so we bail
-    // out.
-    if (SizeOp->isValueDependent())
+    case Builtin::BI__builtin_launder:
+      return SemaBuiltinLaunder(*this, TheCall);
+    case Builtin::BI__sync_fetch_and_add:
+    case Builtin::BI__sync_fetch_and_add_1:
+    case Builtin::BI__sync_fetch_and_add_2:
+    case Builtin::BI__sync_fetch_and_add_4:
+    case Builtin::BI__sync_fetch_and_add_8:
+    case Builtin::BI__sync_fetch_and_add_16:
+    case Builtin::BI__sync_fetch_and_sub:
+    case Builtin::BI__sync_fetch_and_sub_1:
+    case Builtin::BI__sync_fetch_and_sub_2:
+    case Builtin::BI__sync_fetch_and_sub_4:
+    case Builtin::BI__sync_fetch_and_sub_8:
+    case Builtin::BI__sync_fetch_and_sub_16:
+    case Builtin::BI__sync_fetch_and_or:
+    case Builtin::BI__sync_fetch_and_or_1:
+    case Builtin::BI__sync_fetch_and_or_2:
+    case Builtin::BI__sync_fetch_and_or_4:
+    case Builtin::BI__sync_fetch_and_or_8:
+    case Builtin::BI__sync_fetch_and_or_16:
+    case Builtin::BI__sync_fetch_and_and:
+    case Builtin::BI__sync_fetch_and_and_1:
+    case Builtin::BI__sync_fetch_and_and_2:
+    case Builtin::BI__sync_fetch_and_and_4:
+    case Builtin::BI__sync_fetch_and_and_8:
+    case Builtin::BI__sync_fetch_and_and_16:
+    case Builtin::BI__sync_fetch_and_xor:
+    case Builtin::BI__sync_fetch_and_xor_1:
+    case Builtin::BI__sync_fetch_and_xor_2:
+    case Builtin::BI__sync_fetch_and_xor_4:
+    case Builtin::BI__sync_fetch_and_xor_8:
+    case Builtin::BI__sync_fetch_and_xor_16:
+    case Builtin::BI__sync_fetch_and_nand:
+    case Builtin::BI__sync_fetch_and_nand_1:
+    case Builtin::BI__sync_fetch_and_nand_2:
+    case Builtin::BI__sync_fetch_and_nand_4:
+    case Builtin::BI__sync_fetch_and_nand_8:
+    case Builtin::BI__sync_fetch_and_nand_16:
+    case Builtin::BI__sync_add_and_fetch:
+    case Builtin::BI__sync_add_and_fetch_1:
+    case Builtin::BI__sync_add_and_fetch_2:
+    case Builtin::BI__sync_add_and_fetch_4:
+    case Builtin::BI__sync_add_and_fetch_8:
+    case Builtin::BI__sync_add_and_fetch_16:
+    case Builtin::BI__sync_sub_and_fetch:
+    case Builtin::BI__sync_sub_and_fetch_1:
+    case Builtin::BI__sync_sub_and_fetch_2:
+    case Builtin::BI__sync_sub_and_fetch_4:
+    case Builtin::BI__sync_sub_and_fetch_8:
+    case Builtin::BI__sync_sub_and_fetch_16:
+    case Builtin::BI__sync_and_and_fetch:
+    case Builtin::BI__sync_and_and_fetch_1:
+    case Builtin::BI__sync_and_and_fetch_2:
+    case Builtin::BI__sync_and_and_fetch_4:
+    case Builtin::BI__sync_and_and_fetch_8:
+    case Builtin::BI__sync_and_and_fetch_16:
+    case Builtin::BI__sync_or_and_fetch:
+    case Builtin::BI__sync_or_and_fetch_1:
+    case Builtin::BI__sync_or_and_fetch_2:
+    case Builtin::BI__sync_or_and_fetch_4:
+    case Builtin::BI__sync_or_and_fetch_8:
+    case Builtin::BI__sync_or_and_fetch_16:
+    case Builtin::BI__sync_xor_and_fetch:
+    case Builtin::BI__sync_xor_and_fetch_1:
+    case Builtin::BI__sync_xor_and_fetch_2:
+    case Builtin::BI__sync_xor_and_fetch_4:
+    case Builtin::BI__sync_xor_and_fetch_8:
+    case Builtin::BI__sync_xor_and_fetch_16:
+    case Builtin::BI__sync_nand_and_fetch:
+    case Builtin::BI__sync_nand_and_fetch_1:
+    case Builtin::BI__sync_nand_and_fetch_2:
+    case Builtin::BI__sync_nand_and_fetch_4:
+    case Builtin::BI__sync_nand_and_fetch_8:
+    case Builtin::BI__sync_nand_and_fetch_16:
+    case Builtin::BI__sync_val_compare_and_swap:
+    case Builtin::BI__sync_val_compare_and_swap_1:
+    case Builtin::BI__sync_val_compare_and_swap_2:
+    case Builtin::BI__sync_val_compare_and_swap_4:
+    case Builtin::BI__sync_val_compare_and_swap_8:
+    case Builtin::BI__sync_val_compare_and_swap_16:
+    case Builtin::BI__sync_bool_compare_and_swap:
+    case Builtin::BI__sync_bool_compare_and_swap_1:
+    case Builtin::BI__sync_bool_compare_and_swap_2:
+    case Builtin::BI__sync_bool_compare_and_swap_4:
+    case Builtin::BI__sync_bool_compare_and_swap_8:
+    case Builtin::BI__sync_bool_compare_and_swap_16:
+    case Builtin::BI__sync_lock_test_and_set:
+    case Builtin::BI__sync_lock_test_and_set_1:
+    case Builtin::BI__sync_lock_test_and_set_2:
+    case Builtin::BI__sync_lock_test_and_set_4:
+    case Builtin::BI__sync_lock_test_and_set_8:
+    case Builtin::BI__sync_lock_test_and_set_16:
+    case Builtin::BI__sync_lock_release:
+    case Builtin::BI__sync_lock_release_1:
+    case Builtin::BI__sync_lock_release_2:
+    case Builtin::BI__sync_lock_release_4:
+    case Builtin::BI__sync_lock_release_8:
+    case Builtin::BI__sync_lock_release_16:
+    case Builtin::BI__sync_swap:
+    case Builtin::BI__sync_swap_1:
+    case Builtin::BI__sync_swap_2:
+    case Builtin::BI__sync_swap_4:
+    case Builtin::BI__sync_swap_8:
+    case Builtin::BI__sync_swap_16:
+      return SemaBuiltinAtomicOverloaded(TheCallResult);
+    case Builtin::BI__sync_synchronize:
+      Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst)
+          << TheCall->getCallee()->getSourceRange();
       break;
-    if (!SizeOp->EvaluateKnownConstInt(Context).isZero())
-      CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
-    break;
-  }
+    case Builtin::BI__builtin_nontemporal_load:
+    case Builtin::BI__builtin_nontemporal_store:
+      return SemaBuiltinNontemporalOverloaded(TheCallResult);
+    case Builtin::BI__builtin_memcpy_inline: {
+      clang::Expr *SizeOp = TheCall->getArg(2);
+      // We warn about copying to or from `nullptr` pointers when `size` is
+      // greater than 0. When `size` is value dependent we cannot evaluate its
+      // value so we bail out.
+      if (SizeOp->isValueDependent())
+        break;
+      if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) {
+        CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
+        CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc());
+      }
+      break;
+    }
+    case Builtin::BI__builtin_memset_inline: {
+      clang::Expr *SizeOp = TheCall->getArg(2);
+      // We warn about filling to `nullptr` pointers when `size` is greater than
+      // 0. When `size` is value dependent we cannot evaluate its value so we
+      // bail out.
+      if (SizeOp->isValueDependent())
+        break;
+      if (!SizeOp->EvaluateKnownConstInt(Context).isZero())
+        CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
+      break;
+    }
 #define BUILTIN(ID, TYPE, ATTRS)
 #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
   case Builtin::BI##ID: \
@@ -3014,7 +3050,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
   }
 
   return TheCallResult;
-}
+  }
 
 // Get the valid immediate range for the specified NEON type code.
 static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) {
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 4710bd61a78e14..8f5ca271242d5b 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5952,6 +5952,35 @@ static void handleBuiltinAliasAttr(Sema &S, Decl *D,
   D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
 }
 
+static void handleElementwiseBuiltinAliasAttr(Sema &S, Decl *D,
+                                              const ParsedAttr &AL) {
+  if (!AL.isArgIdent(0)) {
+    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
+        << AL << 1 << AANT_ArgumentIdentifier;
+    return;
+  }
+
+  IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident;
+  unsigned BuiltinID = Ident->getBuiltinID();
+  StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
+
+  bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
+  bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
+  bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
+  bool IsHLSL = S.Context.getLangOpts().HLSL;
+  if ((IsAArch64 && !ArmSveAliasValid(S.Context, BuiltinID, AliasName)) ||
+      (IsARM && !ArmMveAliasValid(BuiltinID, AliasName) &&
+       !ArmCdeAliasValid(BuiltinID, AliasName)) ||
+      (IsRISCV && !RISCVAliasValid(BuiltinID, AliasName)) ||
+      (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL)) {
+    S.Diag(AL.getLoc(), diag::err_attribute_elementwise_builtin_alias) << AL;
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+                 ElementwiseBuiltinAliasAttr(S.Context, AL, Ident));
+}
+
 static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (!AL.hasParsedType()) {
     S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
@@ -9852,7 +9881,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
     handleBuiltinAliasAttr(S, D, AL);
     break;
   case ParsedAttr::AT_ElementwiseBuiltinAlias:
-    handleBuiltinAliasAttr(S, D, AL);
+    handleElementwiseBuiltinAliasAttr(S, D, AL);
     break;
 
   case ParsedAttr::AT_PreferredType:

>From 866007083a306bd4785579b691bbf99143bc0548 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 21 Mar 2024 11:43:18 -0700
Subject: [PATCH 4/7] IT WORKS ON CEIL!!!

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 4 ++--
 clang/lib/Sema/SemaChecking.cpp          | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index f646522e35e84c..1c8e4073026091 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -99,7 +99,7 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
 double2 abs(double2);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
 double3 abs(double3);
-_HLSL_ELEMENTWISE_BUILTIN_ALIAS(__builtin_elementwise_abs)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
 double4 abs(double4);
 
 //===----------------------------------------------------------------------===//
@@ -251,7 +251,7 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil)
 double2 ceil(double2);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil)
 double3 ceil(double3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil)
+_HLSL_ELEMENTWISE_BUILTIN_ALIAS(__builtin_ceil)
 double4 ceil(double4);
 
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index f60a38980549e9..c2621bdd2f9ce9 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2242,7 +2242,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
 
   // if the call has the elementwise attribute, then
   // make sure that an elementwise expr is emitted.
-  if (FDecl->hasAttr(Attr::AT_ElementwiseBuiltinAlias)) {
+  if (FDecl->hasAttr<ElementwiseBuiltinAliasAttr>()) {
     switch (FDecl->getNumParams()) {
     case 1: {
       if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
@@ -2272,7 +2272,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
       break;
     }
     }
-
+  }
     FPOptions FPO;
     switch (BuiltinID) {
     case Builtin::BI__builtin_cpu_supports:

>From 74e4c62bc4d2e3ad6ccf0fe5d7f83db7d309db30 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 21 Mar 2024 12:21:24 -0700
Subject: [PATCH 5/7] clang-format attempt

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h |   2 +-
 clang/lib/Sema/SemaChecking.cpp          | 606 +++++++++++------------
 2 files changed, 302 insertions(+), 306 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 1c8e4073026091..9ab34cc57ef322 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -18,7 +18,7 @@ namespace hlsl {
 
 #define _HLSL_BUILTIN_ALIAS(builtin)                                           \
   __attribute__((clang_builtin_alias(builtin)))
-#define _HLSL_ELEMENTWISE_BUILTIN_ALIAS(builtin)                                           \
+#define _HLSL_ELEMENTWISE_BUILTIN_ALIAS(builtin)                               \
   __attribute__((clang_elementwise_builtin_alias(builtin)))
 #define _HLSL_AVAILABILITY(environment, version)                               \
   __attribute__((availability(environment, introduced = version)))
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index c2621bdd2f9ce9..5460d32e10e343 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2239,10 +2239,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
       return true;
     ICEArguments &= ~(1 << ArgNo);
   }
-
   // if the call has the elementwise attribute, then
   // make sure that an elementwise expr is emitted.
-  if (FDecl->hasAttr<ElementwiseBuiltinAliasAttr>()) {
+  if (FDecl->hasAttr<ElementwiseBuiltinAlias>()) {
     switch (FDecl->getNumParams()) {
     case 1: {
       if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
@@ -2253,7 +2252,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
               *this, TheCall->getArg(0)->getBeginLoc(), ArgTy, 1))
         return ExprError();
       break;
-    }
     case 2: {
       if (SemaBuiltinElementwiseMath(TheCall))
         return ExprError();
@@ -2272,321 +2270,319 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
       break;
     }
     }
-  }
+    }
+
     FPOptions FPO;
-    switch (BuiltinID) {
-    case Builtin::BI__builtin_cpu_supports:
-    case Builtin::BI__builtin_cpu_is:
-      if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall,
-                         Context.getAuxTargetInfo(), BuiltinID))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_cpu_init:
-      if (!Context.getTargetInfo().supportsCpuInit()) {
-        Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
-            << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
-        return ExprError();
-      }
-      break;
-    case Builtin::BI__builtin___CFStringMakeConstantString:
-      // CFStringMakeConstantString is currently not implemented for GOFF (i.e.,
-      // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported
-      if (CheckBuiltinTargetNotInUnsupported(
-              *this, BuiltinID, TheCall,
-              {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
-        return ExprError();
-      assert(TheCall->getNumArgs() == 1 &&
-             "Wrong # arguments to builtin CFStringMakeConstantString");
-      if (CheckObjCString(TheCall->getArg(0)))
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_cpu_supports:
+  case Builtin::BI__builtin_cpu_is:
+    if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall,
+                       Context.getAuxTargetInfo(), BuiltinID))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_cpu_init:
+    if (!Context.getTargetInfo().supportsCpuInit()) {
+      Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
+          << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
+      return ExprError();
+    }
+    break;
+  case Builtin::BI__builtin___CFStringMakeConstantString:
+    // CFStringMakeConstantString is currently not implemented for GOFF (i.e.,
+    // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported
+    if (CheckBuiltinTargetNotInUnsupported(
+            *this, BuiltinID, TheCall,
+            {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
+      return ExprError();
+    assert(TheCall->getNumArgs() == 1 &&
+           "Wrong # arguments to builtin CFStringMakeConstantString");
+    if (CheckObjCString(TheCall->getArg(0)))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_ms_va_start:
+  case Builtin::BI__builtin_stdarg_start:
+  case Builtin::BI__builtin_va_start:
+    if (SemaBuiltinVAStart(BuiltinID, TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__va_start: {
+    switch (Context.getTargetInfo().getTriple().getArch()) {
+    case llvm::Triple::aarch64:
+    case llvm::Triple::arm:
+    case llvm::Triple::thumb:
+      if (SemaBuiltinVAStartARMMicrosoft(TheCall))
         return ExprError();
       break;
-    case Builtin::BI__builtin_ms_va_start:
-    case Builtin::BI__builtin_stdarg_start:
-    case Builtin::BI__builtin_va_start:
+    default:
       if (SemaBuiltinVAStart(BuiltinID, TheCall))
         return ExprError();
       break;
-    case Builtin::BI__va_start: {
-      switch (Context.getTargetInfo().getTriple().getArch()) {
-      case llvm::Triple::aarch64:
-      case llvm::Triple::arm:
-      case llvm::Triple::thumb:
-        if (SemaBuiltinVAStartARMMicrosoft(TheCall))
-          return ExprError();
-        break;
-      default:
-        if (SemaBuiltinVAStart(BuiltinID, TheCall))
-          return ExprError();
-        break;
-      }
-      break;
     }
+    break;
+  }
 
-    // The acquire, release, and no fence variants are ARM and AArch64 only.
-    case Builtin::BI_interlockedbittestandset_acq:
-    case Builtin::BI_interlockedbittestandset_rel:
-    case Builtin::BI_interlockedbittestandset_nf:
-    case Builtin::BI_interlockedbittestandreset_acq:
-    case Builtin::BI_interlockedbittestandreset_rel:
-    case Builtin::BI_interlockedbittestandreset_nf:
-      if (CheckBuiltinTargetInSupported(
-              *this, BuiltinID, TheCall,
-              {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
-        return ExprError();
-      break;
+  // The acquire, release, and no fence variants are ARM and AArch64 only.
+  case Builtin::BI_interlockedbittestandset_acq:
+  case Builtin::BI_interlockedbittestandset_rel:
+  case Builtin::BI_interlockedbittestandset_nf:
+  case Builtin::BI_interlockedbittestandreset_acq:
+  case Builtin::BI_interlockedbittestandreset_rel:
+  case Builtin::BI_interlockedbittestandreset_nf:
+    if (CheckBuiltinTargetInSupported(
+            *this, BuiltinID, TheCall,
+            {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
+      return ExprError();
+    break;
 
-    // The 64-bit bittest variants are x64, ARM, and AArch64 only.
-    case Builtin::BI_bittest64:
-    case Builtin::BI_bittestandcomplement64:
-    case Builtin::BI_bittestandreset64:
-    case Builtin::BI_bittestandset64:
-    case Builtin::BI_interlockedbittestandreset64:
-    case Builtin::BI_interlockedbittestandset64:
-      if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall,
-                                        {llvm::Triple::x86_64,
-                                         llvm::Triple::arm, llvm::Triple::thumb,
-                                         llvm::Triple::aarch64}))
-        return ExprError();
-      break;
+  // The 64-bit bittest variants are x64, ARM, and AArch64 only.
+  case Builtin::BI_bittest64:
+  case Builtin::BI_bittestandcomplement64:
+  case Builtin::BI_bittestandreset64:
+  case Builtin::BI_bittestandset64:
+  case Builtin::BI_interlockedbittestandreset64:
+  case Builtin::BI_interlockedbittestandset64:
+    if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall,
+                                      {llvm::Triple::x86_64, llvm::Triple::arm,
+                                       llvm::Triple::thumb,
+                                       llvm::Triple::aarch64}))
+      return ExprError();
+    break;
 
-    case Builtin::BI__builtin_set_flt_rounds:
-      if (CheckBuiltinTargetInSupported(
-              *this, BuiltinID, TheCall,
-              {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
-               llvm::Triple::thumb, llvm::Triple::aarch64}))
-        return ExprError();
-      break;
+  case Builtin::BI__builtin_set_flt_rounds:
+    if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall,
+                                      {llvm::Triple::x86, llvm::Triple::x86_64,
+                                       llvm::Triple::arm, llvm::Triple::thumb,
+                                       llvm::Triple::aarch64}))
+      return ExprError();
+    break;
 
-    case Builtin::BI__builtin_isgreater:
-    case Builtin::BI__builtin_isgreaterequal:
-    case Builtin::BI__builtin_isless:
-    case Builtin::BI__builtin_islessequal:
-    case Builtin::BI__builtin_islessgreater:
-    case Builtin::BI__builtin_isunordered:
-      if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_fpclassify:
-      if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_isfpclass:
-      if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_isfinite:
-    case Builtin::BI__builtin_isinf:
-    case Builtin::BI__builtin_isinf_sign:
-    case Builtin::BI__builtin_isnan:
-    case Builtin::BI__builtin_issignaling:
-    case Builtin::BI__builtin_isnormal:
-    case Builtin::BI__builtin_issubnormal:
-    case Builtin::BI__builtin_iszero:
-    case Builtin::BI__builtin_signbit:
-    case Builtin::BI__builtin_signbitf:
-    case Builtin::BI__builtin_signbitl:
-      if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_shufflevector:
-      return SemaBuiltinShuffleVector(TheCall);
-      // TheCall will be freed by the smart pointer here, but that's fine, since
-      // SemaBuiltinShuffleVector guts it, but then doesn't release it.
-    case Builtin::BI__builtin_prefetch:
-      if (SemaBuiltinPrefetch(TheCall))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_alloca_with_align:
-    case Builtin::BI__builtin_alloca_with_align_uninitialized:
-      if (SemaBuiltinAllocaWithAlign(TheCall))
-        return ExprError();
-      [[fallthrough]];
-    case Builtin::BI__builtin_alloca:
-    case Builtin::BI__builtin_alloca_uninitialized:
-      Diag(TheCall->getBeginLoc(), diag::warn_alloca)
-          << TheCall->getDirectCallee();
-      break;
-    case Builtin::BI__arithmetic_fence:
-      if (SemaBuiltinArithmeticFence(TheCall))
-        return ExprError();
-      break;
-    case Builtin::BI__assume:
-    case Builtin::BI__builtin_assume:
-      if (SemaBuiltinAssume(TheCall))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_assume_aligned:
-      if (SemaBuiltinAssumeAligned(TheCall))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_dynamic_object_size:
-    case Builtin::BI__builtin_object_size:
-      if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_longjmp:
-      if (SemaBuiltinLongjmp(TheCall))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_setjmp:
-      if (SemaBuiltinSetjmp(TheCall))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_classify_type:
-      if (checkArgCount(*this, TheCall, 1))
-        return true;
-      TheCall->setType(Context.IntTy);
-      break;
-    case Builtin::BI__builtin_complex:
-      if (SemaBuiltinComplex(TheCall))
-        return ExprError();
-      break;
-    case Builtin::BI__builtin_constant_p: {
-      if (checkArgCount(*this, TheCall, 1))
-        return true;
-      ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));
-      if (Arg.isInvalid())
-        return true;
-      TheCall->setArg(0, Arg.get());
-      TheCall->setType(Context.IntTy);
-      break;
-    }
-    case Builtin::BI__builtin_launder:
-      return SemaBuiltinLaunder(*this, TheCall);
-    case Builtin::BI__sync_fetch_and_add:
-    case Builtin::BI__sync_fetch_and_add_1:
-    case Builtin::BI__sync_fetch_and_add_2:
-    case Builtin::BI__sync_fetch_and_add_4:
-    case Builtin::BI__sync_fetch_and_add_8:
-    case Builtin::BI__sync_fetch_and_add_16:
-    case Builtin::BI__sync_fetch_and_sub:
-    case Builtin::BI__sync_fetch_and_sub_1:
-    case Builtin::BI__sync_fetch_and_sub_2:
-    case Builtin::BI__sync_fetch_and_sub_4:
-    case Builtin::BI__sync_fetch_and_sub_8:
-    case Builtin::BI__sync_fetch_and_sub_16:
-    case Builtin::BI__sync_fetch_and_or:
-    case Builtin::BI__sync_fetch_and_or_1:
-    case Builtin::BI__sync_fetch_and_or_2:
-    case Builtin::BI__sync_fetch_and_or_4:
-    case Builtin::BI__sync_fetch_and_or_8:
-    case Builtin::BI__sync_fetch_and_or_16:
-    case Builtin::BI__sync_fetch_and_and:
-    case Builtin::BI__sync_fetch_and_and_1:
-    case Builtin::BI__sync_fetch_and_and_2:
-    case Builtin::BI__sync_fetch_and_and_4:
-    case Builtin::BI__sync_fetch_and_and_8:
-    case Builtin::BI__sync_fetch_and_and_16:
-    case Builtin::BI__sync_fetch_and_xor:
-    case Builtin::BI__sync_fetch_and_xor_1:
-    case Builtin::BI__sync_fetch_and_xor_2:
-    case Builtin::BI__sync_fetch_and_xor_4:
-    case Builtin::BI__sync_fetch_and_xor_8:
-    case Builtin::BI__sync_fetch_and_xor_16:
-    case Builtin::BI__sync_fetch_and_nand:
-    case Builtin::BI__sync_fetch_and_nand_1:
-    case Builtin::BI__sync_fetch_and_nand_2:
-    case Builtin::BI__sync_fetch_and_nand_4:
-    case Builtin::BI__sync_fetch_and_nand_8:
-    case Builtin::BI__sync_fetch_and_nand_16:
-    case Builtin::BI__sync_add_and_fetch:
-    case Builtin::BI__sync_add_and_fetch_1:
-    case Builtin::BI__sync_add_and_fetch_2:
-    case Builtin::BI__sync_add_and_fetch_4:
-    case Builtin::BI__sync_add_and_fetch_8:
-    case Builtin::BI__sync_add_and_fetch_16:
-    case Builtin::BI__sync_sub_and_fetch:
-    case Builtin::BI__sync_sub_and_fetch_1:
-    case Builtin::BI__sync_sub_and_fetch_2:
-    case Builtin::BI__sync_sub_and_fetch_4:
-    case Builtin::BI__sync_sub_and_fetch_8:
-    case Builtin::BI__sync_sub_and_fetch_16:
-    case Builtin::BI__sync_and_and_fetch:
-    case Builtin::BI__sync_and_and_fetch_1:
-    case Builtin::BI__sync_and_and_fetch_2:
-    case Builtin::BI__sync_and_and_fetch_4:
-    case Builtin::BI__sync_and_and_fetch_8:
-    case Builtin::BI__sync_and_and_fetch_16:
-    case Builtin::BI__sync_or_and_fetch:
-    case Builtin::BI__sync_or_and_fetch_1:
-    case Builtin::BI__sync_or_and_fetch_2:
-    case Builtin::BI__sync_or_and_fetch_4:
-    case Builtin::BI__sync_or_and_fetch_8:
-    case Builtin::BI__sync_or_and_fetch_16:
-    case Builtin::BI__sync_xor_and_fetch:
-    case Builtin::BI__sync_xor_and_fetch_1:
-    case Builtin::BI__sync_xor_and_fetch_2:
-    case Builtin::BI__sync_xor_and_fetch_4:
-    case Builtin::BI__sync_xor_and_fetch_8:
-    case Builtin::BI__sync_xor_and_fetch_16:
-    case Builtin::BI__sync_nand_and_fetch:
-    case Builtin::BI__sync_nand_and_fetch_1:
-    case Builtin::BI__sync_nand_and_fetch_2:
-    case Builtin::BI__sync_nand_and_fetch_4:
-    case Builtin::BI__sync_nand_and_fetch_8:
-    case Builtin::BI__sync_nand_and_fetch_16:
-    case Builtin::BI__sync_val_compare_and_swap:
-    case Builtin::BI__sync_val_compare_and_swap_1:
-    case Builtin::BI__sync_val_compare_and_swap_2:
-    case Builtin::BI__sync_val_compare_and_swap_4:
-    case Builtin::BI__sync_val_compare_and_swap_8:
-    case Builtin::BI__sync_val_compare_and_swap_16:
-    case Builtin::BI__sync_bool_compare_and_swap:
-    case Builtin::BI__sync_bool_compare_and_swap_1:
-    case Builtin::BI__sync_bool_compare_and_swap_2:
-    case Builtin::BI__sync_bool_compare_and_swap_4:
-    case Builtin::BI__sync_bool_compare_and_swap_8:
-    case Builtin::BI__sync_bool_compare_and_swap_16:
-    case Builtin::BI__sync_lock_test_and_set:
-    case Builtin::BI__sync_lock_test_and_set_1:
-    case Builtin::BI__sync_lock_test_and_set_2:
-    case Builtin::BI__sync_lock_test_and_set_4:
-    case Builtin::BI__sync_lock_test_and_set_8:
-    case Builtin::BI__sync_lock_test_and_set_16:
-    case Builtin::BI__sync_lock_release:
-    case Builtin::BI__sync_lock_release_1:
-    case Builtin::BI__sync_lock_release_2:
-    case Builtin::BI__sync_lock_release_4:
-    case Builtin::BI__sync_lock_release_8:
-    case Builtin::BI__sync_lock_release_16:
-    case Builtin::BI__sync_swap:
-    case Builtin::BI__sync_swap_1:
-    case Builtin::BI__sync_swap_2:
-    case Builtin::BI__sync_swap_4:
-    case Builtin::BI__sync_swap_8:
-    case Builtin::BI__sync_swap_16:
-      return SemaBuiltinAtomicOverloaded(TheCallResult);
-    case Builtin::BI__sync_synchronize:
-      Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst)
-          << TheCall->getCallee()->getSourceRange();
-      break;
-    case Builtin::BI__builtin_nontemporal_load:
-    case Builtin::BI__builtin_nontemporal_store:
-      return SemaBuiltinNontemporalOverloaded(TheCallResult);
-    case Builtin::BI__builtin_memcpy_inline: {
-      clang::Expr *SizeOp = TheCall->getArg(2);
-      // We warn about copying to or from `nullptr` pointers when `size` is
-      // greater than 0. When `size` is value dependent we cannot evaluate its
-      // value so we bail out.
-      if (SizeOp->isValueDependent())
-        break;
-      if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) {
-        CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
-        CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc());
-      }
+  case Builtin::BI__builtin_isgreater:
+  case Builtin::BI__builtin_isgreaterequal:
+  case Builtin::BI__builtin_isless:
+  case Builtin::BI__builtin_islessequal:
+  case Builtin::BI__builtin_islessgreater:
+  case Builtin::BI__builtin_isunordered:
+    if (SemaBuiltinUnorderedCompare(TheCall, BuiltinID))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_fpclassify:
+    if (SemaBuiltinFPClassification(TheCall, 6, BuiltinID))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_isfpclass:
+    if (SemaBuiltinFPClassification(TheCall, 2, BuiltinID))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_isfinite:
+  case Builtin::BI__builtin_isinf:
+  case Builtin::BI__builtin_isinf_sign:
+  case Builtin::BI__builtin_isnan:
+  case Builtin::BI__builtin_issignaling:
+  case Builtin::BI__builtin_isnormal:
+  case Builtin::BI__builtin_issubnormal:
+  case Builtin::BI__builtin_iszero:
+  case Builtin::BI__builtin_signbit:
+  case Builtin::BI__builtin_signbitf:
+  case Builtin::BI__builtin_signbitl:
+    if (SemaBuiltinFPClassification(TheCall, 1, BuiltinID))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_shufflevector:
+    return SemaBuiltinShuffleVector(TheCall);
+    // TheCall will be freed by the smart pointer here, but that's fine, since
+    // SemaBuiltinShuffleVector guts it, but then doesn't release it.
+  case Builtin::BI__builtin_prefetch:
+    if (SemaBuiltinPrefetch(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_alloca_with_align:
+  case Builtin::BI__builtin_alloca_with_align_uninitialized:
+    if (SemaBuiltinAllocaWithAlign(TheCall))
+      return ExprError();
+    [[fallthrough]];
+  case Builtin::BI__builtin_alloca:
+  case Builtin::BI__builtin_alloca_uninitialized:
+    Diag(TheCall->getBeginLoc(), diag::warn_alloca)
+        << TheCall->getDirectCallee();
+    break;
+  case Builtin::BI__arithmetic_fence:
+    if (SemaBuiltinArithmeticFence(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__assume:
+  case Builtin::BI__builtin_assume:
+    if (SemaBuiltinAssume(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_assume_aligned:
+    if (SemaBuiltinAssumeAligned(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_dynamic_object_size:
+  case Builtin::BI__builtin_object_size:
+    if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_longjmp:
+    if (SemaBuiltinLongjmp(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_setjmp:
+    if (SemaBuiltinSetjmp(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_classify_type:
+    if (checkArgCount(*this, TheCall, 1)) return true;
+    TheCall->setType(Context.IntTy);
+    break;
+  case Builtin::BI__builtin_complex:
+    if (SemaBuiltinComplex(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_constant_p: {
+    if (checkArgCount(*this, TheCall, 1)) return true;
+    ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));
+    if (Arg.isInvalid()) return true;
+    TheCall->setArg(0, Arg.get());
+    TheCall->setType(Context.IntTy);
+    break;
+  }
+  case Builtin::BI__builtin_launder:
+    return SemaBuiltinLaunder(*this, TheCall);
+  case Builtin::BI__sync_fetch_and_add:
+  case Builtin::BI__sync_fetch_and_add_1:
+  case Builtin::BI__sync_fetch_and_add_2:
+  case Builtin::BI__sync_fetch_and_add_4:
+  case Builtin::BI__sync_fetch_and_add_8:
+  case Builtin::BI__sync_fetch_and_add_16:
+  case Builtin::BI__sync_fetch_and_sub:
+  case Builtin::BI__sync_fetch_and_sub_1:
+  case Builtin::BI__sync_fetch_and_sub_2:
+  case Builtin::BI__sync_fetch_and_sub_4:
+  case Builtin::BI__sync_fetch_and_sub_8:
+  case Builtin::BI__sync_fetch_and_sub_16:
+  case Builtin::BI__sync_fetch_and_or:
+  case Builtin::BI__sync_fetch_and_or_1:
+  case Builtin::BI__sync_fetch_and_or_2:
+  case Builtin::BI__sync_fetch_and_or_4:
+  case Builtin::BI__sync_fetch_and_or_8:
+  case Builtin::BI__sync_fetch_and_or_16:
+  case Builtin::BI__sync_fetch_and_and:
+  case Builtin::BI__sync_fetch_and_and_1:
+  case Builtin::BI__sync_fetch_and_and_2:
+  case Builtin::BI__sync_fetch_and_and_4:
+  case Builtin::BI__sync_fetch_and_and_8:
+  case Builtin::BI__sync_fetch_and_and_16:
+  case Builtin::BI__sync_fetch_and_xor:
+  case Builtin::BI__sync_fetch_and_xor_1:
+  case Builtin::BI__sync_fetch_and_xor_2:
+  case Builtin::BI__sync_fetch_and_xor_4:
+  case Builtin::BI__sync_fetch_and_xor_8:
+  case Builtin::BI__sync_fetch_and_xor_16:
+  case Builtin::BI__sync_fetch_and_nand:
+  case Builtin::BI__sync_fetch_and_nand_1:
+  case Builtin::BI__sync_fetch_and_nand_2:
+  case Builtin::BI__sync_fetch_and_nand_4:
+  case Builtin::BI__sync_fetch_and_nand_8:
+  case Builtin::BI__sync_fetch_and_nand_16:
+  case Builtin::BI__sync_add_and_fetch:
+  case Builtin::BI__sync_add_and_fetch_1:
+  case Builtin::BI__sync_add_and_fetch_2:
+  case Builtin::BI__sync_add_and_fetch_4:
+  case Builtin::BI__sync_add_and_fetch_8:
+  case Builtin::BI__sync_add_and_fetch_16:
+  case Builtin::BI__sync_sub_and_fetch:
+  case Builtin::BI__sync_sub_and_fetch_1:
+  case Builtin::BI__sync_sub_and_fetch_2:
+  case Builtin::BI__sync_sub_and_fetch_4:
+  case Builtin::BI__sync_sub_and_fetch_8:
+  case Builtin::BI__sync_sub_and_fetch_16:
+  case Builtin::BI__sync_and_and_fetch:
+  case Builtin::BI__sync_and_and_fetch_1:
+  case Builtin::BI__sync_and_and_fetch_2:
+  case Builtin::BI__sync_and_and_fetch_4:
+  case Builtin::BI__sync_and_and_fetch_8:
+  case Builtin::BI__sync_and_and_fetch_16:
+  case Builtin::BI__sync_or_and_fetch:
+  case Builtin::BI__sync_or_and_fetch_1:
+  case Builtin::BI__sync_or_and_fetch_2:
+  case Builtin::BI__sync_or_and_fetch_4:
+  case Builtin::BI__sync_or_and_fetch_8:
+  case Builtin::BI__sync_or_and_fetch_16:
+  case Builtin::BI__sync_xor_and_fetch:
+  case Builtin::BI__sync_xor_and_fetch_1:
+  case Builtin::BI__sync_xor_and_fetch_2:
+  case Builtin::BI__sync_xor_and_fetch_4:
+  case Builtin::BI__sync_xor_and_fetch_8:
+  case Builtin::BI__sync_xor_and_fetch_16:
+  case Builtin::BI__sync_nand_and_fetch:
+  case Builtin::BI__sync_nand_and_fetch_1:
+  case Builtin::BI__sync_nand_and_fetch_2:
+  case Builtin::BI__sync_nand_and_fetch_4:
+  case Builtin::BI__sync_nand_and_fetch_8:
+  case Builtin::BI__sync_nand_and_fetch_16:
+  case Builtin::BI__sync_val_compare_and_swap:
+  case Builtin::BI__sync_val_compare_and_swap_1:
+  case Builtin::BI__sync_val_compare_and_swap_2:
+  case Builtin::BI__sync_val_compare_and_swap_4:
+  case Builtin::BI__sync_val_compare_and_swap_8:
+  case Builtin::BI__sync_val_compare_and_swap_16:
+  case Builtin::BI__sync_bool_compare_and_swap:
+  case Builtin::BI__sync_bool_compare_and_swap_1:
+  case Builtin::BI__sync_bool_compare_and_swap_2:
+  case Builtin::BI__sync_bool_compare_and_swap_4:
+  case Builtin::BI__sync_bool_compare_and_swap_8:
+  case Builtin::BI__sync_bool_compare_and_swap_16:
+  case Builtin::BI__sync_lock_test_and_set:
+  case Builtin::BI__sync_lock_test_and_set_1:
+  case Builtin::BI__sync_lock_test_and_set_2:
+  case Builtin::BI__sync_lock_test_and_set_4:
+  case Builtin::BI__sync_lock_test_and_set_8:
+  case Builtin::BI__sync_lock_test_and_set_16:
+  case Builtin::BI__sync_lock_release:
+  case Builtin::BI__sync_lock_release_1:
+  case Builtin::BI__sync_lock_release_2:
+  case Builtin::BI__sync_lock_release_4:
+  case Builtin::BI__sync_lock_release_8:
+  case Builtin::BI__sync_lock_release_16:
+  case Builtin::BI__sync_swap:
+  case Builtin::BI__sync_swap_1:
+  case Builtin::BI__sync_swap_2:
+  case Builtin::BI__sync_swap_4:
+  case Builtin::BI__sync_swap_8:
+  case Builtin::BI__sync_swap_16:
+    return SemaBuiltinAtomicOverloaded(TheCallResult);
+  case Builtin::BI__sync_synchronize:
+    Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst)
+        << TheCall->getCallee()->getSourceRange();
+    break;
+  case Builtin::BI__builtin_nontemporal_load:
+  case Builtin::BI__builtin_nontemporal_store:
+    return SemaBuiltinNontemporalOverloaded(TheCallResult);
+  case Builtin::BI__builtin_memcpy_inline: {
+    clang::Expr *SizeOp = TheCall->getArg(2);
+    // We warn about copying to or from `nullptr` pointers when `size` is
+    // greater than 0. When `size` is value dependent we cannot evaluate its
+    // value so we bail out.
+    if (SizeOp->isValueDependent())
       break;
+    if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) {
+      CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
+      CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc());
     }
-    case Builtin::BI__builtin_memset_inline: {
-      clang::Expr *SizeOp = TheCall->getArg(2);
-      // We warn about filling to `nullptr` pointers when `size` is greater than
-      // 0. When `size` is value dependent we cannot evaluate its value so we
-      // bail out.
-      if (SizeOp->isValueDependent())
-        break;
-      if (!SizeOp->EvaluateKnownConstInt(Context).isZero())
-        CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
+    break;
+  }
+  case Builtin::BI__builtin_memset_inline: {
+    clang::Expr *SizeOp = TheCall->getArg(2);
+    // We warn about filling to `nullptr` pointers when `size` is greater than
+    // 0. When `size` is value dependent we cannot evaluate its value so we bail
+    // out.
+    if (SizeOp->isValueDependent())
       break;
-    }
+    if (!SizeOp->EvaluateKnownConstInt(Context).isZero())
+      CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
+    break;
+  }
 #define BUILTIN(ID, TYPE, ATTRS)
 #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
   case Builtin::BI##ID: \
@@ -3050,7 +3046,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
   }
 
   return TheCallResult;
-  }
+}
 
 // Get the valid immediate range for the specified NEON type code.
 static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) {

>From 3b80e4f4d29dccacb9acd2d11dd517f7857d661b Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 21 Mar 2024 13:01:18 -0700
Subject: [PATCH 6/7] add a brace

---
 clang/lib/Sema/SemaChecking.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5460d32e10e343..a4b9ab53527a48 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2241,7 +2241,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
   }
   // if the call has the elementwise attribute, then
   // make sure that an elementwise expr is emitted.
-  if (FDecl->hasAttr<ElementwiseBuiltinAlias>()) {
+  if (FDecl->hasAttr<ElementwiseBuiltinAliasAttr>()) {
     switch (FDecl->getNumParams()) {
     case 1: {
       if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
@@ -2252,6 +2252,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
               *this, TheCall->getArg(0)->getBeginLoc(), ArgTy, 1))
         return ExprError();
       break;
+    }
     case 2: {
       if (SemaBuiltinElementwiseMath(TheCall))
         return ExprError();
@@ -2270,9 +2271,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
       break;
     }
     }
-    }
+  }
 
-    FPOptions FPO;
+  FPOptions FPO;
   switch (BuiltinID) {
   case Builtin::BI__builtin_cpu_supports:
   case Builtin::BI__builtin_cpu_is:

>From 388aa3cdbf1335cfc55d5977d433935daf122332 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 26 Mar 2024 11:00:45 -0700
Subject: [PATCH 7/7] add new attr to attr test, fix trailing whitespace

---
 clang/include/clang/Basic/AttrDocs.td                           | 2 +-
 clang/test/Misc/pragma-attribute-supported-attributes-list.test | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 7ce83bc881f064..37dfd84d7da9fe 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5469,7 +5469,7 @@ def ElementwiseBuiltinAliasDocs : Documentation {
 This attribute is used in the implementation of the C intrinsics.
 It allows the C intrinsic functions to be declared using the names defined
 in target builtins, and still be recognized as clang builtins equivalent to the
-underlying name. It also declares that the given C intrinsic can accept 
+underlying name. It also declares that the given C intrinsic can accept
 vector arguments. For example, ``hlsl_intrinsics.h`` declares the function ``abs``
 with ``__attribute__((clang_elementwise_builtin_alias(__builtin_abs)))``.
 This ensures that both functions are recognized as that clang builtin,
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index ec84ebdc6abe7b..bb8104a26578b6 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -4,6 +4,7 @@
 
 // CHECK: #pragma clang attribute supports the following attributes:
 // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
+// CHECK-NEXT: AMDGPUMaxNumWorkGroups (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUWavesPerEU (SubjectMatchRule_function)
@@ -68,6 +69,7 @@
 // CHECK-NEXT: DiagnoseAsBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: DisableSanitizerInstrumentation (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: DisableTailCalls (SubjectMatchRule_function, SubjectMatchRule_objc_method)
+// CHECK-NEXT: ElementwiseBuiltinAlias (SubjectMatchRule_function)
 // CHECK-NEXT: EnableIf (SubjectMatchRule_function)
 // CHECK-NEXT: EnforceTCB (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: EnforceTCBLeaf (SubjectMatchRule_function, SubjectMatchRule_objc_method)



More information about the cfe-commits mailing list