[clang] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests (PR #73760)

2023-11-29 Thread via cfe-commits

https://github.com/zeroomega created 
https://github.com/llvm/llvm-project/pull/73760

This patch explicitly set C++23 in libcxx tests to avoid a test breakage caused 
by removal of codecvt.

>From fc6f7dec3769ce748a097749dd5094081f113eb4 Mon Sep 17 00:00:00 2001
From: Haowei Wu 
Date: Wed, 29 Nov 2023 00:00:53 -0800
Subject: [PATCH] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests

This patch explicitly set C++23 in libcxx tests to avoid a test
breakage caused by removal of codecvt.
---
 clang/cmake/caches/Fuchsia-stage2.cmake | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake 
b/clang/cmake/caches/Fuchsia-stage2.cmake
index 4b9085d99378c6f..57761ef194976bd 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -28,6 +28,7 @@ set(LLVM_STATIC_LINK_CXX_STDLIB ON CACHE BOOL "")
 set(LLVM_USE_RELATIVE_PATHS_IN_FILES ON CACHE BOOL "")
 set(LLDB_ENABLE_CURSES OFF CACHE BOOL "")
 set(LLDB_ENABLE_LIBEDIT OFF CACHE BOOL "")
+set(LIBCXX_TEST_PARAMS "std=c++23" CACHE STRING "")
 
 if(WIN32)
   set(FUCHSIA_DISABLE_DRIVER_BUILD ON)

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests (PR #73760)

2023-11-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Haowei (zeroomega)


Changes

This patch explicitly set C++23 in libcxx tests to avoid a test breakage caused 
by removal of codecvt.

---
Full diff: https://github.com/llvm/llvm-project/pull/73760.diff


1 Files Affected:

- (modified) clang/cmake/caches/Fuchsia-stage2.cmake (+1) 


``diff
diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake 
b/clang/cmake/caches/Fuchsia-stage2.cmake
index 4b9085d99378c6f..57761ef194976bd 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -28,6 +28,7 @@ set(LLVM_STATIC_LINK_CXX_STDLIB ON CACHE BOOL "")
 set(LLVM_USE_RELATIVE_PATHS_IN_FILES ON CACHE BOOL "")
 set(LLDB_ENABLE_CURSES OFF CACHE BOOL "")
 set(LLDB_ENABLE_LIBEDIT OFF CACHE BOOL "")
+set(LIBCXX_TEST_PARAMS "std=c++23" CACHE STRING "")
 
 if(WIN32)
   set(FUCHSIA_DISABLE_DRIVER_BUILD ON)

``




https://github.com/llvm/llvm-project/pull/73760
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests (PR #73760)

2023-11-29 Thread via cfe-commits

zeroomega wrote:

We still need PR #73679 landed to clear build failures though.

https://github.com/llvm/llvm-project/pull/73760
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests (PR #73760)

2023-11-29 Thread Petr Hosek via cfe-commits


@@ -28,6 +28,7 @@ set(LLVM_STATIC_LINK_CXX_STDLIB ON CACHE BOOL "")
 set(LLVM_USE_RELATIVE_PATHS_IN_FILES ON CACHE BOOL "")
 set(LLDB_ENABLE_CURSES OFF CACHE BOOL "")
 set(LLDB_ENABLE_LIBEDIT OFF CACHE BOOL "")
+set(LIBCXX_TEST_PARAMS "std=c++23" CACHE STRING "")

petrhosek wrote:

This needs to be set separately for all targets, i.e. 
`RUNTIMES_${target}_LIBCXX_TEST_PARAMS`, `LIBCXX_TEST_PARAMS` should be only 
set for Darwin.

https://github.com/llvm/llvm-project/pull/73760
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests (PR #73760)

2023-11-29 Thread via cfe-commits

https://github.com/zeroomega updated 
https://github.com/llvm/llvm-project/pull/73760

>From 24f78f125b4f7a9ea4f3488d0acc396b510c86c8 Mon Sep 17 00:00:00 2001
From: Haowei Wu 
Date: Wed, 29 Nov 2023 00:00:53 -0800
Subject: [PATCH] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests

This patch explicitly set C++23 in libcxx tests to avoid a test
breakage caused by removal of codecvt.
---
 clang/cmake/caches/Fuchsia-stage2.cmake | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake 
b/clang/cmake/caches/Fuchsia-stage2.cmake
index 4b9085d99378c6f..ffd7e418ccaeee5 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -136,6 +136,7 @@ if(WIN32 OR LLVM_WINSYSROOT)
   set(RUNTIMES_${target}_CMAKE_EXE_LINKER_FLAGS ${WINDOWS_LINK_FLAGS} CACHE 
STRING "")
   set(RUNTIMES_${target}_CMAKE_SHARED_LINKER_FLAGS ${WINDOWS_LINK_FLAGS} CACHE 
STRING "")
   set(RUNTIMES_${target}_CMAKE_MODULE_LINKER_FLAGS ${WINDOWS_LINK_FLAGS} CACHE 
STRING "")
+  set(RUNTIMES_${target}_LIBCXX_TEST_PARAMS "std=c++23" CACHE STRING "")
 endif()
 
 foreach(target 
aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unknown-linux-gnu;riscv64-unknown-linux-gnu;x86_64-unknown-linux-gnu)

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests (PR #73760)

2023-11-29 Thread via cfe-commits


@@ -28,6 +28,7 @@ set(LLVM_STATIC_LINK_CXX_STDLIB ON CACHE BOOL "")
 set(LLVM_USE_RELATIVE_PATHS_IN_FILES ON CACHE BOOL "")
 set(LLDB_ENABLE_CURSES OFF CACHE BOOL "")
 set(LLDB_ENABLE_LIBEDIT OFF CACHE BOOL "")
+set(LIBCXX_TEST_PARAMS "std=c++23" CACHE STRING "")

zeroomega wrote:

You are correct. I have set `set(RUNTIMES_${target}_LIBCXX_TEST_PARAMS 
"std=c++23" CACHE STRING "")` in windows runtime target in patch 
24f78f125b4f7a9ea4f3488d0acc396b510c86c8 . Since these are windows only tests.

https://github.com/llvm/llvm-project/pull/73760
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer]:fix valistChecker false negative in windows platform (PR #72951)

2023-11-29 Thread via cfe-commits

https://github.com/mzyKi updated https://github.com/llvm/llvm-project/pull/72951

>From e62698df942c547f287f0e0fd5863d746d597f53 Mon Sep 17 00:00:00 2001
From: miaozhiyuan 
Date: Tue, 21 Nov 2023 12:07:35 +0800
Subject: [PATCH] [analyzer]:fix valistChecker false negative in windows
 platform

---
 .../StaticAnalyzer/Checkers/ValistChecker.cpp | 51 +++
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
index 2d1b873abf73f09..0ab018af1ed549b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -25,10 +25,13 @@ using namespace ento;
 REGISTER_SET_WITH_PROGRAMSTATE(InitializedVALists, const MemRegion *)
 
 namespace {
+const StringRef Valist = "va_list";
+
 typedef SmallVector RegionVector;
 
-class ValistChecker : public Checker,
- check::DeadSymbols> {
+class ValistChecker
+: public Checker,
+ check::PreStmt, check::DeadSymbols> {
   mutable std::unique_ptr BT_leakedvalist, BT_uninitaccess;
 
   struct VAListAccepter {
@@ -49,11 +52,13 @@ class ValistChecker : public Checker,
   bool ChecksEnabled[CK_NumCheckKinds] = {false};
   CheckerNameRef CheckNames[CK_NumCheckKinds];
 
+  void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
   void checkPreStmt(const VAArgExpr *VAA, CheckerContext &C) const;
-  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
+  bool evalCall(const CallEvent &Call, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
 
 private:
+  bool isWinValistType(const VarDecl *VD) const;
   const MemRegion *getVAListAsRegion(SVal SV, const Expr *VAExpr,
  bool &IsSymbolic, CheckerContext &C) 
const;
   const ExplodedNode *getStartCallSite(const ExplodedNode *N,
@@ -122,10 +127,9 @@ const CallDescription 
ValistChecker::VaStart({"__builtin_va_start"}, /*Args=*/2,
 ValistChecker::VaEnd({"__builtin_va_end"}, 1);
 } // end anonymous namespace
 
-void ValistChecker::checkPreCall(const CallEvent &Call,
- CheckerContext &C) const {
+bool ValistChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {
   if (!Call.isGlobalCFunction())
-return;
+return false;
   if (VaStart.matches(Call))
 checkVAListStartCall(Call, C, false);
   else if (VaCopy.matches(Call))
@@ -141,15 +145,15 @@ void ValistChecker::checkPreCall(const CallEvent &Call,
   getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos),
 Call.getArgExpr(FuncInfo.VAListPos), Symbolic, C);
   if (!VAList)
-return;
+return false;
 
   if (C.getState()->contains(VAList))
-return;
+return false;
 
   // We did not see va_start call, but the source of the region is unknown.
   // Be conservative and assume the best.
   if (Symbolic)
-return;
+return false;
 
   SmallString<80> Errmsg("Function '");
   Errmsg += FuncInfo.Func.getFunctionName();
@@ -158,6 +162,35 @@ void ValistChecker::checkPreCall(const CallEvent &Call,
   break;
 }
   }
+  return C.isDifferent();
+}
+
+bool ValistChecker::isWinValistType(const VarDecl *VD) const {
+  ASTContext &Ctx = VD->getASTContext();
+  QualType T = VD->getType();
+  if (T.isNull()) {
+return false;
+  }
+  if (!Valist.equals(T.getAsString())) {
+return false;
+  }
+  return T.getDesugaredType(Ctx)->isPointerType() &&
+ T.getDesugaredType(Ctx)->getPointeeType()->isCharType();
+}
+
+void ValistChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
+  for (const auto *I : DS->decls()) {
+const auto *VD = dyn_cast(I);
+if (nullptr == VD || !isWinValistType(VD)) {
+  continue;
+}
+ProgramStateRef State = C.getState();
+const VarRegion *VR = State->getRegion(VD, C.getLocationContext());
+SValBuilder &SVB = C.getSValBuilder();
+State = State->bindLoc(State->getLValue(VD, C.getLocationContext()),
+   SVB.makeLoc(VR), C.getLocationContext());
+C.addTransition(State);
+  }
 }
 
 const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E,

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer]:fix valistChecker false negative in windows platform (PR #72951)

2023-11-29 Thread via cfe-commits

https://github.com/mzyKi edited https://github.com/llvm/llvm-project/pull/72951
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer]:fix valistChecker false negative in windows platform (PR #72951)

2023-11-29 Thread via cfe-commits

https://github.com/mzyKi edited https://github.com/llvm/llvm-project/pull/72951
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Fuchsia] Explicitly set C++ standard C++23 in libcxx tests (PR #73760)

2023-11-29 Thread Petr Hosek via cfe-commits


@@ -136,6 +136,7 @@ if(WIN32 OR LLVM_WINSYSROOT)
   set(RUNTIMES_${target}_CMAKE_EXE_LINKER_FLAGS ${WINDOWS_LINK_FLAGS} CACHE 
STRING "")
   set(RUNTIMES_${target}_CMAKE_SHARED_LINKER_FLAGS ${WINDOWS_LINK_FLAGS} CACHE 
STRING "")
   set(RUNTIMES_${target}_CMAKE_MODULE_LINKER_FLAGS ${WINDOWS_LINK_FLAGS} CACHE 
STRING "")
+  set(RUNTIMES_${target}_LIBCXX_TEST_PARAMS "std=c++23" CACHE STRING "")

petrhosek wrote:

This is just a nit, but can you move this next to the other `*_LIBCXX_*` flags 
in this block?

https://github.com/llvm/llvm-project/pull/73760
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread Brandon Wu via cfe-commits

https://github.com/4vtomat created 
https://github.com/llvm/llvm-project/pull/73765

Extend the multi-lib re-use selection mechanism for RISC-V.
This funciton will try to re-use multi-lib if they are compatible.
Definition of compatible:
  - ABI must be the same.
  - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
is a subset of march=rv32imc.
  - march that contains atomic extension can't reuse multi-lib that
doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
march=rv32ima are not compatible, because software and hardware
atomic operation can't work together correctly.


>From 4f6500b9cc359522e399ef0965f01ff820d7cd54 Mon Sep 17 00:00:00 2001
From: Brandon Wu 
Date: Wed, 29 Nov 2023 00:27:25 -0800
Subject: [PATCH] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal
 toolchain

Extend the multi-lib re-use selection mechanism for RISC-V.
This funciton will try to re-use multi-lib if they are compatible.
Definition of compatible:
  - ABI must be the same.
  - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
is a subset of march=rv32imc.
  - march that contains atomic extension can't reuse multi-lib that
doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
march=rv32ima are not compatible, because software and hardware
atomic operation can't work together correctly.
---
 clang/lib/Driver/ToolChains/Gnu.cpp   | 134 +-
 .../8.2.0/rv32ic/ilp32/crtbegin.o |   0
 .../8.2.0/rv32if/ilp32f/crtbegin.o|   0
 .../8.2.0/rv32ifc/ilp32/crtbegin.o|   0
 .../8.2.0/rv32ifc/ilp32f/crtbegin.o   |   0
 .../riscv-toolchain-gcc-multilib-reuse.c  |  86 +++
 6 files changed, 216 insertions(+), 4 deletions(-)
 create mode 100644 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ic/ilp32/crtbegin.o
 create mode 100644 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32if/ilp32f/crtbegin.o
 create mode 100644 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32/crtbegin.o
 create mode 100644 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32f/crtbegin.o
 create mode 100644 clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c

diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 16cf5707227264d..ffc53377d97bd02 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/RISCVISAInfo.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/TargetParser/TargetParser.h"
 #include 
@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const 
llvm::Triple &TargetTriple,
 Result.Multilibs = CSKYMultilibs;
 }
 
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+///   - ABI must be the same.
+///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+///   - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+const Multilib::flags_list &Flags,
+llvm::SmallVector &SelectedMultilibs) {
+  // Try to find the perfect matching multi-lib first.
+  if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+return true;
+
+  llvm::StringMap FlagSet;
+  Multilib::flags_list NewFlags;
+  std::vector NewMultilibs;
+
+  auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+  Arch, /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!ParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+consumeError(ParseResult.takeError());
+return false;
+  }
+  auto &ISAInfo = *ParseResult;
+
+  auto CurrentExts = ISAInfo->getExtensions();
+
+  addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+  addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+  // Collect all flags except march=*
+  for (StringRef Flag : Flags) {
+if (Flag.startswith("!march=") || Flag.startswith("-march="))
+  continue;
+
+NewFlags.push_back(Flag.str());
+  }
+
+  llvm::StringSet<> AllArchExts;
+  // Reconstruct multi-lib list, and break march option into seperated
+  // extension. e.g. march=rv32im -> +i +m
+  for (auto M : RISCVMultilibSet) {
+bool Skip = false;
+
+Multil

[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: Brandon Wu (4vtomat)


Changes

Extend the multi-lib re-use selection mechanism for RISC-V.
This funciton will try to re-use multi-lib if they are compatible.
Definition of compatible:
  - ABI must be the same.
  - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
is a subset of march=rv32imc.
  - march that contains atomic extension can't reuse multi-lib that
doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
march=rv32ima are not compatible, because software and hardware
atomic operation can't work together correctly.


---
Full diff: https://github.com/llvm/llvm-project/pull/73765.diff


6 Files Affected:

- (modified) clang/lib/Driver/ToolChains/Gnu.cpp (+130-4) 
- (added) 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ic/ilp32/crtbegin.o
 () 
- (added) 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32if/ilp32f/crtbegin.o
 () 
- (added) 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32/crtbegin.o
 () 
- (added) 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32f/crtbegin.o
 () 
- (added) clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c (+86) 


``diff
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 16cf5707227264d..ffc53377d97bd02 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/RISCVISAInfo.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/TargetParser/TargetParser.h"
 #include 
@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const 
llvm::Triple &TargetTriple,
 Result.Multilibs = CSKYMultilibs;
 }
 
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+///   - ABI must be the same.
+///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+///   - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+const Multilib::flags_list &Flags,
+llvm::SmallVector &SelectedMultilibs) {
+  // Try to find the perfect matching multi-lib first.
+  if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+return true;
+
+  llvm::StringMap FlagSet;
+  Multilib::flags_list NewFlags;
+  std::vector NewMultilibs;
+
+  auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+  Arch, /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!ParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+consumeError(ParseResult.takeError());
+return false;
+  }
+  auto &ISAInfo = *ParseResult;
+
+  auto CurrentExts = ISAInfo->getExtensions();
+
+  addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+  addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+  // Collect all flags except march=*
+  for (StringRef Flag : Flags) {
+if (Flag.startswith("!march=") || Flag.startswith("-march="))
+  continue;
+
+NewFlags.push_back(Flag.str());
+  }
+
+  llvm::StringSet<> AllArchExts;
+  // Reconstruct multi-lib list, and break march option into seperated
+  // extension. e.g. march=rv32im -> +i +m
+  for (auto M : RISCVMultilibSet) {
+bool Skip = false;
+
+MultilibBuilder NewMultilib =
+MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());
+for (StringRef Flag : M.flags()) {
+  // Add back the all option except -march.
+  if (!Flag.startswith("-march=")) {
+NewMultilib.flag(Flag);
+continue;
+  }
+
+  // Break down -march into individual extension.
+  auto MLConfigParseResult = llvm::RISCVISAInfo::parseArchString(
+  Flag.drop_front(7), /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!MLConfigParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+llvm::consumeError(MLConfigParseResult.takeError());
+
+// We might got parsing error if rv32e in the list, we could just skip
+// that and process the rest of multi-lib configs.
+Skip = true;
+continue;
+  }
+  auto &MLConfigISAInfo = *MLConfigParseResult;
+
+  auto MLConfigArchExts = MLConfigISAInfo

[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-risc-v

Author: Brandon Wu (4vtomat)


Changes

Extend the multi-lib re-use selection mechanism for RISC-V.
This funciton will try to re-use multi-lib if they are compatible.
Definition of compatible:
  - ABI must be the same.
  - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
is a subset of march=rv32imc.
  - march that contains atomic extension can't reuse multi-lib that
doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
march=rv32ima are not compatible, because software and hardware
atomic operation can't work together correctly.


---
Full diff: https://github.com/llvm/llvm-project/pull/73765.diff


6 Files Affected:

- (modified) clang/lib/Driver/ToolChains/Gnu.cpp (+130-4) 
- (added) 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ic/ilp32/crtbegin.o
 () 
- (added) 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32if/ilp32f/crtbegin.o
 () 
- (added) 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32/crtbegin.o
 () 
- (added) 
clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32f/crtbegin.o
 () 
- (added) clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c (+86) 


``diff
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 16cf5707227264d..ffc53377d97bd02 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/RISCVISAInfo.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/TargetParser/TargetParser.h"
 #include 
@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const 
llvm::Triple &TargetTriple,
 Result.Multilibs = CSKYMultilibs;
 }
 
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+///   - ABI must be the same.
+///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+///   - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+const Multilib::flags_list &Flags,
+llvm::SmallVector &SelectedMultilibs) {
+  // Try to find the perfect matching multi-lib first.
+  if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+return true;
+
+  llvm::StringMap FlagSet;
+  Multilib::flags_list NewFlags;
+  std::vector NewMultilibs;
+
+  auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+  Arch, /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!ParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+consumeError(ParseResult.takeError());
+return false;
+  }
+  auto &ISAInfo = *ParseResult;
+
+  auto CurrentExts = ISAInfo->getExtensions();
+
+  addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+  addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+  // Collect all flags except march=*
+  for (StringRef Flag : Flags) {
+if (Flag.startswith("!march=") || Flag.startswith("-march="))
+  continue;
+
+NewFlags.push_back(Flag.str());
+  }
+
+  llvm::StringSet<> AllArchExts;
+  // Reconstruct multi-lib list, and break march option into seperated
+  // extension. e.g. march=rv32im -> +i +m
+  for (auto M : RISCVMultilibSet) {
+bool Skip = false;
+
+MultilibBuilder NewMultilib =
+MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());
+for (StringRef Flag : M.flags()) {
+  // Add back the all option except -march.
+  if (!Flag.startswith("-march=")) {
+NewMultilib.flag(Flag);
+continue;
+  }
+
+  // Break down -march into individual extension.
+  auto MLConfigParseResult = llvm::RISCVISAInfo::parseArchString(
+  Flag.drop_front(7), /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!MLConfigParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+llvm::consumeError(MLConfigParseResult.takeError());
+
+// We might got parsing error if rv32e in the list, we could just skip
+// that and process the rest of multi-lib configs.
+Skip = true;
+continue;
+  }
+  auto &MLConfigISAInfo = *MLConfigParseResult;
+
+  auto MLConfigArchExts = MLConfigISAIn

[mlir] [clang-tools-extra] [clang] [lldb] [llvm] [compiler-rt] [libc] [flang] [DAGCombiner] Combine frem into fdiv+ftrunc+fma (PR #67642)

2023-11-29 Thread Qiu Chaofan via cfe-commits

https://github.com/ecnelises updated 
https://github.com/llvm/llvm-project/pull/67642

>From 2ff3a666e4347f9224c1a406126282d98e3c9633 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Thu, 28 Sep 2023 16:09:40 +0800
Subject: [PATCH 1/2] [DAGCombiner] Combine frem into fdiv+ftrunc+fma

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  12 ++
 llvm/test/CodeGen/PowerPC/frem.ll | 142 +-
 2 files changed, 49 insertions(+), 105 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp 
b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 0d34ebb117667aa..2f5f295e199188a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16958,6 +16958,18 @@ SDValue DAGCombiner::visitFREM(SDNode *N) {
   if (SDValue NewSel = foldBinOpIntoSelect(N))
 return NewSel;
 
+  // (frem x, y) -> (fma (fneg (ftrunc (fdiv x, y))), y, x)
+  if (Flags.hasApproximateFuncs() && Flags.hasNoSignedZeros() &&
+  Flags.hasNoInfs() && !TLI.isOperationLegalOrCustom(ISD::FREM, VT) &&
+  TLI.isOperationLegalOrCustom(ISD::FTRUNC, VT) &&
+  TLI.isOperationLegalOrCustom(ISD::FMA, VT)) {
+SDLoc Loc(N);
+SDValue Div = DAG.getNode(ISD::FDIV, Loc, VT, N0, N1);
+SDValue Trunc = DAG.getNode(ISD::FTRUNC, Loc, VT, Div);
+return DAG.getNode(ISD::FMA, Loc, VT,
+   DAG.getNode(ISD::FNEG, Loc, VT, Trunc), N1, N0);
+  }
+
   return SDValue();
 }
 
diff --git a/llvm/test/CodeGen/PowerPC/frem.ll 
b/llvm/test/CodeGen/PowerPC/frem.ll
index 8cb68e60f7f9b71..dff9c796289e96e 100644
--- a/llvm/test/CodeGen/PowerPC/frem.ll
+++ b/llvm/test/CodeGen/PowerPC/frem.ll
@@ -4,16 +4,13 @@
 define float @frem32(float %a, float %b) {
 ; CHECK-LABEL: frem32:
 ; CHECK:   # %bb.0: # %entry
-; CHECK-NEXT:mflr 0
-; CHECK-NEXT:stdu 1, -32(1)
-; CHECK-NEXT:std 0, 48(1)
-; CHECK-NEXT:.cfi_def_cfa_offset 32
-; CHECK-NEXT:.cfi_offset lr, 16
-; CHECK-NEXT:bl fmodf
-; CHECK-NEXT:nop
-; CHECK-NEXT:addi 1, 1, 32
-; CHECK-NEXT:ld 0, 16(1)
-; CHECK-NEXT:mtlr 0
+; CHECK-NEXT:xsresp 0, 2
+; CHECK-NEXT:fmr 4, 1
+; CHECK-NEXT:xsmulsp 3, 1, 0
+; CHECK-NEXT:xsnmsubasp 4, 2, 3
+; CHECK-NEXT:xsmaddasp 3, 0, 4
+; CHECK-NEXT:xsrdpiz 0, 3
+; CHECK-NEXT:xsnmsubasp 1, 0, 2
 ; CHECK-NEXT:blr
 entry:
   %rem = frem fast float %a, %b
@@ -23,16 +20,17 @@ entry:
 define double @frem64(double %a, double %b) {
 ; CHECK-LABEL: frem64:
 ; CHECK:   # %bb.0: # %entry
-; CHECK-NEXT:mflr 0
-; CHECK-NEXT:stdu 1, -32(1)
-; CHECK-NEXT:std 0, 48(1)
-; CHECK-NEXT:.cfi_def_cfa_offset 32
-; CHECK-NEXT:.cfi_offset lr, 16
-; CHECK-NEXT:bl fmod
-; CHECK-NEXT:nop
-; CHECK-NEXT:addi 1, 1, 32
-; CHECK-NEXT:ld 0, 16(1)
-; CHECK-NEXT:mtlr 0
+; CHECK-NEXT:vspltisw 2, -1
+; CHECK-NEXT:xsredp 0, 2
+; CHECK-NEXT:fmr 4, 1
+; CHECK-NEXT:xvcvsxwdp 3, 34
+; CHECK-NEXT:xsmaddadp 3, 2, 0
+; CHECK-NEXT:xsnmsubadp 0, 0, 3
+; CHECK-NEXT:xsmuldp 3, 1, 0
+; CHECK-NEXT:xsnmsubadp 4, 2, 3
+; CHECK-NEXT:xsmaddadp 3, 0, 4
+; CHECK-NEXT:xsrdpiz 0, 3
+; CHECK-NEXT:xsnmsubadp 1, 0, 2
 ; CHECK-NEXT:blr
 entry:
   %rem = frem fast double %a, %b
@@ -42,59 +40,13 @@ entry:
 define <4 x float> @frem4x32(<4 x float> %a, <4 x float> %b) {
 ; CHECK-LABEL: frem4x32:
 ; CHECK:   # %bb.0: # %entry
-; CHECK-NEXT:mflr 0
-; CHECK-NEXT:stdu 1, -96(1)
-; CHECK-NEXT:std 0, 112(1)
-; CHECK-NEXT:.cfi_def_cfa_offset 96
-; CHECK-NEXT:.cfi_offset lr, 16
-; CHECK-NEXT:.cfi_offset v28, -64
-; CHECK-NEXT:.cfi_offset v29, -48
-; CHECK-NEXT:.cfi_offset v30, -32
-; CHECK-NEXT:.cfi_offset v31, -16
-; CHECK-NEXT:xxsldwi 0, 34, 34, 3
-; CHECK-NEXT:stxv 60, 32(1) # 16-byte Folded Spill
-; CHECK-NEXT:xscvspdpn 1, 0
-; CHECK-NEXT:xxsldwi 0, 35, 35, 3
-; CHECK-NEXT:stxv 61, 48(1) # 16-byte Folded Spill
-; CHECK-NEXT:stxv 62, 64(1) # 16-byte Folded Spill
-; CHECK-NEXT:stxv 63, 80(1) # 16-byte Folded Spill
-; CHECK-NEXT:xscvspdpn 2, 0
-; CHECK-NEXT:vmr 31, 3
-; CHECK-NEXT:vmr 30, 2
-; CHECK-NEXT:bl fmodf
-; CHECK-NEXT:nop
-; CHECK-NEXT:xxsldwi 0, 62, 62, 1
-; CHECK-NEXT:xscpsgndp 61, 1, 1
-; CHECK-NEXT:xscvspdpn 1, 0
-; CHECK-NEXT:xxsldwi 0, 63, 63, 1
-; CHECK-NEXT:xscvspdpn 2, 0
-; CHECK-NEXT:bl fmodf
-; CHECK-NEXT:nop
-; CHECK-NEXT:# kill: def $f1 killed $f1 def $vsl1
-; CHECK-NEXT:xxmrghd 0, 1, 61
-; CHECK-NEXT:xscvspdpn 1, 62
-; CHECK-NEXT:xscvspdpn 2, 63
-; CHECK-NEXT:xvcvdpsp 60, 0
-; CHECK-NEXT:bl fmodf
-; CHECK-NEXT:nop
-; CHECK-NEXT:xxswapd 0, 62
-; CHECK-NEXT:xscpsgndp 61, 1, 1
-; CHECK-NEXT:xscvspdpn 1, 0
-; CHECK-NEXT:xxswapd 0, 63
-; CHECK-NEXT:xscvspdpn 2, 0
-; CHECK-NEXT:bl fmodf
-; CHECK-NEXT:nop
-; CHECK-NEXT:# kill: def $f1 killed $f1 def $vsl1
-; CHECK-NEXT:xxmrghd 0, 61, 1
-; CHE

[clang] 95943d2 - [Flang] Add code-object-version option (#72638)

2023-11-29 Thread Dominik Adamski via cfe-commits

Author: Dominik Adamski
Date: 2023-11-29T03:01:01-06:00
New Revision: 95943d2fab7e6f8dcea216df2d56a0512201b467

URL: 
https://github.com/llvm/llvm-project/commit/95943d2fab7e6f8dcea216df2d56a0512201b467
DIFF: 
https://github.com/llvm/llvm-project/commit/95943d2fab7e6f8dcea216df2d56a0512201b467.diff

LOG: [Flang] Add code-object-version option (#72638)

Information about code object version can be configured by the user for
AMD GPU target and it needs to be placed in LLVM IR generated by Flang.

Information about code object version in MLIR generated by the parser
can be reused by other tools. There is no need to specify extra flags if
we want to invoke MLIR tools (like fir-opt) separately.

Changes in comparison to a8ac93:
 * added information about required targets for test
   flang/test/Driver/driver-help.f90

Added: 
flang/test/Driver/code-object-version.f90
flang/test/Lower/AMD/code-object-version.f90

Modified: 
clang/include/clang/Basic/TargetOptions.h
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/CodeGen/Targets/AMDGPU.cpp
clang/lib/Driver/ToolChains/Flang.cpp
clang/lib/Driver/ToolChains/Flang.h
flang/include/flang/Frontend/CodeGenOptions.h
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Frontend/FrontendActions.cpp
flang/test/Driver/driver-help-hidden.f90
flang/test/Driver/driver-help.f90
llvm/include/llvm/Target/TargetOptions.h

Removed: 




diff  --git a/clang/include/clang/Basic/TargetOptions.h 
b/clang/include/clang/Basic/TargetOptions.h
index ba3acd029587160..2049f03b28893fd 100644
--- a/clang/include/clang/Basic/TargetOptions.h
+++ b/clang/include/clang/Basic/TargetOptions.h
@@ -78,17 +78,9 @@ class TargetOptions {
   /// \brief If enabled, allow AMDGPU unsafe floating point atomics.
   bool AllowAMDGPUUnsafeFPAtomics = false;
 
-  /// \brief Enumeration value for AMDGPU code object version, which is the
-  /// code object version times 100.
-  enum CodeObjectVersionKind {
-COV_None,
-COV_2 = 200, // Unsupported.
-COV_3 = 300, // Unsupported.
-COV_4 = 400,
-COV_5 = 500,
-  };
   /// \brief Code object version for AMDGPU.
-  CodeObjectVersionKind CodeObjectVersion = CodeObjectVersionKind::COV_None;
+  llvm::CodeObjectVersionKind CodeObjectVersion =
+  llvm::CodeObjectVersionKind::COV_None;
 
   /// \brief Enumeration values for AMDGPU printf lowering scheme
   enum class AMDGPUPrintfKind {

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 9689f12fd01417b..7dd2755350f7a56 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4721,9 +4721,9 @@ defm amdgpu_ieee : BoolOption<"m", "amdgpu-ieee",
 
 def mcode_object_version_EQ : Joined<["-"], "mcode-object-version=">, 
Group,
   HelpText<"Specify code object ABI version. Defaults to 4. (AMDGPU only)">,
-  Visibility<[ClangOption, CC1Option]>,
+  Visibility<[ClangOption, FlangOption, CC1Option, FC1Option]>,
   Values<"none,4,5">,
-  NormalizedValuesScope<"TargetOptions">,
+  NormalizedValuesScope<"llvm::CodeObjectVersionKind">,
   NormalizedValues<["COV_None", "COV_4", "COV_5"]>,
   MarshallingInfoEnum, "COV_4">;
 

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c83ea966fdeadc6..65d9862621061d8 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -17588,7 +17588,7 @@ Value *EmitAMDGPUWorkGroupSize(CodeGenFunction &CGF, 
unsigned Index) {
 
   auto Cov = CGF.getTarget().getTargetOpts().CodeObjectVersion;
 
-  if (Cov == clang::TargetOptions::COV_None) {
+  if (Cov == CodeObjectVersionKind::COV_None) {
 StringRef Name = "__oclc_ABI_version";
 auto *ABIVersionC = CGF.CGM.getModule().getNamedGlobal(Name);
 if (!ABIVersionC)
@@ -17606,7 +17606,7 @@ Value *EmitAMDGPUWorkGroupSize(CodeGenFunction &CGF, 
unsigned Index) {
 
 Value *IsCOV5 = CGF.Builder.CreateICmpSGE(
 ABIVersion,
-llvm::ConstantInt::get(CGF.Int32Ty, clang::TargetOptions::COV_5));
+llvm::ConstantInt::get(CGF.Int32Ty, CodeObjectVersionKind::COV_5));
 
 // Indexing the implicit kernarg segment.
 Value *ImplicitGEP = CGF.Builder.CreateConstGEP1_32(
@@ -17621,7 +17621,7 @@ Value *EmitAMDGPUWorkGroupSize(CodeGenFunction &CGF, 
unsigned Index) {
 Address(Result, CGF.Int16Ty, CharUnits::fromQuantity(2)));
   } else {
 Value *GEP = nullptr;
-if (Cov == clang::TargetOptions::COV_5) {
+if (Cov == CodeObjectVersionKind::COV_5) {
   // Indexing the implicit kernarg segment.
   GEP = CGF.Builder.CreateConstGEP1_32(
   CGF.Int8Ty, EmitAMDGPUImplicitArgPtr(CGF), 12 + Index * 2);

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 41ff4a992f194ae..3225c984768657a 100644
--- a/cla

[llvm] [clang] [AMDGPU] Improve selection of ballot.i64 intrinsic in wave32 mode. (PR #71556)

2023-11-29 Thread Pierre van Houtryve via cfe-commits


@@ -961,6 +961,18 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, 
IntrinsicInst &II) const {
 return IC.replaceInstUsesWith(II, 
Constant::getNullValue(II.getType()));
   }
 }
+if (ST->isWave32() && II.getType()->getIntegerBitWidth() == 64) {
+  // %b64 = call i64 ballot.i64(...)
+  // =>
+  // %b32 = call i32 ballot.i32(...)
+  // %b64 = zext i32 %b32 to i64
+  Function *NewF = Intrinsic::getDeclaration(
+  II.getModule(), Intrinsic::amdgcn_ballot, {IC.Builder.getInt32Ty()});
+  CallInst *NewCall = IC.Builder.CreateCall(NewF, {II.getArgOperand(0)});
+  Value *CastedCall = IC.Builder.CreateZExtOrBitCast(NewCall, 
II.getType());
+  CastedCall->takeName(&II);
+  return IC.replaceInstUsesWith(II, CastedCall);

Pierre-vh wrote:

Nit: Can just reuse the same value, e.g.
```
  Value *Call = IC.Builder.CreateCall(NewF, {II.getArgOperand(0)});
  Call = IC.Builder.CreateZExtOrBitCast(NewCall, II.getType());
  Call->takeName(&II);
  return IC.replaceInstUsesWith(II, Call);
```

I also think you should be able to use something like 
`IC.Builder.CreateIntrinsic` ? There should be a function to create an 
intrinsic call directly.

https://github.com/llvm/llvm-project/pull/71556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread Brandon Wu via cfe-commits

https://github.com/4vtomat updated 
https://github.com/llvm/llvm-project/pull/73765

>From c406872192d75c92dedd13d1afc36e7b5d71ccca Mon Sep 17 00:00:00 2001
From: Brandon Wu 
Date: Wed, 29 Nov 2023 00:27:25 -0800
Subject: [PATCH] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal
 toolchain

Extend the multi-lib re-use selection mechanism for RISC-V.
This funciton will try to re-use multi-lib if they are compatible.
Definition of compatible:
  - ABI must be the same.
  - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
is a subset of march=rv32imc.
  - march that contains atomic extension can't reuse multi-lib that
doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
march=rv32ima are not compatible, because software and hardware
atomic operation can't work together correctly.
---
 clang/lib/Driver/ToolChains/Gnu.cpp   | 127 +-
 .../riscv-toolchain-gcc-multilib-reuse.c  |  86 
 2 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c

diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 16cf5707227264d..5bb09101fef0038 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/RISCVISAInfo.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/TargetParser/TargetParser.h"
 #include 
@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const 
llvm::Triple &TargetTriple,
 Result.Multilibs = CSKYMultilibs;
 }
 
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+///   - ABI must be the same.
+///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+///   - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+const Multilib::flags_list &Flags,
+llvm::SmallVector &SelectedMultilibs) {
+  // Try to find the perfect matching multi-lib first.
+  if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+return true;
+
+  llvm::StringMap FlagSet;
+  Multilib::flags_list NewFlags;
+  std::vector NewMultilibs;
+
+  auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+  Arch, /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!ParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+consumeError(ParseResult.takeError());
+return false;
+  }
+  auto &ISAInfo = *ParseResult;
+
+  auto CurrentExts = ISAInfo->getExtensions();
+
+  addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+  addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+  // Collect all flags except march=*
+  for (StringRef Flag : Flags) {
+if (Flag.startswith("!march=") || Flag.startswith("-march="))
+  continue;
+
+NewFlags.push_back(Flag.str());
+  }
+
+  llvm::StringSet<> AllArchExts;
+  // Reconstruct multi-lib list, and break march option into seperated
+  // extension. e.g. march=rv32im -> +i +m
+  for (auto M : RISCVMultilibSet) {
+bool Skip = false;
+
+MultilibBuilder NewMultilib =
+MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());
+for (StringRef Flag : M.flags()) {
+  // Add back the all option except -march.
+  if (!Flag.startswith("-march=")) {
+NewMultilib.flag(Flag);
+continue;
+  }
+
+  // Break down -march into individual extension.
+  auto MLConfigParseResult = llvm::RISCVISAInfo::parseArchString(
+  Flag.drop_front(7), /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!MLConfigParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+llvm::consumeError(MLConfigParseResult.takeError());
+
+// We might got parsing error if rv32e in the list, we could just skip
+// that and process the rest of multi-lib configs.
+Skip = true;
+continue;
+  }
+  auto &MLConfigISAInfo = *MLConfigParseResult;
+
+  auto MLConfigArchExts = MLConfigISAInfo->getExtensions();
+  for (auto MLConfigArchExt : MLConfigArchExts) {
+auto ExtName = MLConfigArchExt.first;
+NewMultilib.flag(Twine("-", ExtName).str());
+
+if (!AllArchExts.contains(ExtName)) {
+  AllArchExts.insert

[clang] [AArch64] Warn when calling a NEON builtin in a streaming function (PR #73672)

2023-11-29 Thread Sander de Smalen via cfe-commits


@@ -3136,6 +3192,31 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 
 bool Sema::CheckNeonBuiltinFunctionCall(const TargetInfo &TI,
 unsigned BuiltinID, CallExpr *TheCall) 
{
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+std::optional BuiltinType;
+
+bool IsNeon = false;
+switch (BuiltinID) {
+default:
+  break;
+#define GET_NEON_BUILTINS
+#define TARGET_BUILTIN(id, x, y, z)
\
+  case NEON::BI##id:   
\
+IsNeon = true; 
\
+break;
+#define BUILTIN(id, x, y) TARGET_BUILTIN(id, x, y, "");
+#include "clang/Basic/arm_neon.inc"
+#undef TARGET_BUILTIN
+#undef BUILTIN
+#undef GET_NEON_BUILTINS
+}
+
+if (IsNeon) {
+  checkArmStreamingBuiltin(*this, TheCall, FD, ArmNonStreaming);
+  return true;
+}

sdesmalen-arm wrote:

nit: Can this be simplified as:
```
  switch (BuiltinID) {
  default:
break;
#define TARGET_BUILTIN(id, ...) case NEON::BI##id:  
#define BUILTIN(id, ...) case NEON::BI##id:
#define GET_NEON_BUILTINS
#include "clang/Basic/arm_neon.inc"
return checkArmStreamingBuiltin(*this, TheCall, FD, ArmNonStreaming);
#undef GET_NEON_BUILTINS
#undef BUILTIN
#undef TARGET_BUILTIN
```
?

https://github.com/llvm/llvm-project/pull/73672
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64] Warn when calling a NEON builtin in a streaming function (PR #73672)

2023-11-29 Thread Sander de Smalen via cfe-commits


@@ -2993,6 +2993,62 @@ static QualType getNeonEltType(NeonTypeFlags Flags, 
ASTContext &Context,
   llvm_unreachable("Invalid NeonTypeFlag!");
 }
 
+enum ArmStreamingType {
+  ArmNonStreaming,
+  ArmStreaming,
+  ArmStreamingCompatible,
+  ArmLocallyStreaming,
+  ArmStreamingOrSVE2p1

sdesmalen-arm wrote:

`ArmStreamingOrSVE2p1` is not relevant to this patch.

https://github.com/llvm/llvm-project/pull/73672
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64] Warn when calling a NEON builtin in a streaming function (PR #73672)

2023-11-29 Thread Sander de Smalen via cfe-commits


@@ -0,0 +1,24 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1  -triple aarch64-none-linux-gnu -target-feature +sve \
+// RUN:   -target-feature +sme -target-feature +sve2 -target-feature +neon 
-fsyntax-only -verify %s
+
+// REQUIRES: aarch64-registered-target
+
+#include "arm_neon.h"
+#include "arm_sme_draft_spec_subject_to_change.h"
+#include "arm_sve.h"

sdesmalen-arm wrote:

I don't think these two includes are necessary.

https://github.com/llvm/llvm-project/pull/73672
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64] Warn when calling a NEON builtin in a streaming function (PR #73672)

2023-11-29 Thread Sander de Smalen via cfe-commits


@@ -3136,6 +3192,31 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 
 bool Sema::CheckNeonBuiltinFunctionCall(const TargetInfo &TI,
 unsigned BuiltinID, CallExpr *TheCall) 
{
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+std::optional BuiltinType;

sdesmalen-arm wrote:

`BuiltinType` seems unused.

https://github.com/llvm/llvm-project/pull/73672
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64] Warn when calling a NEON builtin in a streaming function (PR #73672)

2023-11-29 Thread Sander de Smalen via cfe-commits


@@ -2993,6 +2993,62 @@ static QualType getNeonEltType(NeonTypeFlags Flags, 
ASTContext &Context,
   llvm_unreachable("Invalid NeonTypeFlag!");
 }
 
+enum ArmStreamingType {
+  ArmNonStreaming,
+  ArmStreaming,
+  ArmStreamingCompatible,
+  ArmLocallyStreaming,
+  ArmStreamingOrSVE2p1
+};
+
+static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return ArmLocallyStreaming;
+  if (const auto *T = FD->getType()->getAs()) {
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask)
+  return ArmStreaming;
+if (T->getAArch64SMEAttributes() & 
FunctionType::SME_PStateSMCompatibleMask)
+  return ArmStreamingCompatible;
+  }
+  return ArmNonStreaming;
+}
+
+static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
+ const FunctionDecl *FD,
+ ArmStreamingType BuiltinType) {
+  assert(BuiltinType != ArmLocallyStreaming &&
+ "Unexpected locally_streaming attribute for builtin!");
+
+  ArmStreamingType FnType = getArmStreamingFnType(FD);
+  if (BuiltinType == ArmStreamingOrSVE2p1) {
+// Check intrinsics that are available in [sve2p1 or sme/sme2].
+llvm::StringMap CallerFeatureMap;
+S.Context.getFunctionFeatureMap(CallerFeatureMap, FD);
+if (Builtin::evaluateRequiredTargetFeatures("sve2p1", CallerFeatureMap))
+  BuiltinType = ArmStreamingCompatible;
+else
+  BuiltinType = ArmStreaming;
+  }
+

sdesmalen-arm wrote:

This seems irrelevant to this patch.

https://github.com/llvm/llvm-project/pull/73672
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64] Warn when calling a NEON builtin in a streaming function (PR #73672)

2023-11-29 Thread Sander de Smalen via cfe-commits


@@ -2993,6 +2993,62 @@ static QualType getNeonEltType(NeonTypeFlags Flags, 
ASTContext &Context,
   llvm_unreachable("Invalid NeonTypeFlag!");
 }
 
+enum ArmStreamingType {
+  ArmNonStreaming,
+  ArmStreaming,
+  ArmStreamingCompatible,
+  ArmLocallyStreaming,
+  ArmStreamingOrSVE2p1
+};
+
+static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return ArmLocallyStreaming;
+  if (const auto *T = FD->getType()->getAs()) {
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask)
+  return ArmStreaming;
+if (T->getAArch64SMEAttributes() & 
FunctionType::SME_PStateSMCompatibleMask)
+  return ArmStreamingCompatible;
+  }
+  return ArmNonStreaming;
+}
+
+static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
+ const FunctionDecl *FD,
+ ArmStreamingType BuiltinType) {
+  assert(BuiltinType != ArmLocallyStreaming &&
+ "Unexpected locally_streaming attribute for builtin!");
+
+  ArmStreamingType FnType = getArmStreamingFnType(FD);
+  if (BuiltinType == ArmStreamingOrSVE2p1) {
+// Check intrinsics that are available in [sve2p1 or sme/sme2].
+llvm::StringMap CallerFeatureMap;
+S.Context.getFunctionFeatureMap(CallerFeatureMap, FD);
+if (Builtin::evaluateRequiredTargetFeatures("sve2p1", CallerFeatureMap))
+  BuiltinType = ArmStreamingCompatible;
+else
+  BuiltinType = ArmStreaming;
+  }
+
+  if ((FnType == ArmStreaming || FnType == ArmLocallyStreaming) &&
+  BuiltinType == ArmNonStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "streaming or locally streaming";
+  }
+
+  if ((FnType == ArmStreamingCompatible) &&
+  BuiltinType != ArmStreamingCompatible) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "streaming compatible";
+return;
+  }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }

sdesmalen-arm wrote:

This seems irrelevant to this patch.

https://github.com/llvm/llvm-project/pull/73672
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-29 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/73770

Increment and decrement are equivalent to adding or subtracting 1. For the 
floating-point values these operations depend on the current rounding mode. 
Teach constant evaluator to perform ++ and -- according to the current 
floating-point environment.

>From 48ed25acfa5765af607efce2309605b96a09d477 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 29 Nov 2023 00:53:54 +0700
Subject: [PATCH] [clang] Use current rounding mode for float inc/dec

Increment and decrement are equivalent to adding or subtracting 1. For
the floating-point values these operations depend on the current
rounding mode. Teach constant evaluator to perform ++ and -- according
to the current floating-point environment.
---
 clang/lib/AST/ExprConstant.cpp   |  6 --
 clang/test/SemaCXX/rounding-math.cpp | 21 +
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 16697e5f076a8f8..e0abe832c47a9f1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4623,10 +4623,12 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
+llvm::RoundingMode RM =
+E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
 if (AccessKind == AK_Increment)
-  Value.add(One, APFloat::rmNearestTiesToEven);
+  Value.add(One, RM);
 else
-  Value.subtract(One, APFloat::rmNearestTiesToEven);
+  Value.subtract(One, RM);
 return true;
   }
   bool foundPointer(APValue &Subobj, QualType SubobjType) {
diff --git a/clang/test/SemaCXX/rounding-math.cpp 
b/clang/test/SemaCXX/rounding-math.cpp
index 73f9f10e6d59417..e7ead05041b560d 100644
--- a/clang/test/SemaCXX/rounding-math.cpp
+++ b/clang/test/SemaCXX/rounding-math.cpp
@@ -77,3 +77,24 @@ struct S1d {
   int f;
 };
 static_assert(sizeof(S1d) == sizeof(int), "");
+
+constexpr float incr_down(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+
+// 0x1.0p23 = 8388608.0, inc(8388608.0) = 8388609.0
+static_assert(incr_down(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round down -> 
16777216.0
+static_assert(incr_down(0x1.0p24F) == 0x1.0p24F, "");
+
+#pragma STDC FENV_ROUND FE_UPWARD
+constexpr float incr_up(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+static_assert(incr_up(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round up -> 
16777218.0
+static_assert(incr_up(0x1.0p24F) == 0x1.02p24F, "");

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Serge Pavlov (spavloff)


Changes

Increment and decrement are equivalent to adding or subtracting 1. For the 
floating-point values these operations depend on the current rounding mode. 
Teach constant evaluator to perform ++ and -- according to the current 
floating-point environment.

---
Full diff: https://github.com/llvm/llvm-project/pull/73770.diff


2 Files Affected:

- (modified) clang/lib/AST/ExprConstant.cpp (+4-2) 
- (modified) clang/test/SemaCXX/rounding-math.cpp (+21) 


``diff
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 16697e5f076a8f8..e0abe832c47a9f1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4623,10 +4623,12 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
+llvm::RoundingMode RM =
+E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
 if (AccessKind == AK_Increment)
-  Value.add(One, APFloat::rmNearestTiesToEven);
+  Value.add(One, RM);
 else
-  Value.subtract(One, APFloat::rmNearestTiesToEven);
+  Value.subtract(One, RM);
 return true;
   }
   bool foundPointer(APValue &Subobj, QualType SubobjType) {
diff --git a/clang/test/SemaCXX/rounding-math.cpp 
b/clang/test/SemaCXX/rounding-math.cpp
index 73f9f10e6d59417..e7ead05041b560d 100644
--- a/clang/test/SemaCXX/rounding-math.cpp
+++ b/clang/test/SemaCXX/rounding-math.cpp
@@ -77,3 +77,24 @@ struct S1d {
   int f;
 };
 static_assert(sizeof(S1d) == sizeof(int), "");
+
+constexpr float incr_down(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+
+// 0x1.0p23 = 8388608.0, inc(8388608.0) = 8388609.0
+static_assert(incr_down(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round down -> 
16777216.0
+static_assert(incr_down(0x1.0p24F) == 0x1.0p24F, "");
+
+#pragma STDC FENV_ROUND FE_UPWARD
+constexpr float incr_up(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+static_assert(incr_up(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round up -> 
16777218.0
+static_assert(incr_up(0x1.0p24F) == 0x1.02p24F, "");

``




https://github.com/llvm/llvm-project/pull/73770
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread Yeting Kuo via cfe-commits


@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const 
llvm::Triple &TargetTriple,
 Result.Multilibs = CSKYMultilibs;
 }
 
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+///   - ABI must be the same.
+///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+///   - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+const Multilib::flags_list &Flags,
+llvm::SmallVector &SelectedMultilibs) {

yetingk wrote:

Use `ArrayRef` or `SmallVectorImpl` instead of `SmallVector`. `SmallVector` 
actually use two template parameters. 

https://github.com/llvm/llvm-project/pull/73765
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread Yeting Kuo via cfe-commits


@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const 
llvm::Triple &TargetTriple,
 Result.Multilibs = CSKYMultilibs;
 }
 
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+///   - ABI must be the same.
+///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+///   - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+const Multilib::flags_list &Flags,
+llvm::SmallVector &SelectedMultilibs) {
+  // Try to find the perfect matching multi-lib first.
+  if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+return true;
+
+  llvm::StringMap FlagSet;
+  Multilib::flags_list NewFlags;
+  std::vector NewMultilibs;
+
+  auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+  Arch, /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!ParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+consumeError(ParseResult.takeError());
+return false;
+  }
+  auto &ISAInfo = *ParseResult;
+
+  auto CurrentExts = ISAInfo->getExtensions();
+
+  addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+  addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+  // Collect all flags except march=*
+  for (StringRef Flag : Flags) {

yetingk wrote:

`StringRef` -> `const StringRef &`

https://github.com/llvm/llvm-project/pull/73765
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread Yeting Kuo via cfe-commits


@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const 
llvm::Triple &TargetTriple,
 Result.Multilibs = CSKYMultilibs;
 }
 
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+///   - ABI must be the same.
+///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+///   - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+const Multilib::flags_list &Flags,
+llvm::SmallVector &SelectedMultilibs) {
+  // Try to find the perfect matching multi-lib first.
+  if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+return true;
+
+  llvm::StringMap FlagSet;
+  Multilib::flags_list NewFlags;
+  std::vector NewMultilibs;
+
+  auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+  Arch, /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!ParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+consumeError(ParseResult.takeError());
+return false;
+  }
+  auto &ISAInfo = *ParseResult;
+
+  auto CurrentExts = ISAInfo->getExtensions();
+
+  addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+  addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+  // Collect all flags except march=*
+  for (StringRef Flag : Flags) {
+if (Flag.startswith("!march=") || Flag.startswith("-march="))
+  continue;
+
+NewFlags.push_back(Flag.str());
+  }
+
+  llvm::StringSet<> AllArchExts;
+  // Reconstruct multi-lib list, and break march option into seperated
+  // extension. e.g. march=rv32im -> +i +m
+  for (auto M : RISCVMultilibSet) {
+bool Skip = false;
+
+MultilibBuilder NewMultilib =
+MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());
+for (StringRef Flag : M.flags()) {

yetingk wrote:

`StringRef` -> `const StringRef &`

https://github.com/llvm/llvm-project/pull/73765
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenMP] Support for `nothing` in `metadirective` (PR #73690)

2023-11-29 Thread Sandeep Kosuri via cfe-commits

https://github.com/sandeepkosuri closed 
https://github.com/llvm/llvm-project/pull/73690
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 6e01016 - [OpenMP] Support for `nothing` in `metadirective` (#73690)

2023-11-29 Thread via cfe-commits

Author: Sandeep Kosuri
Date: 2023-11-29T15:13:43+05:30
New Revision: 6e0101684e59d5e8b11853a7311c71090547d355

URL: 
https://github.com/llvm/llvm-project/commit/6e0101684e59d5e8b11853a7311c71090547d355
DIFF: 
https://github.com/llvm/llvm-project/commit/6e0101684e59d5e8b11853a7311c71090547d355.diff

LOG: [OpenMP] Support for `nothing` in `metadirective` (#73690)

- Removed an unnecessary check that was preventing `nothing` to work
properly inside `metadirective`.

Added: 


Modified: 
clang/lib/Parse/ParseOpenMP.cpp
clang/test/OpenMP/metadirective_ast_print.c
clang/test/OpenMP/metadirective_empty.cpp
clang/test/OpenMP/nothing_messages.cpp

Removed: 




diff  --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index ca70bb241d6f723..fb7e7a979e49f7e 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2518,12 +2518,14 @@ StmtResult 
Parser::ParseOpenMPDeclarativeOrExecutableDirective(
 
   switch (DKind) {
   case OMPD_nothing:
-if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
-ParsedStmtContext())
-  Diag(Tok, diag::err_omp_immediate_directive)
-<< getOpenMPDirectiveName(DKind) << 0;
 ConsumeToken();
-skipUntilPragmaOpenMPEnd(DKind);
+// If we are parsing the directive within a metadirective, the directive
+// ends with a ')'.
+if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
+  while (Tok.isNot(tok::annot_pragma_openmp_end))
+ConsumeAnyToken();
+else
+  skipUntilPragmaOpenMPEnd(DKind);
 if (Tok.is(tok::annot_pragma_openmp_end))
   ConsumeAnnotationToken();
 break;

diff  --git a/clang/test/OpenMP/metadirective_ast_print.c 
b/clang/test/OpenMP/metadirective_ast_print.c
index ddd5b8633cc5013..d9ff7e764521607 100644
--- a/clang/test/OpenMP/metadirective_ast_print.c
+++ b/clang/test/OpenMP/metadirective_ast_print.c
@@ -67,6 +67,16 @@ void foo(void) {
 default(parallel for)
   for (int i = 0; i < 100; i++)
   ;
+
+#pragma omp metadirective when(implementation = {extension(match_all)} \
+   : nothing) default(parallel for)
+  for (int i = 0; i < 16; i++)
+;
+
+#pragma omp metadirective when(implementation = {extension(match_any)} \
+   : parallel) default(nothing)
+  for (int i = 0; i < 16; i++)
+;
 }
 
 // CHECK: void bar(void);
@@ -95,5 +105,7 @@ void foo(void) {
 // CHECK-NEXT: for (int j = 0; j < 16; j++)
 // CHECK-AMDGCN: #pragma omp teams distribute parallel for
 // CHECK-AMDGCN-NEXT: for (int i = 0; i < 100; i++)
+// CHECK: for (int i = 0; i < 16; i++)
+// CHECK: for (int i = 0; i < 16; i++)
 
 #endif

diff  --git a/clang/test/OpenMP/metadirective_empty.cpp 
b/clang/test/OpenMP/metadirective_empty.cpp
index 8708aa45b156309..b93ed722cb6e904 100644
--- a/clang/test/OpenMP/metadirective_empty.cpp
+++ b/clang/test/OpenMP/metadirective_empty.cpp
@@ -14,11 +14,17 @@ void func() {
:) default(parallel for)
   for (int i = 0; i < N; i++)
 ;
+
+#pragma omp metadirective when(implementation = {vendor(llvm)} \
+   :nothing) default(parallel for)
+  for (int i = 0; i < N; i++)
+;
 }
 
 // CHECK-LABEL: void @_Z4funcv()
 // CHECK: entry:
 // CHECK:   [[I:%.+]] = alloca i32,
+// CHECK:   [[I1:%.+]] = alloca i32,
 // CHECK:   store i32 0, ptr [[I]],
 // CHECK:   br label %[[FOR_COND:.+]]
 // CHECK: [[FOR_COND]]:
@@ -33,6 +39,20 @@ void func() {
 // CHECK:   store i32 [[INC]], ptr [[I]],
 // CHECK:   br label %[[FOR_COND]],
 // CHECK: [[FOR_END]]:
+// CHECK:   store i32 0, ptr [[I1]],
+// CHECK:   br label %[[FOR_COND1:.+]]
+// CHECK: [[FOR_COND1]]:
+// CHECK:   [[TWO:%.+]] = load i32, ptr [[I1]],
+// CHECK:   [[CMP1:%.+]] = icmp slt i32 [[TWO]], 1000
+// CHECK:   br i1 [[CMP1]], label %[[FOR_BODY1:.+]], label %[[FOR_END1:.+]]
+// CHECK: [[FOR_BODY1]]:
+// CHECK:   br label %[[FOR_INC1:.+]]
+// CHECK: [[FOR_INC1]]:
+// CHECK:   [[THREE:%.+]] = load i32, ptr [[I1]],
+// CHECK:   [[INC1:%.+]] = add nsw i32 [[THREE]], 1
+// CHECK:   store i32 [[INC1]], ptr [[I1]],
+// CHECK:   br label %[[FOR_COND1]],
+// CHECK: [[FOR_END1]]:
 // CHECK:   ret void
 // CHECK: }
 

diff  --git a/clang/test/OpenMP/nothing_messages.cpp 
b/clang/test/OpenMP/nothing_messages.cpp
index cd6d0defe492fb4..0e27e3c27076a7b 100644
--- a/clang/test/OpenMP/nothing_messages.cpp
+++ b/clang/test/OpenMP/nothing_messages.cpp
@@ -12,7 +12,6 @@ int mixed() {
 x=d;
   }
 
-// expected-error@+2 {{#pragma omp nothing' cannot be an immediate 
substatement}}
   if(!x)
 #pragma omp nothing
 x=d;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread Yeting Kuo via cfe-commits


@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const 
llvm::Triple &TargetTriple,
 Result.Multilibs = CSKYMultilibs;
 }
 
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+///   - ABI must be the same.
+///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+///   - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+const Multilib::flags_list &Flags,
+llvm::SmallVector &SelectedMultilibs) {
+  // Try to find the perfect matching multi-lib first.
+  if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+return true;
+
+  llvm::StringMap FlagSet;
+  Multilib::flags_list NewFlags;
+  std::vector NewMultilibs;
+
+  auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+  Arch, /*EnableExperimentalExtension=*/true,
+  /*ExperimentalExtensionVersionCheck=*/false);
+  if (!ParseResult) {
+// Ignore any error here, we assume it will handled in another place.
+consumeError(ParseResult.takeError());
+return false;
+  }
+  auto &ISAInfo = *ParseResult;
+
+  auto CurrentExts = ISAInfo->getExtensions();

yetingk wrote:

Maybe use accurate type instead of `auto`. LLVM only uses `auto` if it makes 
the code more readable or easier to maintain.

Ref: 
https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable

https://github.com/llvm/llvm-project/pull/73765
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain (PR #73765)

2023-11-29 Thread Yeting Kuo via cfe-commits

https://github.com/yetingk edited 
https://github.com/llvm/llvm-project/pull/73765
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] AArch64: add support for currently released Apple CPUs. (PR #73499)

2023-11-29 Thread Tim Northover via cfe-commits

https://github.com/TNorthover updated 
https://github.com/llvm/llvm-project/pull/73499

>From 61e58d0eb96f9443e13879c3055d3d32b33dc2d4 Mon Sep 17 00:00:00 2001
From: Tim Northover 
Date: Wed, 22 Nov 2023 14:10:31 +
Subject: [PATCH] AArch64: add support for currently released Apple CPUs.

These are still v8.6a so mostly just a copy/paste job.
---
 clang/test/Misc/target-invalid-cpu-note.c |  4 +--
 .../llvm/TargetParser/AArch64TargetParser.h   | 10 
 llvm/lib/Target/AArch64/AArch64.td| 25 ++-
 llvm/lib/Target/AArch64/AArch64Subtarget.cpp  |  2 ++
 llvm/lib/Target/AArch64/AArch64Subtarget.h|  1 +
 .../TargetParser/TargetParserTest.cpp | 22 +++-
 6 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/clang/test/Misc/target-invalid-cpu-note.c 
b/clang/test/Misc/target-invalid-cpu-note.c
index 693f47a78b7fa57..c7146e63add5f20 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -5,11 +5,11 @@
 
 // RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix AARCH64
 // AARCH64: error: unknown target CPU 'not-a-cpu'
-// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, 
cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, cortex-a65, 
cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, 
cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, 
cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, 
neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, 
neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, 
apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-m1, apple-m2, 
apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, 
thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, 
tsv110, a64fx, carmel, ampere1, ampere1a, grace{{$}}
+// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, 
cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, cortex-a65, 
cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, 
cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, 
cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, 
neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, 
neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, 
apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, 
apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, 
falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, 
thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, grace{{$}}
 
 // RUN: not %clang_cc1 -triple arm64--- -tune-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix TUNE_AARCH64
 // TUNE_AARCH64: error: unknown target CPU 'not-a-cpu'
-// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, 
cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, 
cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, 
cortex-a76ae, cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-a715, 
cortex-a720, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, 
cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, 
neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, 
apple-a12, apple-a13, apple-a14, apple-a15, apple-a16,  apple-m1, apple-m2, 
apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, 
thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, 
tsv110, a64fx, carmel, ampere1, ampere1a, grace{{$}}
+// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, 
cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, 
cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, 
cortex-a76ae, cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-a715, 
cortex-a720, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, 
cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, 
neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, 
apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, 
apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, 
falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, 
thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, grace{{$}}
 
 // RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix X86
 // X86: error: unknown target CPU 'not-a-cpu'
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h 
b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 6dc93ca74a38a87..17cafd146b0e75d

[llvm] [clang] AArch64: add support for currently released Apple CPUs. (PR #73499)

2023-11-29 Thread Tim Northover via cfe-commits

TNorthover wrote:

Push was to resolve merge conflicts.

https://github.com/llvm/llvm-project/pull/73499
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 10d6d5f - AArch64: add support for currently released Apple CPUs. (#73499)

2023-11-29 Thread via cfe-commits

Author: Tim Northover
Date: 2023-11-29T09:51:42Z
New Revision: 10d6d5f224c2e9b5fed025940bc1ac45a4f6f70f

URL: 
https://github.com/llvm/llvm-project/commit/10d6d5f224c2e9b5fed025940bc1ac45a4f6f70f
DIFF: 
https://github.com/llvm/llvm-project/commit/10d6d5f224c2e9b5fed025940bc1ac45a4f6f70f.diff

LOG: AArch64: add support for currently released Apple CPUs. (#73499)

These are still v8.6a and have no real changes as far as LLVM cares, so
it's mostly just a copy/paste job.

Added: 


Modified: 
clang/test/Misc/target-invalid-cpu-note.c
llvm/include/llvm/TargetParser/AArch64TargetParser.h
llvm/lib/Target/AArch64/AArch64.td
llvm/lib/Target/AArch64/AArch64Subtarget.cpp
llvm/lib/Target/AArch64/AArch64Subtarget.h
llvm/unittests/TargetParser/TargetParserTest.cpp

Removed: 




diff  --git a/clang/test/Misc/target-invalid-cpu-note.c 
b/clang/test/Misc/target-invalid-cpu-note.c
index 693f47a78b7fa57..c7146e63add5f20 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -5,11 +5,11 @@
 
 // RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix AARCH64
 // AARCH64: error: unknown target CPU 'not-a-cpu'
-// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, 
cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, cortex-a65, 
cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, 
cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, 
cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, 
neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, 
neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, 
apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-m1, apple-m2, 
apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, 
thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, 
tsv110, a64fx, carmel, ampere1, ampere1a, grace{{$}}
+// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, 
cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, cortex-a65, 
cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, 
cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, 
cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, 
neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, 
neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, 
apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, 
apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, 
falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, 
thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, grace{{$}}
 
 // RUN: not %clang_cc1 -triple arm64--- -tune-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix TUNE_AARCH64
 // TUNE_AARCH64: error: unknown target CPU 'not-a-cpu'
-// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, 
cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, 
cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, 
cortex-a76ae, cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-a715, 
cortex-a720, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, 
cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, 
neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, 
apple-a12, apple-a13, apple-a14, apple-a15, apple-a16,  apple-m1, apple-m2, 
apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, 
thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, 
tsv110, a64fx, carmel, ampere1, ampere1a, grace{{$}}
+// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, 
cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, 
cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, 
cortex-a76ae, cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-a715, 
cortex-a720, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, 
cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, 
neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, 
apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, 
apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, 
falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, 
thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, grace{{$}}
 
 // RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix X86
 // X86: error: unknown target CPU 'not-a-cpu'

diff  --git a/llvm/include/llvm/TargetPar

[llvm] [clang] AArch64: add support for currently released Apple CPUs. (PR #73499)

2023-11-29 Thread Tim Northover via cfe-commits

https://github.com/TNorthover closed 
https://github.com/llvm/llvm-project/pull/73499
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-29 Thread Sameer Sahasrabuddhe via cfe-commits

ssahasra wrote:

> ping

Some comments still need to be addressed.

https://github.com/llvm/llvm-project/pull/72556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-29 Thread Sameer Sahasrabuddhe via cfe-commits


@@ -406,5 +410,9 @@ TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f32, "iffiIb", 
"nc", "fp8-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f32, "ifiiIi", "nc", "fp8-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f32, "ifiiIi", "nc", "fp8-insts")
 
+// OpenCL
+LANGBUILTIN(printf, "icC*4.", "fp:0:", ALL_OCL_LANGUAGES)

ssahasra wrote:

Although we talked about this offline, the explanation needs to be added here. 
In fact, the motivation for having this builtin should be added as a comment to 
the source itself for future reference.

https://github.com/llvm/llvm-project/pull/72556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-29 Thread Sameer Sahasrabuddhe via cfe-commits


@@ -198,6 +229,10 @@ static void locateCStrings(SparseBitVector<8> &BV, 
StringRef Str) {
 if (SpecEnd == StringRef::npos)
   return;
 auto Spec = Str.slice(SpecPos, SpecEnd + 1);
+
+if ((Spec.find_first_of("v")) != StringRef::npos)

ssahasra wrote:

Just ".find()" should be sufficient?

https://github.com/llvm/llvm-project/pull/72556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-29 Thread Sameer Sahasrabuddhe via cfe-commits


@@ -26,28 +26,31 @@ using namespace llvm;
 
 #define DEBUG_TYPE "amdgpu-emit-printf"
 
-static Value *fitArgInto64Bits(IRBuilder<> &Builder, Value *Arg) {
+static Value *fitArgInto64Bits(IRBuilder<> &Builder, Value *Arg,
+   bool IsBuffered) {
+  const DataLayout &DL = 
Builder.GetInsertBlock()->getModule()->getDataLayout();
   auto Int64Ty = Builder.getInt64Ty();
   auto Ty = Arg->getType();
 
   if (auto IntTy = dyn_cast(Ty)) {
-switch (IntTy->getBitWidth()) {
-case 32:
-  return Builder.CreateZExt(Arg, Int64Ty);
-case 64:
-  return Arg;
+if (IntTy->getBitWidth() < 64) {
+  return Builder.CreateZExt(Arg, Builder.getInt64Ty());
 }
   }
 
-  if (Ty->getTypeID() == Type::DoubleTyID) {
+  if (Ty->isFloatingPointTy()) {
+if (DL.getTypeAllocSize(Ty) < 8)
+  Arg = Builder.CreateFPExt(Arg, Builder.getDoubleTy());
+if (IsBuffered)
+  return Arg;
 return Builder.CreateBitCast(Arg, Int64Ty);
   }
 
-  if (isa(Ty)) {
+  if (!IsBuffered && isa(Ty)) {
 return Builder.CreatePtrToInt(Arg, Int64Ty);

ssahasra wrote:

Information like this should be written in comments in the source code itself.

https://github.com/llvm/llvm-project/pull/72556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Draft:[analyzer]:fix valistChecker false negative in windows platform (PR #72951)

2023-11-29 Thread via cfe-commits

https://github.com/mzyKi edited https://github.com/llvm/llvm-project/pull/72951
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-29 Thread Sameer Sahasrabuddhe via cfe-commits


@@ -1,12 +1,68 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
-// RUN: %clang_cc1 -cl-std=CL1.2 -triple amdgcn-amd-amdhsa 
-disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -cl-std=CL1.2 -triple amdgcn-amd-amdhsa 
-mprintf-kind=buffered -disable-llvm-passes -emit-llvm -o - %s | FileCheck 
--check-prefix=CHECK_BUFFERED %s
+// RUN: %clang_cc1 -cl-std=CL1.2 -triple amdgcn-amd-amdhsa 
-mprintf-kind=hostcall -disable-llvm-passes -emit-llvm -o - %s | FileCheck 
--check-prefix=CHECK_HOSTCALL %s
 
 int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 
2)));

ssahasra wrote:

I only see tests with the "v" correctly used as a vector specifier. What about 
tests like "%dv", and other cases where either the "v" is wrong, or it's just 
part of the text being printed? Given that the first attempt at detecting "v" 
had errors in it, I think it will be good to cover all corner cases where a "v" 
is actually a vector specifier and and where it is not.

https://github.com/llvm/llvm-project/pull/72556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Draft:[analyzer]:fix valistChecker false negative in windows platform (PR #72951)

2023-11-29 Thread via cfe-commits

https://github.com/mzyKi edited https://github.com/llvm/llvm-project/pull/72951
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][analyzer] Support `fgets` in the SteamChecker (PR #73638)

2023-11-29 Thread Balázs Kéri via cfe-commits

https://github.com/balazske approved this pull request.


https://github.com/llvm/llvm-project/pull/73638
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ValueTracking] Add dominating condition support in computeKnownBits() (PR #73662)

2023-11-29 Thread Nikita Popov via cfe-commits


@@ -16,11 +16,15 @@ define i32 @test_asr(i32 %a, i32 %b) {
 ; CHECK-NEXT:[[C:%.*]] = icmp slt i32 [[A]], 0
 ; CHECK-NEXT:br i1 [[C]], label [[BB2:%.*]], label [[BB3:%.*]]
 ; CHECK:   bb2:
+; CHECK-NEXT:[[NOT:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT:[[D:%.*]] = lshr i32 [[NOT]], [[B]]
+; CHECK-NEXT:[[NOT2:%.*]] = xor i32 [[D]], -1

nikic wrote:

Regression.

https://github.com/llvm/llvm-project/pull/73662
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[flang] [clang] [Flang][Clang] Add support for frame pointers in Flang Driver (PR #72146)

2023-11-29 Thread Tom Eccles via cfe-commits

https://github.com/tblah approved this pull request.

LGTM, thanks!

https://github.com/llvm/llvm-project/pull/72146
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [ValueTracking] Add dominating condition support in computeKnownBits() (PR #73662)

2023-11-29 Thread Nikita Popov via cfe-commits

nikic wrote:

> Just realized that this doesn't cover uses of isKnownNonNegative() in 
> InstCombine yet, as it currently doesn't go through SimplifyQuery. I'll see 
> about migrating those APIs tomorrow.

This is done now, but introduced an additional regression in idioms.ll.

https://github.com/llvm/llvm-project/pull/73662
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] Replace usage of StringRef::find_last_of with a string literal of size one by the equivalent char literal (PR #73776)

2023-11-29 Thread Lucas Duarte Prates via cfe-commits

https://github.com/pratlucas created 
https://github.com/llvm/llvm-project/pull/73776

None

>From bff5119a857124f113d9dc499701ad87941fe1c3 Mon Sep 17 00:00:00 2001
From: Lucas Prates 
Date: Wed, 15 Nov 2023 10:33:42 +
Subject: [PATCH] [AArch64] Assembly support for the Checked Pointer Arithmetic
 Extension

This introduces assembly support for the Checked Pointer Arithmetic
Extension (FEAT_CPA), annouced as part of the Armv9.5-A architecture
version.

The changes include:
* New subtarget feature for FEAT_CPA
* New scalar instruction for pointer arithmetic
  * ADDPT, SUBPT, MADDPT, and MSUBPT
* New SVE instructions for pointer arithmetic
  * ADDPT (vectors, predicated), ADDPT (vectors, unpredicated)
  * SUBPT (vectors, predicated), SUBPT (vectors, unpredicated)
  * MADPT and MLAPT
* New ID_AA64ISAR3_EL1 system register

Mode details about the extension can be found at:
* 
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/arm-a-profile-architecture-developments-2023
* https://developer.arm.com/documentation/ddi0602/2023-09/

Co-authored-by: Rodolfo Wottrich 
---
 clang/test/Driver/aarch64-v95a.c  |  5 ++
 .../llvm/TargetParser/AArch64TargetParser.h   |  5 +-
 llvm/lib/Target/AArch64/AArch64.td|  5 +-
 .../lib/Target/AArch64/AArch64InstrFormats.td | 52 ++
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   | 19 +
 .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 21 ++
 llvm/lib/Target/AArch64/AArch64SchedA64FX.td  |  2 +-
 .../Target/AArch64/AArch64SchedNeoverseN2.td  |  2 +-
 .../Target/AArch64/AArch64SchedNeoverseV1.td  |  2 +-
 .../Target/AArch64/AArch64SchedNeoverseV2.td  |  2 +-
 .../AArch64/AsmParser/AArch64AsmParser.cpp| 18 +
 llvm/lib/Target/AArch64/SVEInstrFormats.td| 31 +
 llvm/test/MC/AArch64/SVE/armv9.5a-cpa.s   | 69 +++
 llvm/test/MC/AArch64/armv9.5a-cpa.s   | 50 ++
 llvm/test/MC/AArch64/basic-a64-diagnostics.s  |  8 +++
 llvm/test/MC/AArch64/basic-a64-instructions.s |  4 ++
 .../MC/Disassembler/AArch64/armv9.5a-cpa.txt  | 42 +++
 .../AArch64/basic-a64-instructions.txt|  2 +
 .../TargetParser/TargetParserTest.cpp |  4 +-
 19 files changed, 336 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/MC/AArch64/SVE/armv9.5a-cpa.s
 create mode 100644 llvm/test/MC/AArch64/armv9.5a-cpa.s
 create mode 100644 llvm/test/MC/Disassembler/AArch64/armv9.5a-cpa.txt

diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c
index 6044a4f155db02c..366cade86a9fb71 100644
--- a/clang/test/Driver/aarch64-v95a.c
+++ b/clang/test/Driver/aarch64-v95a.c
@@ -13,3 +13,8 @@
 // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5-a -### -c %s 
2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
 // GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" 
"generic" "-target-feature" "+neon" "-target-feature" "+v9.5a"
 
+// = Features supported on aarch64 =
+
+// RUN: %clang -target aarch64 -march=armv9.5a+cpa -### -c %s 2>&1 | FileCheck 
-check-prefix=V95A-CPA %s
+// RUN: %clang -target aarch64 -march=armv9.5-a+cpa -### -c %s 2>&1 | 
FileCheck -check-prefix=V95A-CPA %s
+// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" 
"-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+cpa"
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h 
b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 38ccca56336abb9..90fd666da8d13b5 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -173,6 +173,7 @@ enum ArchExtKind : unsigned {
   AEK_SMEF8F16 =  69, // FEAT_SME_F8F16
   AEK_SMEF8F32 =  70, // FEAT_SME_F8F32
   AEK_SMEFA64 =   71, // FEAT_SME_FA64
+  AEK_CPA =   72, // FEAT_CPA
   AEK_NUM_EXTENSIONS
 };
 using ExtensionBitset = Bitset;
@@ -295,6 +296,7 @@ inline constexpr ExtensionInfo Extensions[] = {
 {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-fa64",  AArch64::AEK_SMEFA64,  "+sme-fa64", "-sme-fa64",  FEAT_INIT, 
"", 0},
+{"cpa", AArch64::AEK_CPA, "+cpa", "-cpa", FEAT_INIT, "", 0},
 // Special cases
 {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", 
ExtensionInfo::MaxFMVPriority},
 };
@@ -378,7 +380,8 @@ inline constexpr ArchInfo ARMV9_3A  = { VersionTuple{9, 3}, 
AProfile, "armv9.3-a
 
AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))};
 inline constexpr ArchInfo ARMV9_4A  = { VersionTuple{9, 4}, AProfile, 
"armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts |
 
AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, 
AArch64::AEK_RASv2}))};
-inline constexpr ArchInfo ARMV9_5A  = { Ver

[llvm] [clang] Replace usage of StringRef::find_last_of with a string literal of size one by the equivalent char literal (PR #73776)

2023-11-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Lucas Duarte Prates (pratlucas)


Changes



---

Patch is 27.46 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/73776.diff


19 Files Affected:

- (modified) clang/test/Driver/aarch64-v95a.c (+5) 
- (modified) llvm/include/llvm/TargetParser/AArch64TargetParser.h (+4-1) 
- (modified) llvm/lib/Target/AArch64/AArch64.td (+4-1) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrFormats.td (+52) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+19) 
- (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+21) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedA64FX.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseV2.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+18) 
- (modified) llvm/lib/Target/AArch64/SVEInstrFormats.td (+31) 
- (added) llvm/test/MC/AArch64/SVE/armv9.5a-cpa.s (+69) 
- (added) llvm/test/MC/AArch64/armv9.5a-cpa.s (+50) 
- (modified) llvm/test/MC/AArch64/basic-a64-diagnostics.s (+8) 
- (modified) llvm/test/MC/AArch64/basic-a64-instructions.s (+4) 
- (added) llvm/test/MC/Disassembler/AArch64/armv9.5a-cpa.txt (+42) 
- (modified) llvm/test/MC/Disassembler/AArch64/basic-a64-instructions.txt (+2) 
- (modified) llvm/unittests/TargetParser/TargetParserTest.cpp (+3-1) 


``diff
diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c
index 6044a4f155db02c..366cade86a9fb71 100644
--- a/clang/test/Driver/aarch64-v95a.c
+++ b/clang/test/Driver/aarch64-v95a.c
@@ -13,3 +13,8 @@
 // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5-a -### -c %s 
2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
 // GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" 
"generic" "-target-feature" "+neon" "-target-feature" "+v9.5a"
 
+// = Features supported on aarch64 =
+
+// RUN: %clang -target aarch64 -march=armv9.5a+cpa -### -c %s 2>&1 | FileCheck 
-check-prefix=V95A-CPA %s
+// RUN: %clang -target aarch64 -march=armv9.5-a+cpa -### -c %s 2>&1 | 
FileCheck -check-prefix=V95A-CPA %s
+// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" 
"-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+cpa"
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h 
b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 38ccca56336abb9..90fd666da8d13b5 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -173,6 +173,7 @@ enum ArchExtKind : unsigned {
   AEK_SMEF8F16 =  69, // FEAT_SME_F8F16
   AEK_SMEF8F32 =  70, // FEAT_SME_F8F32
   AEK_SMEFA64 =   71, // FEAT_SME_FA64
+  AEK_CPA =   72, // FEAT_CPA
   AEK_NUM_EXTENSIONS
 };
 using ExtensionBitset = Bitset;
@@ -295,6 +296,7 @@ inline constexpr ExtensionInfo Extensions[] = {
 {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-fa64",  AArch64::AEK_SMEFA64,  "+sme-fa64", "-sme-fa64",  FEAT_INIT, 
"", 0},
+{"cpa", AArch64::AEK_CPA, "+cpa", "-cpa", FEAT_INIT, "", 0},
 // Special cases
 {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", 
ExtensionInfo::MaxFMVPriority},
 };
@@ -378,7 +380,8 @@ inline constexpr ArchInfo ARMV9_3A  = { VersionTuple{9, 3}, 
AProfile, "armv9.3-a
 
AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))};
 inline constexpr ArchInfo ARMV9_4A  = { VersionTuple{9, 4}, AProfile, 
"armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts |
 
AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, 
AArch64::AEK_RASv2}))};
-inline constexpr ArchInfo ARMV9_5A  = { VersionTuple{9, 5}, AProfile, 
"armv9.5-a", "+v9.5a", (ARMV9_4A.DefaultExts)};
+inline constexpr ArchInfo ARMV9_5A  = { VersionTuple{9, 5}, AProfile, 
"armv9.5-a", "+v9.5a", (ARMV9_4A.DefaultExts |
+
AArch64::ExtensionBitset({AArch64::AEK_CPA}))};
 // For v8-R, we do not enable crypto and align with GCC that enables a more 
minimal set of optional architecture extensions.
 inline constexpr ArchInfo ARMV8R= { VersionTuple{8, 0}, RProfile, 
"armv8-r", "+v8r", (ARMV8_5A.DefaultExts |
 
AArch64::ExtensionBitset({AArch64::AEK_SSBS,
diff --git a/llvm/lib/Target/AArch64/AArch64.td 
b/llvm/lib/Target/AArch64/AArch64.td
index 914ad0b68a624f6..4a829d3278fe0e9 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -622,6 +622,9 @@ def FeatureLdpAlignedOnly : 
SubtargetFeature<"ldp-aligned-only", "HasLdpAlignedO
 def FeatureStpAlignedOnly 

[clang] [llvm] Replace usage of StringRef::find_last_of with a string literal of size one by the equivalent char literal (PR #73776)

2023-11-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-mc

Author: Lucas Duarte Prates (pratlucas)


Changes



---

Patch is 27.46 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/73776.diff


19 Files Affected:

- (modified) clang/test/Driver/aarch64-v95a.c (+5) 
- (modified) llvm/include/llvm/TargetParser/AArch64TargetParser.h (+4-1) 
- (modified) llvm/lib/Target/AArch64/AArch64.td (+4-1) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrFormats.td (+52) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+19) 
- (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+21) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedA64FX.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseV2.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+18) 
- (modified) llvm/lib/Target/AArch64/SVEInstrFormats.td (+31) 
- (added) llvm/test/MC/AArch64/SVE/armv9.5a-cpa.s (+69) 
- (added) llvm/test/MC/AArch64/armv9.5a-cpa.s (+50) 
- (modified) llvm/test/MC/AArch64/basic-a64-diagnostics.s (+8) 
- (modified) llvm/test/MC/AArch64/basic-a64-instructions.s (+4) 
- (added) llvm/test/MC/Disassembler/AArch64/armv9.5a-cpa.txt (+42) 
- (modified) llvm/test/MC/Disassembler/AArch64/basic-a64-instructions.txt (+2) 
- (modified) llvm/unittests/TargetParser/TargetParserTest.cpp (+3-1) 


``diff
diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c
index 6044a4f155db02c..366cade86a9fb71 100644
--- a/clang/test/Driver/aarch64-v95a.c
+++ b/clang/test/Driver/aarch64-v95a.c
@@ -13,3 +13,8 @@
 // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5-a -### -c %s 
2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
 // GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" 
"generic" "-target-feature" "+neon" "-target-feature" "+v9.5a"
 
+// = Features supported on aarch64 =
+
+// RUN: %clang -target aarch64 -march=armv9.5a+cpa -### -c %s 2>&1 | FileCheck 
-check-prefix=V95A-CPA %s
+// RUN: %clang -target aarch64 -march=armv9.5-a+cpa -### -c %s 2>&1 | 
FileCheck -check-prefix=V95A-CPA %s
+// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" 
"-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+cpa"
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h 
b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 38ccca56336abb9..90fd666da8d13b5 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -173,6 +173,7 @@ enum ArchExtKind : unsigned {
   AEK_SMEF8F16 =  69, // FEAT_SME_F8F16
   AEK_SMEF8F32 =  70, // FEAT_SME_F8F32
   AEK_SMEFA64 =   71, // FEAT_SME_FA64
+  AEK_CPA =   72, // FEAT_CPA
   AEK_NUM_EXTENSIONS
 };
 using ExtensionBitset = Bitset;
@@ -295,6 +296,7 @@ inline constexpr ExtensionInfo Extensions[] = {
 {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-fa64",  AArch64::AEK_SMEFA64,  "+sme-fa64", "-sme-fa64",  FEAT_INIT, 
"", 0},
+{"cpa", AArch64::AEK_CPA, "+cpa", "-cpa", FEAT_INIT, "", 0},
 // Special cases
 {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", 
ExtensionInfo::MaxFMVPriority},
 };
@@ -378,7 +380,8 @@ inline constexpr ArchInfo ARMV9_3A  = { VersionTuple{9, 3}, 
AProfile, "armv9.3-a
 
AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))};
 inline constexpr ArchInfo ARMV9_4A  = { VersionTuple{9, 4}, AProfile, 
"armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts |
 
AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, 
AArch64::AEK_RASv2}))};
-inline constexpr ArchInfo ARMV9_5A  = { VersionTuple{9, 5}, AProfile, 
"armv9.5-a", "+v9.5a", (ARMV9_4A.DefaultExts)};
+inline constexpr ArchInfo ARMV9_5A  = { VersionTuple{9, 5}, AProfile, 
"armv9.5-a", "+v9.5a", (ARMV9_4A.DefaultExts |
+
AArch64::ExtensionBitset({AArch64::AEK_CPA}))};
 // For v8-R, we do not enable crypto and align with GCC that enables a more 
minimal set of optional architecture extensions.
 inline constexpr ArchInfo ARMV8R= { VersionTuple{8, 0}, RProfile, 
"armv8-r", "+v8r", (ARMV8_5A.DefaultExts |
 
AArch64::ExtensionBitset({AArch64::AEK_SSBS,
diff --git a/llvm/lib/Target/AArch64/AArch64.td 
b/llvm/lib/Target/AArch64/AArch64.td
index 914ad0b68a624f6..4a829d3278fe0e9 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -622,6 +622,9 @@ def FeatureLdpAlignedOnly : 
SubtargetFeature<"ldp-aligned-only", "HasLdpAlignedO
 def FeatureStpAlignedOnly : S

[clang] [llvm] Replace usage of StringRef::find_last_of with a string literal of size one by the equivalent char literal (PR #73776)

2023-11-29 Thread Lucas Duarte Prates via cfe-commits

https://github.com/pratlucas closed 
https://github.com/llvm/llvm-project/pull/73776
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Replace usage of StringRef::find_last_of with a string literal of size one by the equivalent char literal (PR #73776)

2023-11-29 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 511218642bc5df7815423de211192dd577eb3a9c 
bff5119a857124f113d9dc499701ad87941fe1c3 -- clang/test/Driver/aarch64-v95a.c 
llvm/include/llvm/TargetParser/AArch64TargetParser.h 
llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp 
llvm/unittests/TargetParser/TargetParserTest.cpp
``





View the diff from clang-format here.


``diff
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h 
b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 90fd666da8..7d946dab57 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -422,9 +422,9 @@ inline constexpr CpuInfo CpuInfos[] = {
  (AArch64::ExtensionBitset(
  {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
 {"cortex-a55", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC}))},
 {"cortex-a510", ARMV9A,
  (AArch64::ExtensionBitset(
  {AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_SB,
@@ -440,13 +440,13 @@ inline constexpr CpuInfo CpuInfos[] = {
  (AArch64::ExtensionBitset(
  {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
 {"cortex-a65", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
-  AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
 {"cortex-a65ae", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
-  AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
 {"cortex-a72", ARMV8A,
  (AArch64::ExtensionBitset(
  {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
@@ -454,38 +454,38 @@ inline constexpr CpuInfo CpuInfos[] = {
  (AArch64::ExtensionBitset(
  {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
 {"cortex-a75", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC}))},
 {"cortex-a76", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
 {"cortex-a76ae", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
 {"cortex-a77", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_RCPC,
+AArch64::AEK_DOTPROD, AArch64::AEK_SSBS}))},
 {"cortex-a78", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
-  AArch64::AEK_PROFILE}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS,
+AArch64::AEK_PROFILE}))},

[llvm] [clang] [AArch64] Assembly support for the Checked Pointer Arithmetic Extension (PR #73777)

2023-11-29 Thread Lucas Duarte Prates via cfe-commits

https://github.com/pratlucas created 
https://github.com/llvm/llvm-project/pull/73777

This introduces assembly support for the Checked Pointer Arithmetic Extension 
(FEAT_CPA), annouced as part of the Armv9.5-A architecture version.

The changes include:
* New subtarget feature for FEAT_CPA
* New scalar instruction for pointer arithmetic
  * ADDPT, SUBPT, MADDPT, and MSUBPT
* New SVE instructions for pointer arithmetic
  * ADDPT (vectors, predicated), ADDPT (vectors, unpredicated)
  * SUBPT (vectors, predicated), SUBPT (vectors, unpredicated)
  * MADPT and MLAPT
* New ID_AA64ISAR3_EL1 system register

Mode details about the extension can be found at:
* 
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/arm-a-profile-architecture-developments-2023
* https://developer.arm.com/documentation/ddi0602/2023-09/

Changes by me and @rgwott .

>From bff5119a857124f113d9dc499701ad87941fe1c3 Mon Sep 17 00:00:00 2001
From: Lucas Prates 
Date: Wed, 15 Nov 2023 10:33:42 +
Subject: [PATCH] [AArch64] Assembly support for the Checked Pointer Arithmetic
 Extension

This introduces assembly support for the Checked Pointer Arithmetic
Extension (FEAT_CPA), annouced as part of the Armv9.5-A architecture
version.

The changes include:
* New subtarget feature for FEAT_CPA
* New scalar instruction for pointer arithmetic
  * ADDPT, SUBPT, MADDPT, and MSUBPT
* New SVE instructions for pointer arithmetic
  * ADDPT (vectors, predicated), ADDPT (vectors, unpredicated)
  * SUBPT (vectors, predicated), SUBPT (vectors, unpredicated)
  * MADPT and MLAPT
* New ID_AA64ISAR3_EL1 system register

Mode details about the extension can be found at:
* 
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/arm-a-profile-architecture-developments-2023
* https://developer.arm.com/documentation/ddi0602/2023-09/

Co-authored-by: Rodolfo Wottrich 
---
 clang/test/Driver/aarch64-v95a.c  |  5 ++
 .../llvm/TargetParser/AArch64TargetParser.h   |  5 +-
 llvm/lib/Target/AArch64/AArch64.td|  5 +-
 .../lib/Target/AArch64/AArch64InstrFormats.td | 52 ++
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   | 19 +
 .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 21 ++
 llvm/lib/Target/AArch64/AArch64SchedA64FX.td  |  2 +-
 .../Target/AArch64/AArch64SchedNeoverseN2.td  |  2 +-
 .../Target/AArch64/AArch64SchedNeoverseV1.td  |  2 +-
 .../Target/AArch64/AArch64SchedNeoverseV2.td  |  2 +-
 .../AArch64/AsmParser/AArch64AsmParser.cpp| 18 +
 llvm/lib/Target/AArch64/SVEInstrFormats.td| 31 +
 llvm/test/MC/AArch64/SVE/armv9.5a-cpa.s   | 69 +++
 llvm/test/MC/AArch64/armv9.5a-cpa.s   | 50 ++
 llvm/test/MC/AArch64/basic-a64-diagnostics.s  |  8 +++
 llvm/test/MC/AArch64/basic-a64-instructions.s |  4 ++
 .../MC/Disassembler/AArch64/armv9.5a-cpa.txt  | 42 +++
 .../AArch64/basic-a64-instructions.txt|  2 +
 .../TargetParser/TargetParserTest.cpp |  4 +-
 19 files changed, 336 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/MC/AArch64/SVE/armv9.5a-cpa.s
 create mode 100644 llvm/test/MC/AArch64/armv9.5a-cpa.s
 create mode 100644 llvm/test/MC/Disassembler/AArch64/armv9.5a-cpa.txt

diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c
index 6044a4f155db02c..366cade86a9fb71 100644
--- a/clang/test/Driver/aarch64-v95a.c
+++ b/clang/test/Driver/aarch64-v95a.c
@@ -13,3 +13,8 @@
 // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5-a -### -c %s 
2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
 // GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" 
"generic" "-target-feature" "+neon" "-target-feature" "+v9.5a"
 
+// = Features supported on aarch64 =
+
+// RUN: %clang -target aarch64 -march=armv9.5a+cpa -### -c %s 2>&1 | FileCheck 
-check-prefix=V95A-CPA %s
+// RUN: %clang -target aarch64 -march=armv9.5-a+cpa -### -c %s 2>&1 | 
FileCheck -check-prefix=V95A-CPA %s
+// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" 
"-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+cpa"
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h 
b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 38ccca56336abb9..90fd666da8d13b5 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -173,6 +173,7 @@ enum ArchExtKind : unsigned {
   AEK_SMEF8F16 =  69, // FEAT_SME_F8F16
   AEK_SMEF8F32 =  70, // FEAT_SME_F8F32
   AEK_SMEFA64 =   71, // FEAT_SME_FA64
+  AEK_CPA =   72, // FEAT_CPA
   AEK_NUM_EXTENSIONS
 };
 using ExtensionBitset = Bitset;
@@ -295,6 +296,7 @@ inline constexpr ExtensionInfo Extensions[] = {
 {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", 
FEAT_INIT, "+sme

[llvm] [clang] [AArch64] Assembly support for the Checked Pointer Arithmetic Extension (PR #73777)

2023-11-29 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-mc

@llvm/pr-subscribers-clang

Author: Lucas Duarte Prates (pratlucas)


Changes

This introduces assembly support for the Checked Pointer Arithmetic Extension 
(FEAT_CPA), annouced as part of the Armv9.5-A architecture version.

The changes include:
* New subtarget feature for FEAT_CPA
* New scalar instruction for pointer arithmetic
  * ADDPT, SUBPT, MADDPT, and MSUBPT
* New SVE instructions for pointer arithmetic
  * ADDPT (vectors, predicated), ADDPT (vectors, unpredicated)
  * SUBPT (vectors, predicated), SUBPT (vectors, unpredicated)
  * MADPT and MLAPT
* New ID_AA64ISAR3_EL1 system register

Mode details about the extension can be found at:
* 
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/arm-a-profile-architecture-developments-2023
* https://developer.arm.com/documentation/ddi0602/2023-09/

Changes by me and @rgwott .

---

Patch is 27.46 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/73777.diff


19 Files Affected:

- (modified) clang/test/Driver/aarch64-v95a.c (+5) 
- (modified) llvm/include/llvm/TargetParser/AArch64TargetParser.h (+4-1) 
- (modified) llvm/lib/Target/AArch64/AArch64.td (+4-1) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrFormats.td (+52) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+19) 
- (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+21) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedA64FX.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseV2.td (+1-1) 
- (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+18) 
- (modified) llvm/lib/Target/AArch64/SVEInstrFormats.td (+31) 
- (added) llvm/test/MC/AArch64/SVE/armv9.5a-cpa.s (+69) 
- (added) llvm/test/MC/AArch64/armv9.5a-cpa.s (+50) 
- (modified) llvm/test/MC/AArch64/basic-a64-diagnostics.s (+8) 
- (modified) llvm/test/MC/AArch64/basic-a64-instructions.s (+4) 
- (added) llvm/test/MC/Disassembler/AArch64/armv9.5a-cpa.txt (+42) 
- (modified) llvm/test/MC/Disassembler/AArch64/basic-a64-instructions.txt (+2) 
- (modified) llvm/unittests/TargetParser/TargetParserTest.cpp (+3-1) 


``diff
diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c
index 6044a4f155db02c..366cade86a9fb71 100644
--- a/clang/test/Driver/aarch64-v95a.c
+++ b/clang/test/Driver/aarch64-v95a.c
@@ -13,3 +13,8 @@
 // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5-a -### -c %s 
2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s
 // GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" 
"generic" "-target-feature" "+neon" "-target-feature" "+v9.5a"
 
+// = Features supported on aarch64 =
+
+// RUN: %clang -target aarch64 -march=armv9.5a+cpa -### -c %s 2>&1 | FileCheck 
-check-prefix=V95A-CPA %s
+// RUN: %clang -target aarch64 -march=armv9.5-a+cpa -### -c %s 2>&1 | 
FileCheck -check-prefix=V95A-CPA %s
+// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" 
"-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+cpa"
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h 
b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 38ccca56336abb9..90fd666da8d13b5 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -173,6 +173,7 @@ enum ArchExtKind : unsigned {
   AEK_SMEF8F16 =  69, // FEAT_SME_F8F16
   AEK_SMEF8F32 =  70, // FEAT_SME_F8F32
   AEK_SMEFA64 =   71, // FEAT_SME_FA64
+  AEK_CPA =   72, // FEAT_CPA
   AEK_NUM_EXTENSIONS
 };
 using ExtensionBitset = Bitset;
@@ -295,6 +296,7 @@ inline constexpr ExtensionInfo Extensions[] = {
 {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", 
FEAT_INIT, "+sme2,+fp8", 0},
 {"sme-fa64",  AArch64::AEK_SMEFA64,  "+sme-fa64", "-sme-fa64",  FEAT_INIT, 
"", 0},
+{"cpa", AArch64::AEK_CPA, "+cpa", "-cpa", FEAT_INIT, "", 0},
 // Special cases
 {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", 
ExtensionInfo::MaxFMVPriority},
 };
@@ -378,7 +380,8 @@ inline constexpr ArchInfo ARMV9_3A  = { VersionTuple{9, 3}, 
AProfile, "armv9.3-a
 
AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))};
 inline constexpr ArchInfo ARMV9_4A  = { VersionTuple{9, 4}, AProfile, 
"armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts |
 
AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, 
AArch64::AEK_RASv2}))};
-inline constexpr ArchInfo ARMV9_5A  = { VersionTuple{9, 5}, AProfile, 
"armv9.5-a", "+v9.5a", (ARMV9_4A.DefaultExts)};
+inline constexpr ArchInfo ARMV9_5A  = { VersionTuple{9, 5}, 

[llvm] [clang] [Abandoned][AArch64] Assembly support for the Checked Pointer Arithmetic Extension (PR #73776)

2023-11-29 Thread Lucas Duarte Prates via cfe-commits

https://github.com/pratlucas edited 
https://github.com/llvm/llvm-project/pull/73776
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [AArch64] Assembly support for the Checked Pointer Arithmetic Extension (PR #73777)

2023-11-29 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 0fac9da7342e7846fbc4464abe5c00086cbf026c 
bff5119a857124f113d9dc499701ad87941fe1c3 -- clang/test/Driver/aarch64-v95a.c 
llvm/include/llvm/TargetParser/AArch64TargetParser.h 
llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp 
llvm/unittests/TargetParser/TargetParserTest.cpp
``





View the diff from clang-format here.


``diff
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h 
b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 90fd666da8..7d946dab57 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -422,9 +422,9 @@ inline constexpr CpuInfo CpuInfos[] = {
  (AArch64::ExtensionBitset(
  {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
 {"cortex-a55", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC}))},
 {"cortex-a510", ARMV9A,
  (AArch64::ExtensionBitset(
  {AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_SB,
@@ -440,13 +440,13 @@ inline constexpr CpuInfo CpuInfos[] = {
  (AArch64::ExtensionBitset(
  {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
 {"cortex-a65", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
-  AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
 {"cortex-a65ae", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
-  AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
 {"cortex-a72", ARMV8A,
  (AArch64::ExtensionBitset(
  {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
@@ -454,38 +454,38 @@ inline constexpr CpuInfo CpuInfos[] = {
  (AArch64::ExtensionBitset(
  {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
 {"cortex-a75", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC}))},
 {"cortex-a76", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
 {"cortex-a76ae", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
 {"cortex-a77", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_SSBS}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_RCPC,
+AArch64::AEK_DOTPROD, AArch64::AEK_SSBS}))},
 {"cortex-a78", ARMV8_2A,
- (AArch64::ExtensionBitset(
- {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
-  AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
-  AArch64::AEK_PROFILE}))},
+ (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+AArch64::AEK_FP16, AArch64::AEK_DOTPROD,
+AArch64::AEK_RCPC, AArch64::AEK_SSBS,
+AArch64::AEK_PROFILE}))},

[clang] [llvm] [AArch64] Assembly support for the Checked Pointer Arithmetic Extension (PR #73777)

2023-11-29 Thread Jonathan Thackray via cfe-commits

https://github.com/jthackray approved this pull request.

Great stuff. Looks good to me.

https://github.com/llvm/llvm-project/pull/73777
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [flang] [Flang][Clang] Add support for frame pointers in Flang Driver (PR #72146)

2023-11-29 Thread Tom Eccles via cfe-commits

tblah wrote:

> LGTM, thanks!

But please fix code formatting before merging

https://github.com/llvm/llvm-project/pull/72146
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)

2023-11-29 Thread Jonas Paulsson via cfe-commits


@@ -1687,7 +1687,8 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool 
ForAlignof) const {
   if (VD->hasGlobalStorage() && !ForAlignof) {
 uint64_t TypeSize =
 !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0;
-Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
+Align = std::max(Align, getTargetInfo().getMinGlobalAlign(
+TypeSize, VD->hasDefinition()));

JonPsson1 wrote:

I can't see that this is working with weak symbols with (recent) GCC:

```
test2.c:
 #include  

char __attribute__((weak)) c0_weak = 0;
char __attribute__((weak)) c1_weak = 0;
 
int main() { 
  printf("%d\n", c0_weak + c1_weak); 
}

test2_1.c:
char __attribute__((aligned(1))) c0_weak = 1;
char __attribute__((aligned(1))) c1_weak = 1;
```

```
gcc ./test2.c ./test2_1.c -O3 -munaligned-symbols -S -c
main:
.LFB11:
.cfi_startproc
larl%r2,c0_weak
larl%r1,c1_weak
...
```

```
~/gcc-latest/bin/gcc ./test2.c ./test2_1.c -O3 -munaligned-symbols
/usr/bin/ld: /tmp/ccj8BnuO.o(.text.startup+0x2): misaligned symbol `c0_weak' 
(0x1004021) for relocation R_390_PC32DBL
collect2: error: ld returned 1 exit status
```

https://github.com/llvm/llvm-project/pull/73511
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [AMDGPU] Improve selection of ballot.i64 intrinsic in wave32 mode. (PR #71556)

2023-11-29 Thread Valery Pykhtin via cfe-commits

https://github.com/vpykhtin updated 
https://github.com/llvm/llvm-project/pull/71556

>From 526c635b3f70fd779f0919c5c40acd017a0f800e Mon Sep 17 00:00:00 2001
From: Valery Pykhtin 
Date: Mon, 20 Nov 2023 15:22:16 +0100
Subject: [PATCH 1/2] add instcombine rule

---
 .../CodeGenOpenCL/builtins-amdgcn-wave32.cl   |   8 +-
 llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp |   2 +-
 .../AMDGPU/AMDGPUInstCombineIntrinsic.cpp |  12 ++
 .../AMDGPU/llvm.amdgcn.ballot.i64.wave32.ll   | 110 ++
 .../InstCombine/AMDGPU/amdgcn-intrinsics.ll   |   6 +-
 5 files changed, 129 insertions(+), 9 deletions(-)

diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-wave32.cl 
b/clang/test/CodeGenOpenCL/builtins-amdgcn-wave32.cl
index 43553131f63c549..a0e27ce22fe7d9c 100644
--- a/clang/test/CodeGenOpenCL/builtins-amdgcn-wave32.cl
+++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-wave32.cl
@@ -24,13 +24,11 @@ void test_ballot_wave32_target_attr(global uint* out, int 
a, int b)
 }
 
 // CHECK-LABEL: @test_read_exec(
-// CHECK: call i64 @llvm.amdgcn.ballot.i64(i1 true)
+// CHECK: call i32 @llvm.amdgcn.ballot.i32(i1 true)
 void test_read_exec(global uint* out) {
   *out = __builtin_amdgcn_read_exec();
 }
 
-// CHECK: declare i64 @llvm.amdgcn.ballot.i64(i1) 
#[[$NOUNWIND_READONLY:[0-9]+]]
-
 // CHECK-LABEL: @test_read_exec_lo(
 // CHECK: call i32 @llvm.amdgcn.ballot.i32(i1 true)
 void test_read_exec_lo(global uint* out) {
@@ -38,9 +36,7 @@ void test_read_exec_lo(global uint* out) {
 }
 
 // CHECK-LABEL: @test_read_exec_hi(
-// CHECK: call i64 @llvm.amdgcn.ballot.i64(i1 true)
-// CHECK: lshr i64 [[A:%.*]], 32
-// CHECK: trunc i64 [[B:%.*]] to i32
+// CHECK: store i32 0, ptr addrspace(1) %out
 void test_read_exec_hi(global uint* out) {
   *out = __builtin_amdgcn_read_exec_hi();
 }
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp 
b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
index ead3f51d6acdc5a..e2ea1a2752af166 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
@@ -2315,7 +2315,7 @@ void AMDGPUDAGToDAGISel::SelectBRCOND(SDNode *N) {
 auto CC = cast(Cond->getOperand(2))->get();
 auto *CRHS = dyn_cast(Cond->getOperand(1));
 if ((CC == ISD::SETEQ || CC == ISD::SETNE) && CRHS && CRHS->isZero() &&
-// TODO: make condition below an assert after fixing ballot bitwidth.
+// We may encounter ballot.i64 in wave32 mode on -O0.
 VCMP.getValueType().getSizeInBits() == ST->getWavefrontSize()) {
   // %VCMP = i(WaveSize) AMDGPUISD::SETCC ...
   // %C = i1 ISD::SETCC %VCMP, 0, setne/seteq
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp 
b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index 5296415ab4c36da..510f0a59719ecdb 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -961,6 +961,18 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, 
IntrinsicInst &II) const {
 return IC.replaceInstUsesWith(II, 
Constant::getNullValue(II.getType()));
   }
 }
+if (ST->isWave32() && II.getType()->getIntegerBitWidth() == 64) {
+  // %b64 = call i64 ballot.i64(...)
+  // =>
+  // %b32 = call i32 ballot.i32(...)
+  // %b64 = zext i32 %b32 to i64
+  Function *NewF = Intrinsic::getDeclaration(
+  II.getModule(), Intrinsic::amdgcn_ballot, {IC.Builder.getInt32Ty()});
+  CallInst *NewCall = IC.Builder.CreateCall(NewF, {II.getArgOperand(0)});
+  Value *CastedCall = IC.Builder.CreateZExtOrBitCast(NewCall, 
II.getType());
+  CastedCall->takeName(&II);
+  return IC.replaceInstUsesWith(II, CastedCall);
+}
 break;
   }
   case Intrinsic::amdgcn_wqm_vote: {
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ballot.i64.wave32.ll 
b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ballot.i64.wave32.ll
index 04a993eac82cd5e..e5344b28edf2b59 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ballot.i64.wave32.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ballot.i64.wave32.ll
@@ -3,6 +3,10 @@
 ; RUN: llc -march=amdgcn -global-isel=0 -mcpu=gfx1100 
-amdgpu-enable-delay-alu=0 < %s | FileCheck %s --check-prefixes=CHECK,DAGISEL
 ; RUN: llc -march=amdgcn -global-isel -mcpu=gfx1010 < %s | FileCheck %s 
--check-prefixes=CHECK,GISEL
 ; RUN: llc -march=amdgcn -global-isel -mcpu=gfx1100 -amdgpu-enable-delay-alu=0 
< %s | FileCheck %s --check-prefixes=CHECK,GISEL
+; RUN: opt -mtriple=amdgcn-- -mcpu=gfx1010 
-mattr=+wavefrontsize32,-wavefrontsize64 -passes=instcombine -o - < %s | llc 
-march=amdgcn -global-isel=0 -mcpu=gfx1010 - | FileCheck %s 
--check-prefixes=CHECK-OPT,DAGISEL-OPT
+; RUN: opt -mtriple=amdgcn-- -mcpu=gfx1100 
-mattr=+wavefrontsize32,-wavefrontsize64 -passes=instcombine -o - < %s | llc 
-march=amdgcn -global-isel=0 -mcpu=gfx1100 -amdgpu-enable-delay-alu=0 - | 
FileCheck %s --check-prefixes=CHECK-OPT,DAGISEL-OPT
+; RUN: opt -mtriple=amdgcn-- -mcpu=gfx1010 
-mattr=+wavefrontsize32,-wavefro

[clang] [llvm] [AArch64] Assembly support for the Checked Pointer Arithmetic Extension (PR #73777)

2023-11-29 Thread Rodolfo Wottrich via cfe-commits

https://github.com/rgwott approved this pull request.

Approved.

https://github.com/llvm/llvm-project/pull/73777
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [AMDGPU] Improve selection of ballot.i64 intrinsic in wave32 mode. (PR #71556)

2023-11-29 Thread Valery Pykhtin via cfe-commits

vpykhtin wrote:

I'm going to rebase it on top of 
https://github.com/llvm/llvm-project/pull/73779 to show test changes.

https://github.com/llvm/llvm-project/pull/71556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [AMDGPU] Improve selection of ballot.i64 intrinsic in wave32 mode. (PR #71556)

2023-11-29 Thread Valery Pykhtin via cfe-commits


@@ -961,6 +961,18 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, 
IntrinsicInst &II) const {
 return IC.replaceInstUsesWith(II, 
Constant::getNullValue(II.getType()));
   }
 }
+if (ST->isWave32() && II.getType()->getIntegerBitWidth() == 64) {
+  // %b64 = call i64 ballot.i64(...)
+  // =>
+  // %b32 = call i32 ballot.i32(...)
+  // %b64 = zext i32 %b32 to i64
+  Function *NewF = Intrinsic::getDeclaration(
+  II.getModule(), Intrinsic::amdgcn_ballot, {IC.Builder.getInt32Ty()});
+  CallInst *NewCall = IC.Builder.CreateCall(NewF, {II.getArgOperand(0)});
+  Value *CastedCall = IC.Builder.CreateZExtOrBitCast(NewCall, 
II.getType());
+  CastedCall->takeName(&II);
+  return IC.replaceInstUsesWith(II, CastedCall);

vpykhtin wrote:

Thanks, changed to `IC.Builder.CreateIntrinsic`. I decided to use it as a temp 
for `CreateZExtOrBitCast`.

https://github.com/llvm/llvm-project/pull/71556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 47df664 - [clang][analyzer] Support `fgets` in the SteamChecker (#73638)

2023-11-29 Thread via cfe-commits

Author: Ben Shi
Date: 2023-11-29T19:20:49+08:00
New Revision: 47df664c7acfd8abd082c0252d1793182c92dc3d

URL: 
https://github.com/llvm/llvm-project/commit/47df664c7acfd8abd082c0252d1793182c92dc3d
DIFF: 
https://github.com/llvm/llvm-project/commit/47df664c7acfd8abd082c0252d1793182c92dc3d.diff

LOG: [clang][analyzer] Support `fgets` in the SteamChecker (#73638)

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
clang/test/Analysis/Inputs/system-header-simulator.h
clang/test/Analysis/stream-error.c
clang/test/Analysis/stream.c

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index eccb2063fad10d0..a4799b5f762caee 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -252,7 +252,10 @@ class StreamChecker : public CheckerErrorState != ErrorFEof) {
-NonLoc RetVal = makeRetVal(C, CE).castAs();
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), RetVal);
-SValBuilder &SVB = C.getSValBuilder();
-ASTContext &ASTC = C.getASTContext();
-// The returned 'unsigned char' of `fgetc` is converted to 'int',
-// so we need to check if it is in range [0, 255].
-auto CondLow =
-SVB.evalBinOp(State, BO_GE, RetVal, SVB.makeZeroVal(ASTC.IntTy),
-  SVB.getConditionType())
-.getAs();
-auto CondHigh =
-SVB.evalBinOp(State, BO_LE, RetVal,
-  SVB.makeIntVal(SVB.getBasicValueFactory()
- .getMaxValue(ASTC.UnsignedCharTy)
- .getLimitedValue(),
- ASTC.IntTy),
-  SVB.getConditionType())
-.getAs();
-if (!CondLow || !CondHigh)
-  return;
-StateNotFailed = StateNotFailed->assume(*CondLow, true);
-if (!StateNotFailed)
-  return;
-StateNotFailed = StateNotFailed->assume(*CondHigh, true);
-if (!StateNotFailed)
-  return;
-C.addTransition(StateNotFailed);
+if (SingleChar) {
+  // Generate a transition for the success state of `fgetc`.
+  NonLoc RetVal = makeRetVal(C, CE).castAs();
+  ProgramStateRef StateNotFailed =
+  State->BindExpr(CE, C.getLocationContext(), RetVal);
+  SValBuilder &SVB = C.getSValBuilder();
+  ASTContext &ASTC = C.getASTContext();
+  // The returned 'unsigned char' of `fgetc` is converted to 'int',
+  // so we need to check if it is in range [0, 255].
+  auto CondLow =
+  SVB.evalBinOp(State, BO_GE, RetVal, SVB.makeZeroVal(ASTC.IntTy),
+SVB.getConditionType())
+  .getAs();
+  auto CondHigh =
+  SVB.evalBinOp(State, BO_LE, RetVal,
+SVB.makeIntVal(SVB.getBasicValueFactory()
+   .getMaxValue(ASTC.UnsignedCharTy)
+   .getLimitedValue(),
+   ASTC.IntTy),
+SVB.getConditionType())
+  .getAs();
+  if (!CondLow || !CondHigh)
+return;
+  StateNotFailed = StateNotFailed->assume(*CondLow, true);
+  if (!StateNotFailed)
+return;
+  StateNotFailed = StateNotFailed->assume(*CondHigh, true);
+  if (!StateNotFailed)
+return;
+  C.addTransition(StateNotFailed);
+} else {
+  // Generate a transition for the success state of `fgets`.
+  std::optional GetBuf =
+  Call.getArgSVal(0).getAs();
+  if (!GetBuf)
+return;
+  ProgramStateRef StateNotFailed =
+  State->BindExpr(CE, C.getLocationContext(), *GetBuf);
+  StateNotFailed = StateNotFailed->set(
+  StreamSym, StreamState::getOpened(Desc));
+  C.addTransition(StateNotFailed);
+}
   }
 
   // Add transition for the failed state.
-  ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE);
+  ProgramStateRef StateFailed;
+  if (SingleChar)
+StateFailed = bindInt(*EofVal, State, C, CE);
+  else
+StateFailed =
+State->BindExpr(CE, C.getLocationContext(),
+C.getSValBuilder().makeNullWithType(CE->getType()));
 
   // If a (non-EOF) error occurs, the resulting value of the file position
   // indicator for the stream is indeterminate.

diff  --git a/clang/test/Analysis/Inputs/system-header-simulator.h 
b/clang/test/Analysis/Inputs/system-header-simulator.h
index 7ef5f29fbf42cb1..7089bd8bfc9d983 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -49,6 +49,7 @@ int fclose(FILE *fp);
 size_t fread(void *restrict, size_t, size_t, FILE *restrict);
 size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict)

[clang] [clang][analyzer] Support `fgets` in the SteamChecker (PR #73638)

2023-11-29 Thread Ben Shi via cfe-commits

https://github.com/benshi001 closed 
https://github.com/llvm/llvm-project/pull/73638
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

2023-11-29 Thread Mariya Podchishchaeva via cfe-commits


@@ -2932,6 +2932,22 @@ def warn_private_extern : Warning<
 def note_private_extern : Note<
   "use __attribute__((visibility(\"hidden\"))) attribute instead">;
 
+// C23 constexpr
+def err_c23_thread_local_constexpr : Error<
+  "thread-local storage is not allowed with constexpr">;
+def err_c23_extern_constexpr : Error<
+  "extern specifier is not allowed with constexpr">;

Fznamznon wrote:

I'm not quite sure reusing `err_invalid_decl_spec_combination` will look clear 
enough, here is what I got while trying:
```
t3.c:2:1: error: cannot combine with previous 'extern' declaration specifier
2 | constexpr extern int V79 = 10;
  | ^ ~~

```
If that is still better, I can update it.

https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

2023-11-29 Thread Mariya Podchishchaeva via cfe-commits


@@ -4110,6 +4116,10 @@ static CompleteObject findCompleteObject(EvalInfo &Info, 
const Expr *E,
 }
 
 bool IsConstant = BaseType.isConstant(Info.Ctx);
+bool ConstexprVar = false;
+if (const auto *VD = dyn_cast_if_present(
+Info.EvaluatingDecl.dyn_cast()))
+  ConstexprVar = VD->isConstexpr();

Fznamznon wrote:

This is to check that an initializer for a `constexpr` variable in c23 can only 
reference other `constexpr` variables. Done since C++ allows things like
```
const int a = 0;
constexpr int b = a;
```

https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Move documentation about -verify from a header to public docs (PR #73694)

2023-11-29 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll approved this pull request.


https://github.com/llvm/llvm-project/pull/73694
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Move documentation about -verify from a header to public docs (PR #73694)

2023-11-29 Thread Vlad Serebrennikov via cfe-commits

Endilll wrote:

> Would it make sense to document this more publicly? While it's designed to be 
> an internal tool, it's really useful for people who want to make sure their 
> library produces high quality diagnostics (e.g. nodiscard, static_asserts 
> etc.). I'm sure you are aware that libc++ uses -verify too.

While I'm sympathetic to the intent, making this more public bring up the 
question what are we going to promise the users. I believe status quo is that 
we can do whatever we feel like to, coordinating it with libc++ people, which 
sit at a proverbial next desk to us. So I'm not opposed to this, but I'd like 
to see how we going to address this concern.

https://github.com/llvm/llvm-project/pull/73694
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

2023-11-29 Thread Mariya Podchishchaeva via cfe-commits


@@ -14240,6 +14294,114 @@ StmtResult Sema::ActOnCXXForRangeIdentifier(Scope *S, 
SourceLocation IdentLoc,
   : IdentLoc);
 }
 
+static ImplicitConversionKind getConversionKind(QualType FromType,
+QualType ToType) {
+  if (ToType->isIntegerType()) {
+if (FromType->isComplexType())
+  return ICK_Complex_Real;
+if (FromType->isFloatingType())
+  return ICK_Floating_Integral;
+if (FromType->isIntegerType())
+  return ICK_Integral_Conversion;
+  }
+
+  if (ToType->isFloatingType()) {
+if (FromType->isComplexType())
+  return ICK_Complex_Real;
+if (FromType->isFloatingType())
+  return ICK_Floating_Conversion;
+if (FromType->isIntegerType())
+  return ICK_Floating_Integral;
+  }
+
+  return ICK_Identity;
+}

Fznamznon wrote:

> I wonder if we should expose (some of) the logic of IsStandardConversion() 
> from SemaOverload.cpp

You mean part starting from
https://github.com/llvm/llvm-project/blob/af65379e383bac651f0868237e9086630b15ee0d/clang/lib/Sema/SemaOverload.cpp#L2074
 ?

If yes, how this will help better with the problem of adding new conversions?

https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [AMDGPU] Add code model (#70760) test for amdgpu target. (PR #71019)

2023-11-29 Thread Matt Arsenault via cfe-commits


@@ -5767,12 +5768,23 @@ void Clang::ConstructJob(Compilation &C, const 
JobAction &JA,
 } else if (Triple.getArch() == llvm::Triple::x86_64) {
   Ok = llvm::is_contained({"small", "kernel", "medium", "large", "tiny"},
   CM);
-} else if (Triple.isNVPTX() || Triple.isAMDGPU()) {
-  // NVPTX/AMDGPU does not care about the code model and will accept
+} else if (Triple.isNVPTX()) {
+  // NVPTX does not care about the code model and will accept
   // whatever works for the host.
   Ok = true;
+} else if (Triple.isAMDGPU()) {
+  // AMDGPU does not care about the code model.
+  Ok = true;
+  // AMDGPU target ignores CM tiny and kernel.
+  if (CM == "tiny" || CM == "kernel") {
+Skip = true;
+D.Diag(diag::warn_ignored_clang_option)
+<< A->getSpelling() << CM << TripleStr;
+  }

arsenm wrote:

This is doing more than adding the test?

https://github.com/llvm/llvm-project/pull/71019
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Move documentation about -verify from a header to public docs (PR #73694)

2023-11-29 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> Would it make sense to document this more publicly? While it's designed to be 
> an internal tool, it's really useful for people who want to make sure their 
> library produces high quality diagnostics (e.g. `nodiscard`, `static_assert`s 
> etc.). I'm sure you are aware that libc++ uses `-verify` too.

Because `-verify` is a `-cc1` option and not a driver-level option, it's not 
really user-facing despite being usable (and used!) outside of Clang. So I 
think the internals manual is the most appropriate place for the details; it's 
kind of akin to an internal-use pragma or intrinsic.

https://github.com/llvm/llvm-project/pull/73694
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 15798f4 - Move documentation about -verify from a header to public docs (#73694)

2023-11-29 Thread via cfe-commits

Author: Aaron Ballman
Date: 2023-11-29T07:56:08-05:00
New Revision: 15798f4ec4dfa9607f4a7c94b922b80049e1575d

URL: 
https://github.com/llvm/llvm-project/commit/15798f4ec4dfa9607f4a7c94b922b80049e1575d
DIFF: 
https://github.com/llvm/llvm-project/commit/15798f4ec4dfa9607f4a7c94b922b80049e1575d.diff

LOG: Move documentation about -verify from a header to public docs (#73694)

The internals manual seems like a more obvious home for the details
instead of hiding them away in a header file and relying on doxygen
output to document it publicly.

Added: 


Modified: 
clang/docs/InternalsManual.rst
clang/include/clang/Frontend/VerifyDiagnosticConsumer.h

Removed: 




diff  --git a/clang/docs/InternalsManual.rst b/clang/docs/InternalsManual.rst
index b7d88d3d67d0a0c..f8e3da5f9736829 100644
--- a/clang/docs/InternalsManual.rst
+++ b/clang/docs/InternalsManual.rst
@@ -3309,6 +3309,173 @@ are similar.
  as syntax highlighting, cross-referencing, and so on.  The
  ``c-index-test`` helper program can be used to test these features.
 
+Testing
+---
+All functional changes to Clang should come with test coverage demonstrating
+the change in behavior.
+
+Verifying Diagnostics
+^
+Clang ``-cc1`` supports the ``-verify`` command line option as a way to
+validate diagnostic behavior. This option will use special comments within the
+test file to verify that expected diagnostics appear in the correct source
+locations. If all of the expected diagnostics match the actual output of Clang,
+then the invocation will return normally. If there are discrepancies between
+the expected and actual output, Clang will emit detailed information about
+which expected diagnostics were not seen or which unexpected diagnostics were
+seen, etc. A complete example is:
+
+.. code-block: c++
+
+  // RUN: %clang_cc1 -verify %s
+  int A = B; // expected-error {{use of undeclared identifier 'B'}}
+
+If the test is run and the expected error is emitted on the expected line, the
+diagnostic verifier will pass. However, if the expected error does not appear
+or appears in a 
diff erent location than expected, or if additional diagnostics
+appear, the diagnostic verifier will fail and emit information as to why.
+
+The ``-verify`` command optionally accepts a comma-delimited list of one or
+more verification prefixes that can be used to craft those special comments.
+Each prefix must start with a letter and contain only alphanumeric characters,
+hyphens, and underscores. ``-verify`` by itself is equivalent to
+``-verify=expected``, meaning that special comments will start with
+``expected``. Using 
diff erent prefixes makes it easier to have separate
+``RUN:`` lines in the same test file which result in 
diff ering diagnostic
+behavior. For example:
+
+.. code-block:: c++
+
+  // RUN: %clang_cc1 -verify=foo,bar %s
+
+  int A = B; // foo-error {{use of undeclared identifier 'B'}}
+  int C = D; // bar-error {{use of undeclared identifier 'D'}}
+  int E = F; // expected-error {{use of undeclared identifier 'F'}}
+
+The verifier will recognize ``foo-error`` and ``bar-error`` as special comments
+but will not recognize ``expected-error`` as one because the ``-verify`` line
+does not contain that as a prefix. Thus, this test would fail verification
+because an unexpected diagnostic would appear on the declaration of ``E``.
+
+Multiple occurrences accumulate prefixes.  For example,
+``-verify -verify=foo,bar -verify=baz`` is equivalent to
+``-verify=expected,foo,bar,baz``.
+
+Specifying Diagnostics
+^^
+Indicating that a line expects an error or a warning is simple. Put a comment
+on the line that has the diagnostic, use
+``expected-{error,warning,remark,note}`` to tag if it's an expected error,
+warning, remark, or note (respectively), and place the expected text between
+``{{`` and ``}}`` markers. The full text doesn't have to be included, only
+enough to ensure that the correct diagnostic was emitted. (Note: full text
+should be included in test cases unless there is a compelling reason to use
+truncated text instead.)
+
+Here's an example of the most commonly used way to specify expected
+diagnostics:
+
+.. code-block: c++
+
+  int A = B; // expected-error {{use of undeclared identifier 'B'}}
+
+You can place as many diagnostics on one line as you wish. To make the code
+more readable, you can use slash-newline to separate out the diagnostics.
+
+Alternatively, it is possible to specify the line on which the diagnostic
+should appear by appending ``@`` to ``expected-``, for example:
+
+.. code-block: c++
+
+  #warning some text
+  // expected-warning@10 {{some text}}
+
+The line number may be absolute (as above), or relative to the current line by
+prefixing the number with either ``+`` or ``-``.
+
+If the diagnostic is generated in a separate file, for example in a shared
+header file, it may be beneficial to 

[clang] Move documentation about -verify from a header to public docs (PR #73694)

2023-11-29 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman closed 
https://github.com/llvm/llvm-project/pull/73694
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [RISCV][MC] Always emit relocations for resolved symbols and relax (PR #73793)

2023-11-29 Thread Andreu Carminati via cfe-commits

https://github.com/andcarminati created 
https://github.com/llvm/llvm-project/pull/73793

If relaxation is not itended, it can be disabled in the linker. Also, we cannot 
trust Subtarget features here, because it may be empty in case of LTO codegen, 
preventing relaxations.

Also forward --no-relax option to linker.

>From a7ba3e4e7a84c49e80fe3e05c1a8ca83e7fd8c6e Mon Sep 17 00:00:00 2001
From: Andreu Carminati 
Date: Tue, 28 Nov 2023 15:26:49 +0100
Subject: [PATCH] [RISCV][MC] Always emit relocations for resolved symbols and
 relax

If relaxation is not itended, it can be disabled in the linker. Also,
we cannot trust Subtarget features here, because it may be empty in case
of LTO codegen, preventing relaxations.

Also forward --no-relax option to linker.
---
 clang/lib/Driver/ToolChains/BareMetal.cpp |  3 ++
 .../lib/Driver/ToolChains/RISCVToolchain.cpp  |  3 ++
 clang/test/Driver/baremetal.cpp   | 10 ++
 .../RISCV/MCTargetDesc/RISCVAsmBackend.cpp| 12 +++
 llvm/test/CodeGen/RISCV/compress.ll   | 31 +--
 5 files changed, 41 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp 
b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 42c8336e626c7b5..fc955d79780e5a0 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -443,6 +443,9 @@ void baremetal::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   CmdArgs.push_back("-Bstatic");
 
+  if (Args.hasArg(options::OPT_mno_relax))
+CmdArgs.push_back("--no-relax");
+
   if (Triple.isARM() || Triple.isThumb()) {
 bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
 if (IsBigEndian)
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp 
b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
index 7e6abd144428783..0be7d1a88994957 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -156,6 +156,9 @@ void RISCV::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
   if (!D.SysRoot.empty())
 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
 
+  if (Args.hasArg(options::OPT_mno_relax))
+CmdArgs.push_back("--no-relax");
+
   bool IsRV64 = ToolChain.getArch() == llvm::Triple::riscv64;
   CmdArgs.push_back("-m");
   if (IsRV64) {
diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp
index c04f4506a0994db..134bf427e3dc160 100644
--- a/clang/test/Driver/baremetal.cpp
+++ b/clang/test/Driver/baremetal.cpp
@@ -460,3 +460,13 @@
 // RUN:   | FileCheck --check-prefix=CHECK-CLANGRT-ARCH %s
 // CHECK-CLANGRT-ARCH: "-lclang_rt.builtins-armv6m"
 // CHECK-CLANGRT-ARCH-NOT: "-lclang_rt.builtins"
+
+// RUN: %clang %s -### 2>&1 --target=riscv64-unknown-elf -nostdinc -mno-relax \
+// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \
+// RUN:   | FileCheck --check-prefix=CHECK-RV64-NORELAX %s
+// CHECK-RV64-NORELAX: "--no-relax"
+
+// RUN: %clang %s -### 2>&1 --target=riscv64-unknown-elf -nostdinc \
+// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \
+// RUN:   | FileCheck --check-prefix=CHECK-RV64-RELAX %s
+// CHECK-RV64-RELAX-NOT: "--no-relax"
\ No newline at end of file
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index dfc3c9e9908d888..d4efaaf2666e426 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -103,9 +103,9 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
   return Infos[Kind - FirstTargetFixupKind];
 }
 
-// If linker relaxation is enabled, or the relax option had previously been
-// enabled, always emit relocations even if the fixup can be resolved. This is
-// necessary for correctness as offsets may change during relaxation.
+// Always emit relocations for relative addresses, even if the fixup can be
+// resolved. This is necessary for correctness as offsets may change during
+// relaxation.
 bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
 const MCFixup &Fixup,
 const MCValue &Target) {
@@ -122,13 +122,9 @@ bool RISCVAsmBackend::shouldForceRelocation(const 
MCAssembler &Asm,
 if (Target.isAbsolute())
   return false;
 break;
-  case RISCV::fixup_riscv_got_hi20:
-  case RISCV::fixup_riscv_tls_got_hi20:
-  case RISCV::fixup_riscv_tls_gd_hi20:
-return true;
   }
 
-  return STI.hasFeature(RISCV::FeatureRelax) || ForceRelocs;
+  return true;
 }
 
 bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
diff --git a/llvm/test/CodeGen/RISCV/compress.ll 
b/llvm/test/CodeGen/RISCV/compress.ll
index 479b7e524cd347c..fd7c4e9cc9934e9 100644
--- a/llvm/test/CodeGen/RISCV/compress.ll
+++ b/llvm/test/CodeGen/RISCV/compress.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions 

[llvm] [clang] [RISCV][MC] Always emit relocations for resolved symbols and relax (PR #73793)

2023-11-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-risc-v

Author: Andreu Carminati (andcarminati)


Changes

If relaxation is not itended, it can be disabled in the linker. Also, we cannot 
trust Subtarget features here, because it may be empty in case of LTO codegen, 
preventing relaxations.

Also forward --no-relax option to linker.

---
Full diff: https://github.com/llvm/llvm-project/pull/73793.diff


5 Files Affected:

- (modified) clang/lib/Driver/ToolChains/BareMetal.cpp (+3) 
- (modified) clang/lib/Driver/ToolChains/RISCVToolchain.cpp (+3) 
- (modified) clang/test/Driver/baremetal.cpp (+10) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp (+4-8) 
- (modified) llvm/test/CodeGen/RISCV/compress.ll (+21-10) 


``diff
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp 
b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 42c8336e626c7b5..fc955d79780e5a0 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -443,6 +443,9 @@ void baremetal::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   CmdArgs.push_back("-Bstatic");
 
+  if (Args.hasArg(options::OPT_mno_relax))
+CmdArgs.push_back("--no-relax");
+
   if (Triple.isARM() || Triple.isThumb()) {
 bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
 if (IsBigEndian)
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp 
b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
index 7e6abd144428783..0be7d1a88994957 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -156,6 +156,9 @@ void RISCV::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
   if (!D.SysRoot.empty())
 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
 
+  if (Args.hasArg(options::OPT_mno_relax))
+CmdArgs.push_back("--no-relax");
+
   bool IsRV64 = ToolChain.getArch() == llvm::Triple::riscv64;
   CmdArgs.push_back("-m");
   if (IsRV64) {
diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp
index c04f4506a0994db..134bf427e3dc160 100644
--- a/clang/test/Driver/baremetal.cpp
+++ b/clang/test/Driver/baremetal.cpp
@@ -460,3 +460,13 @@
 // RUN:   | FileCheck --check-prefix=CHECK-CLANGRT-ARCH %s
 // CHECK-CLANGRT-ARCH: "-lclang_rt.builtins-armv6m"
 // CHECK-CLANGRT-ARCH-NOT: "-lclang_rt.builtins"
+
+// RUN: %clang %s -### 2>&1 --target=riscv64-unknown-elf -nostdinc -mno-relax \
+// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \
+// RUN:   | FileCheck --check-prefix=CHECK-RV64-NORELAX %s
+// CHECK-RV64-NORELAX: "--no-relax"
+
+// RUN: %clang %s -### 2>&1 --target=riscv64-unknown-elf -nostdinc \
+// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \
+// RUN:   | FileCheck --check-prefix=CHECK-RV64-RELAX %s
+// CHECK-RV64-RELAX-NOT: "--no-relax"
\ No newline at end of file
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index dfc3c9e9908d888..d4efaaf2666e426 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -103,9 +103,9 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
   return Infos[Kind - FirstTargetFixupKind];
 }
 
-// If linker relaxation is enabled, or the relax option had previously been
-// enabled, always emit relocations even if the fixup can be resolved. This is
-// necessary for correctness as offsets may change during relaxation.
+// Always emit relocations for relative addresses, even if the fixup can be
+// resolved. This is necessary for correctness as offsets may change during
+// relaxation.
 bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
 const MCFixup &Fixup,
 const MCValue &Target) {
@@ -122,13 +122,9 @@ bool RISCVAsmBackend::shouldForceRelocation(const 
MCAssembler &Asm,
 if (Target.isAbsolute())
   return false;
 break;
-  case RISCV::fixup_riscv_got_hi20:
-  case RISCV::fixup_riscv_tls_got_hi20:
-  case RISCV::fixup_riscv_tls_gd_hi20:
-return true;
   }
 
-  return STI.hasFeature(RISCV::FeatureRelax) || ForceRelocs;
+  return true;
 }
 
 bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
diff --git a/llvm/test/CodeGen/RISCV/compress.ll 
b/llvm/test/CodeGen/RISCV/compress.ll
index 479b7e524cd347c..fd7c4e9cc9934e9 100644
--- a/llvm/test/CodeGen/RISCV/compress.ll
+++ b/llvm/test/CodeGen/RISCV/compress.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 3
 ; This test is designed to run twice, once with function attributes and once
 ; with target attributes added on the command line.
 ;
@@ -50,35 +51,45 @@ define i32 @simple_arith(i32 %a, i32 %b) #0 {
 define i32 @select(i32 %a, ptr %b) #0 {
 ; RV32IC-LABEL: :
 ; RV32IC: c.lw a

[llvm] [clang] [RISCV][MC] Always emit relocations for resolved symbols and relax (PR #73793)

2023-11-29 Thread Andreu Carminati via cfe-commits

andcarminati wrote:

Hi @topperc , just another idea to solve the problem, mostly to discuss!

Regards.

https://github.com/llvm/llvm-project/pull/73793
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [RISCV] Always emit relocations for resolved symbols and relax (PR #73793)

2023-11-29 Thread Andreu Carminati via cfe-commits

https://github.com/andcarminati edited 
https://github.com/llvm/llvm-project/pull/73793
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

2023-11-29 Thread Mariya Podchishchaeva via cfe-commits


@@ -14240,6 +14294,114 @@ StmtResult Sema::ActOnCXXForRangeIdentifier(Scope *S, 
SourceLocation IdentLoc,
   : IdentLoc);
 }
 
+static ImplicitConversionKind getConversionKind(QualType FromType,
+QualType ToType) {
+  if (ToType->isIntegerType()) {
+if (FromType->isComplexType())
+  return ICK_Complex_Real;
+if (FromType->isFloatingType())
+  return ICK_Floating_Integral;
+if (FromType->isIntegerType())
+  return ICK_Integral_Conversion;
+  }
+
+  if (ToType->isFloatingType()) {
+if (FromType->isComplexType())
+  return ICK_Complex_Real;
+if (FromType->isFloatingType())
+  return ICK_Floating_Conversion;
+if (FromType->isIntegerType())
+  return ICK_Floating_Integral;
+  }
+
+  return ICK_Identity;
+}
+
+static bool checkC23ConstexprInitConversion(Sema &S, const Expr *Init) {
+  assert(S.getLangOpts().C23);
+  const Expr *InitNoCast = Init->IgnoreImpCasts();
+  StandardConversionSequence SCS;
+  SCS.setAsIdentityConversion();
+  auto FromType = InitNoCast->getType();
+  auto ToType = Init->getType();
+  SCS.setToType(0, FromType);
+  SCS.setToType(1, ToType);
+  SCS.Second = getConversionKind(FromType, ToType);
+
+  APValue Value;
+  QualType PreNarrowingType;
+  // Reuse C++ narrowing check.
+  switch (SCS.getNarrowingKind(S.Context, Init, Value, PreNarrowingType,
+   /*IgnoreFloatToIntegralConversion*/ false)) {
+  // The value doesn't fit.
+  case NK_Constant_Narrowing:
+S.Diag(Init->getBeginLoc(), diag::err_c23_constexpr_init_not_representable)
+<< Value.getAsString(S.Context, PreNarrowingType) << ToType;
+return true;
+
+  // Conversion to a narrower type.
+  case NK_Type_Narrowing:
+S.Diag(Init->getBeginLoc(), diag::err_c23_constexpr_init_type_mismatch)
+<< ToType << FromType;
+return true;
+
+  // Since we only reuse narrowing check for C23 constexpr variables here, 
we're
+  // not really interested in these cases.
+  case NK_Dependent_Narrowing:
+  case NK_Variable_Narrowing:
+  case NK_Not_Narrowing:
+return false;
+  }
+  llvm_unreachable("unhandled case in switch");
+}
+
+static bool checkC23ConstexprInitStringLiteral(const StringLiteral *SE,
+   Sema &SemaRef,
+   SourceLocation Loc) {
+  assert(SemaRef.getLangOpts().C23);
+  // String literals have the target type attached but underneath may contain
+  // values that don't really fit into the target type. Check that every
+  // character fits.
+  const ConstantArrayType *CAT =
+  SemaRef.Context.getAsConstantArrayType(SE->getType());
+  QualType CharType = CAT->getElementType();
+  uint32_t BitWidth = SemaRef.Context.getTypeSize(CharType);
+  bool isUnsigned = CharType->isUnsignedIntegerType();
+  llvm::APSInt Value(BitWidth, isUnsigned);
+  const StringRef S = SE->getBytes();
+  for (unsigned I = 0, N = SE->getLength(); I != N; ++I) {
+Value = S[I];
+if (Value != S[I]) {
+  SemaRef.Diag(Loc, diag::err_c23_constexpr_init_not_representable)
+  << S[I] << CharType;

Fznamznon wrote:

I'm not sure? What I'm trying to do is catch an overflowing conversion which 
already happens in `getCodeUnit()`. Perhaps if I have to use `getCodeUnit()` 
there should be another check then?

https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Eagerly instantiate used constexpr function upon definition. (PR #73463)

2023-11-29 Thread via cfe-commits

https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/73463

>From 001cc1c3a03b80cd6725783edaad84c9013311b6 Mon Sep 17 00:00:00 2001
From: Corentin Jabot 
Date: Sun, 26 Nov 2023 22:47:51 +0100
Subject: [PATCH 1/3] [Clang] Eagerly instantiate used constexpr function upon
 definition.

Despite CWG2497 not being resolved, it is reasonable to expect the following
code to compile (and which is supported by other compilers)

```cpp
  template constexpr T f();
  constexpr int g() { return f(); } // #1
  template constexpr T f() { return 123; }
  int k[g()];
  // #2
```

To that end, we eagerly instantiate all referenced
specializations of constexpr functions when they are defined.

We maintain a map of (pattern, [instantiations]) independant of
`PendingInstantiations` to avoid having to iterate that list after
each function definition.

We should apply the same logic to constexpr variables,
but I wanted to keep the PR small.

Fixes #73232
---
 clang/docs/ReleaseNotes.rst   |  5 
 clang/include/clang/Sema/Sema.h   | 11 +++
 clang/lib/Sema/SemaDecl.cpp   |  3 ++
 clang/lib/Sema/SemaExpr.cpp   |  9 --
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  | 17 +++
 .../SemaCXX/cxx2b-consteval-propagate.cpp |  8 +++--
 .../instantiate-used-constexpr-function.cpp   | 30 +++
 7 files changed, 78 insertions(+), 5 deletions(-)
 create mode 100644 
clang/test/SemaTemplate/instantiate-used-constexpr-function.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e4b0a2cb5e0..ce8b635d2d79bc5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -788,6 +788,11 @@ Bug Fixes to C++ Support
   completes (except deduction guides). Fixes:
   (`#59827 `_)
 
+- Clang now immediately instantiates function template specializations
+  at the end of the definition of the corresponding function template
+  when the definition appears after the first point of instantiation.
+  (`#73232 `_)
+
 Bug Fixes to AST Handling
 ^
 - Fixed an import failure of recursive friend class template.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 5d786fd5fb9a2c4..f56d7c947eacdfc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -59,6 +59,7 @@
 #include "clang/Sema/TypoCorrection.h"
 #include "clang/Sema/Weak.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -10084,6 +10085,12 @@ class Sema final {
   /// but have not yet been performed.
   std::deque PendingInstantiations;
 
+  /// Track constexpr functions referenced before they are (lexically) defined.
+  /// The key is the pattern, associated with a list of specialisations that
+  /// need to be instantiated when the pattern is defined.
+  llvm::DenseMap>
+  PendingInstantiationsOfConstexprEntities;
+
   /// Queue of implicit template instantiations that cannot be performed
   /// eagerly.
   SmallVector LateParsedInstantiations;
@@ -10402,6 +10409,10 @@ class Sema final {
  bool Recursive = false,
  bool DefinitionRequired = false,
  bool AtEndOfTU = false);
+
+  void InstantiateFunctionTemplateSpecializations(
+  SourceLocation PointOfInstantiation, FunctionDecl *Template);
+
   VarTemplateSpecializationDecl *BuildVarTemplateInstantiation(
   VarTemplateDecl *VarTemplate, VarDecl *FromVar,
   const TemplateArgumentList &TemplateArgList,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 23dd8ae15c16583..1030ba0d21b1906 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16255,6 +16255,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt 
*Body,
   if (FD && !FD->isDeleted())
 checkTypeSupport(FD->getType(), FD->getLocation(), FD);
 
+  if (FD && FD->isConstexpr() && FD->isTemplated())
+InstantiateFunctionTemplateSpecializations(FD->getEndLoc(), FD);
+
   return dcl;
 }
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index fc39d6149c1cc65..37b0d0eed35845c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19047,12 +19047,17 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, 
FunctionDecl *Func,
   CodeSynthesisContexts.size())
 PendingLocalImplicitInstantiations.push_back(
 std::make_pair(Func, PointOfInstantiation));
-  else if (Func->isConstexpr())
+  else if (Func->isConstexpr()) {
 // Do not defer instantiations of constexpr functions, to avoid the
 // expression evaluator needing to ca

[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

2023-11-29 Thread Mariya Podchishchaeva via cfe-commits


@@ -14397,17 +14559,21 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl 
*var) {
   QualType baseType = Context.getBaseElementType(type);
   bool HasConstInit = true;
 
+  if (getLangOpts().C23 && var->isConstexpr() && !Init)
+Diag(var->getLocation(), diag::err_constexpr_var_requires_const_init)
+<< var;

Fznamznon wrote:

Yes, existing logic uses `InitializationSequence` code paths that are deeply 
tied to C++ initialization rules, modifying these for C didn't seem reasonable.

https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

2023-11-29 Thread Mariya Podchishchaeva via cfe-commits

https://github.com/Fznamznon edited 
https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME2] Enable CLAMP multi-vector builtins for SME2 (PR #72272)

2023-11-29 Thread Dinar Temirbulatov via cfe-commits

https://github.com/dtemirbulatov updated 
https://github.com/llvm/llvm-project/pull/72272

>From 11d7759523aa7d8c7f581da176f2e4e5a03f76ca Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov 
Date: Tue, 14 Nov 2023 15:25:45 +
Subject: [PATCH] [AArch64][SME2] Enable CLAMP multi-vector builtins for SME2

Thing change add builtins for SME2:
sclamp.single.x2
uclamp.single.x2
fclamp.single.x2
sclamp.single.x4
uclamp.single.x4
fclamp.single.x4

Patch by: Hassnaa Hamdi 
---
 clang/include/clang/Basic/arm_sve.td  |  10 +
 .../aarch64-sme2-intrinsics/acle_sme2_clamp.c | 747 ++
 2 files changed, 757 insertions(+)
 create mode 100644 clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_clamp.c

diff --git a/clang/include/clang/Basic/arm_sve.td 
b/clang/include/clang/Basic/arm_sve.td
index cd4c09a3ad7a81c..4fcc9327f22fe61 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -2101,6 +2101,16 @@ let TargetGuard = "sme2" in {
   defm SVMAXNM : SInstMinMaxByVector<"max">;
 }
 
+let TargetGuard = "sme2" in {
+  def SVSCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]",  "22dd",   "csil", 
MergeNone, "aarch64_sve_sclamp_single_x2",  [IsStreaming], []>;
+  def SVUCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]",  "22dd",   "UcUsUiUl", 
MergeNone, "aarch64_sve_uclamp_single_x2",  [IsStreaming], []>;
+  def SVFCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]",  "22dd",   "hfd",  
MergeNone, "aarch64_sve_fclamp_single_x2",  [IsStreaming], []>;
+
+  def SVSCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]",  "44dd",   "csil", 
MergeNone, "aarch64_sve_sclamp_single_x4",  [IsStreaming], []>;
+  def SVUCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]",  "44dd",   "UcUsUiUl", 
MergeNone, "aarch64_sve_uclamp_single_x4",  [IsStreaming], []>;
+  def SVFCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]",  "44dd",   "hfd",  
MergeNone, "aarch64_sve_fclamp_single_x4",  [IsStreaming], []>;
+}
+
 let TargetGuard = "sme2" in {
 // == ADD (vectors) ==
   def SVADD_SINGLE_X2 : SInst<"svadd[_single_{d}_x2]", "22d", "cUcsUsiUilUl", 
MergeNone, "aarch64_sve_add_single_x2", [IsStreaming], []>;
diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_clamp.c 
b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_clamp.c
new file mode 100644
index 000..4dce1699c264fbf
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_clamp.c
@@ -0,0 +1,747 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve \
+// RUN:   -S -Werror -emit-llvm -disable-O0-optnone -o - %s | opt -S -p 
mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu 
-target-feature +sme2 -target-feature +sve \
+// RUN:   -S -Werror -emit-llvm -disable-O0-optnone -o - %s | opt -S -p 
mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve \
+// RUN:   -S -Werror -emit-llvm -disable-O0-optnone -o - -x c++ %s | opt -S -p 
mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu 
-target-feature +sme2 -target-feature +sve \
+// RUN:   -S -Werror -emit-llvm -disable-O0-optnone -o - -x c++ %s | opt -S -p 
mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve \
+// RUN:   -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+#include 
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4
+#endif
+
+// SCLAMP_X2
+
+// CHECK-LABEL: @test_svclamp_single_s8_x2(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.vector.extract.nxv16i8.nxv32i8( [[OP1:%.*]], i64 0)
+// CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.vector.extract.nxv16i8.nxv32i8( [[OP1]], i64 16)
+// CHECK-NEXT:[[TMP2:%.*]] = tail call { ,  } @llvm.aarch64.sve.sclamp.single.x2.nxv16i8( [[TMP0]], 
 [[TMP1]],  [[OP2:%.*]],  
[[OP3:%.*]])
+// CHECK-NEXT:[[TMP3:%.*]] = extractvalue { ,  } [[TMP2]], 0
+// CHECK-NEXT:[[TMP4:%.*]] = tail call  
@llvm.vector.insert.nxv32i8.nxv16i8( poison,  [[TMP3]], i64 0)
+// CHECK-NEXT:[[TMP5:%.*]] = extractvalue { ,  } [[TMP2]], 1
+// CHECK-NEXT:[[TMP6:%.*]] = tail call  
@llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]],  [[TMP5]], i64 16)
+// CHECK-NEXT:ret  [[TMP6]]
+//
+// CPP-CHECK-LABEL: @_Z25test_svclamp_single_s8_x210svint8x2_tu10__SVInt8_tS0_(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.vector.extract.nxv16i8.nxv32i8( [[OP1:%.*

[clang] 3c00c8c - [AArch64][SME2] Enable CLAMP multi-vector builtins for SME2 (#72272)

2023-11-29 Thread via cfe-commits

Author: Dinar Temirbulatov
Date: 2023-11-29T14:32:40Z
New Revision: 3c00c8c0fcd64600f7adc4538b2116a91ef60ced

URL: 
https://github.com/llvm/llvm-project/commit/3c00c8c0fcd64600f7adc4538b2116a91ef60ced
DIFF: 
https://github.com/llvm/llvm-project/commit/3c00c8c0fcd64600f7adc4538b2116a91ef60ced.diff

LOG: [AArch64][SME2] Enable CLAMP multi-vector builtins for SME2 (#72272)

Thing change add builtins for SME2:
sclamp.single.x2
uclamp.single.x2
fclamp.single.x2
sclamp.single.x4
uclamp.single.x4
fclamp.single.x4

Patch by: Hassnaa Hamdi 

Added: 
clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_clamp.c

Modified: 
clang/include/clang/Basic/arm_sve.td

Removed: 




diff  --git a/clang/include/clang/Basic/arm_sve.td 
b/clang/include/clang/Basic/arm_sve.td
index cd4c09a3ad7a81c..4fcc9327f22fe61 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -2101,6 +2101,16 @@ let TargetGuard = "sme2" in {
   defm SVMAXNM : SInstMinMaxByVector<"max">;
 }
 
+let TargetGuard = "sme2" in {
+  def SVSCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]",  "22dd",   "csil", 
MergeNone, "aarch64_sve_sclamp_single_x2",  [IsStreaming], []>;
+  def SVUCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]",  "22dd",   "UcUsUiUl", 
MergeNone, "aarch64_sve_uclamp_single_x2",  [IsStreaming], []>;
+  def SVFCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]",  "22dd",   "hfd",  
MergeNone, "aarch64_sve_fclamp_single_x2",  [IsStreaming], []>;
+
+  def SVSCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]",  "44dd",   "csil", 
MergeNone, "aarch64_sve_sclamp_single_x4",  [IsStreaming], []>;
+  def SVUCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]",  "44dd",   "UcUsUiUl", 
MergeNone, "aarch64_sve_uclamp_single_x4",  [IsStreaming], []>;
+  def SVFCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]",  "44dd",   "hfd",  
MergeNone, "aarch64_sve_fclamp_single_x4",  [IsStreaming], []>;
+}
+
 let TargetGuard = "sme2" in {
 // == ADD (vectors) ==
   def SVADD_SINGLE_X2 : SInst<"svadd[_single_{d}_x2]", "22d", "cUcsUsiUilUl", 
MergeNone, "aarch64_sve_add_single_x2", [IsStreaming], []>;

diff  --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_clamp.c 
b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_clamp.c
new file mode 100644
index 000..4dce1699c264fbf
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_clamp.c
@@ -0,0 +1,747 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve \
+// RUN:   -S -Werror -emit-llvm -disable-O0-optnone -o - %s | opt -S -p 
mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu 
-target-feature +sme2 -target-feature +sve \
+// RUN:   -S -Werror -emit-llvm -disable-O0-optnone -o - %s | opt -S -p 
mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve \
+// RUN:   -S -Werror -emit-llvm -disable-O0-optnone -o - -x c++ %s | opt -S -p 
mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu 
-target-feature +sme2 -target-feature +sve \
+// RUN:   -S -Werror -emit-llvm -disable-O0-optnone -o - -x c++ %s | opt -S -p 
mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve \
+// RUN:   -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+#include 
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4
+#endif
+
+// SCLAMP_X2
+
+// CHECK-LABEL: @test_svclamp_single_s8_x2(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.vector.extract.nxv16i8.nxv32i8( [[OP1:%.*]], i64 0)
+// CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.vector.extract.nxv16i8.nxv32i8( [[OP1]], i64 16)
+// CHECK-NEXT:[[TMP2:%.*]] = tail call { ,  } @llvm.aarch64.sve.sclamp.single.x2.nxv16i8( [[TMP0]], 
 [[TMP1]],  [[OP2:%.*]],  
[[OP3:%.*]])
+// CHECK-NEXT:[[TMP3:%.*]] = extractvalue { ,  } [[TMP2]], 0
+// CHECK-NEXT:[[TMP4:%.*]] = tail call  
@llvm.vector.insert.nxv32i8.nxv16i8( poison,  [[TMP3]], i64 0)
+// CHECK-NEXT:[[TMP5:%.*]] = extractvalue { ,  } [[TMP2]], 1
+// CHECK-NEXT:[[TMP6:%.*]] = tail call  
@llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]],  [[TMP5]], i64 16)
+// CHECK-NEXT:ret  [[TMP6]]
+//
+// CPP-CHECK-LABEL: @_Z25test_svclamp_single_s8_x210svint8x2_tu10__SVInt8_tS0_(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:[[TMP0:%.*]] = tail call 

[clang] [AArch64][SME2] Enable CLAMP multi-vector builtins for SME2 (PR #72272)

2023-11-29 Thread Dinar Temirbulatov via cfe-commits

https://github.com/dtemirbulatov closed 
https://github.com/llvm/llvm-project/pull/72272
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman commented:

Thank you for the documentation! In general, it's looking great. I did have 
some specific questions or ideas on the more user-facing documentation. I've 
not yet thoroughly reviewed the implementation plans docs.

One thing that's not clear from this is how bounds safety annotations interact 
with variable-length arrays or variably-modified types. e.g.,
```
void func(int n, int vla[n]) {
 // Within the function, is vla treated as-if it was __counted_by(n)?
}
```
or
```
void func(int n) {
  int vla[n];
  int *ptr = vla; // Does this calculate the correct upper bounds based on n?
}
```
We should probably have explicit mention given that VLAs are a source of 
security issues related to bounds. (In fact, we might even want to add specific 
bounds checks for VLAs such as "will the VLA fit comfortably within the stack 
frame?" or "these VLA bounds are user-controllable which is a Very Bad Idea™".)

https://github.com/llvm/llvm-project/pull/70749
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.

AaronBallman wrote:

Users probably aren't too worried about this point, it might make sense to just 
remove it.

https://github.com/llvm/llvm-project/pull/70749
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman edited 
https://github.com/llvm/llvm-project/pull/70749
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.

AaronBallman wrote:

This isn't true without further user intervention like putting the annotations 
behind macros; because we're using keywords, a toolchain which doesn't support 
the extension won't compile.

https://github.com/llvm/llvm-project/pull/70749
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.
+
+.. code-block:: c
+
+   void foo(int *__counted_by(count) p, size_t count) {
+  count++; // violates the invariant of __counted_by
+   }
+
+The requirement to annotate all pointers with explicit bounds information 
could present a significant adoption burden. To tackle this

[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.

AaronBallman wrote:

What about decreasing the value of `count`? Is it any mutation to the value or 
are we actually making sure the value is increased? e.g., `count += -1; // fine`

https://github.com/llvm/llvm-project/pull/70749
_

[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.
+
+.. code-block:: c
+
+   void foo(int *__counted_by(count) p, size_t count) {
+  count++; // violates the invariant of __counted_by
+   }
+
+The requirement to annotate all pointers with explicit bounds information 
could present a significant adoption burden. To tackle this

[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.
+
+.. code-block:: c
+
+   void foo(int *__counted_by(count) p, size_t count) {
+  count++; // violates the invariant of __counted_by
+   }
+
+The requirement to annotate all pointers with explicit bounds information 
could present a significant adoption burden. To tackle this

[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.
+
+.. code-block:: c
+
+   void foo(int *__counted_by(count) p, size_t count) {
+  count++; // violates the invariant of __counted_by
+   }
+
+The requirement to annotate all pointers with explicit bounds information 
could present a significant adoption burden. To tackle this

[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.

AaronBallman wrote:

Heh, this one might be a bit questionable given the ability to name parameters 
before they're declared. Maybe add some wiggle room with: `It is a conforming 
extension to C.` ?

https://github.com/llvm/llvm-project/pull/70749
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.

AaronBallman wrote:

Can you re-flow the document to the usual 80-col limits? (It's fine for lines 
with a link to be longer, but it's a bit easier on some folks' editors to have 
the shorter lines in general.)

https://github.com/llvm/llvm-project/pull/70749
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.
+
+.. code-block:: c
+
+   void foo(int *__counted_by(count) p, size_t count) {
+  count++; // violates the invariant of __counted_by
+   }
+
+The requirement to annotate all pointers with explicit bounds information 
could present a significant adoption burden. To tackle this

[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.
+
+.. code-block:: c
+
+   void foo(int *__counted_by(count) p, size_t count) {
+  count++; // violates the invariant of __counted_by
+   }
+
+The requirement to annotate all pointers with explicit bounds information 
could present a significant adoption burden. To tackle this

[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.
+
+.. code-block:: c
+
+   void foo(int *__counted_by(count) p, size_t count) {
+  count++; // violates the invariant of __counted_by
+   }
+
+The requirement to annotate all pointers with explicit bounds information 
could present a significant adoption burden. To tackle this

[clang] [BoundsSafety] Initial documentation for -fbounds-safety (PR #70749)

2023-11-29 Thread Aaron Ballman via cfe-commits


@@ -0,0 +1,362 @@
+==
+``-fbounds-safety``: Enforcing bounds safety for C
+==
+
+.. contents::
+   :local:
+
+Overview
+
+
+``-fbounds-safety`` is a C extension to enforce bounds safety to prevent 
out-of-bounds (OOB) memory accesses, which remain a major source of security 
vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs 
by turning OOB accesses into deterministic traps.
+
+The ``-fbounds-safety`` extension offers bounds annotations that programmers 
can use to attach bounds to pointers. For example, programmers can add the 
``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the 
pointer has ``N`` valid elements:
+
+.. code-block:: c
+
+   void foo(int *__counted_by(N) ptr, size_t N);
+
+Using this bounds information, the compiler inserts bounds checks on every 
pointer dereference, ensuring that the program does not access memory outside 
the specified bounds. The compiler requires programmers to provide enough 
bounds information so that the accesses can be checked at either run time or 
compile time — and it rejects code if it cannot.
+
+The most important contribution of ``-fbounds-safety`` is how it reduces the 
programmer’s annotation burden by reconciling bounds annotations at ABI 
boundaries with the use of implicit wide pointers (a.k.a. “fat” pointers) that 
carry bounds information on local variables without the need for annotations. 
We designed this model so that it preserves ABI compatibility with C while 
minimizing adoption effort.
+
+The ``-fbounds-safety`` extension has been adopted on millions of lines of 
production C code and proven to work in a consumer operating system setting. 
The extension was designed to enable incremental adoption — a key requirement 
in real-world settings where modifying an entire project and its dependencies 
all at once is often not possible. It also addresses multiple of other 
practical challenges that have made existing approaches to safer C dialects 
difficult to adopt, offering these properties that make it widely adoptable in 
practice:
+
+* It is designed to preserve the Application Binary Interface (ABI).
+* It interoperates well with plain C code.
+* It can be adopted partially and incrementally while still providing safety 
benefits.
+* It is syntactically and semantically compatible with C.
+* Consequently, source code that adopts the extension can continue to be 
compiled by toolchains that do not support the extension.
+* It has a relatively low adoption cost.
+* It can be implemented on top of Clang.
+
+This document discusses the key designs of ``-fbounds-safety``. The document 
is subject to be actively updated with a more detailed specification. The 
implementation plan can be found in `Implementation plans for -fbounds-safety 
`_.
+
+Programming Model
+=
+
+Overview
+
+
+``-fbounds-safety`` ensures that pointers are not used to access memory beyond 
their bounds by performing bounds checking. If a bounds check fails, the 
program will deterministically trap before out-of-bounds memory is accessed.
+
+In our model, every pointer has an explicit or implicit bounds attribute that 
determines its bounds and ensures guaranteed bounds checking. Consider the 
example below where the ``__counted_by(count)`` annotation indicates that 
parameter ``p`` points to a buffer of integers containing ``count`` elements. 
An off-by-one error is present in the loop condition, leading to ``p[i]`` being 
out-of-bounds access during the loop’s final iteration. The compiler inserts a 
bounds check before ``p`` is dereferenced to ensure that the access remains 
within the specified bounds.
+
+.. code-block:: c
+
+   void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
+   // off-by-one error (i < count)
+  for (unsigned i = 0; i <= count; ++i) {
+ // bounds check inserted:
+ //   if (i >= count) trap();
+ p[i] = i;
+  }
+   }
+
+A bounds annotation defines an invariant for the pointer type, and the model 
ensures that this invariant remains true. In the example below, pointer ``p`` 
annotated with ``__counted_by(count)`` must always point to a memory buffer 
containing at least ``count`` elements of the pointee type. Increasing the 
value of ``count``, like in the example below, would violate this invariant and 
permit out-of-bounds access to the pointer. To avoid this, the compiler emits 
either a compile-time error or a run-time trap. Section `Maintaining 
correctness of bounds annotations`_ provides more details about the programming 
model.
+
+.. code-block:: c
+
+   void foo(int *__counted_by(count) p, size_t count) {
+  count++; // violates the invariant of __counted_by
+   }
+
+The requirement to annotate all pointers with explicit bounds information 
could present a significant adoption burden. To tackle this

  1   2   3   4   5   >