[clang] [llvm] [RISCV] Add -m[no-]scalar-strict-align and -m[no-]vector-strict-align. Alias -m[no-]strict-align to scalar. (PR #95024)

Craig Topper via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 10 12:09:37 PDT 2024


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/95024

__riscv_misaligned_fast will be set based on -mno-scalar-strict-align or -mno-strict-align.

This matches the direction gcc is proposing.

See
https://github.com/riscv-non-isa/riscv-c-api-doc/issues/73
https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/49
https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/50
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/80

>From cda94f996a75b9cb4f7a53dce5845926b084af0e Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 10 Jun 2024 12:05:26 -0700
Subject: [PATCH] [RISCV] Add -m[no-]scalar-strict-align and
 -m[no-]vector-strict-align. Alias -m[no-]strict-align to scalar.

__riscv_misaligned_fast will be set based on -mno-scalar-strict-align
or -mno-strict-align.

This matches the direction gcc is proposing.

See
https://github.com/riscv-non-isa/riscv-c-api-doc/issues/73
https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/49
https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/50
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/80
---
 clang/docs/ReleaseNotes.rst                   |  5 +++
 clang/include/clang/Driver/Options.td         |  8 ++++
 clang/lib/Basic/Targets/RISCV.cpp             |  6 +--
 clang/lib/Basic/Targets/RISCV.h               |  2 +-
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp    | 39 +++++++++++++------
 clang/test/Driver/riscv-features.c            | 21 ++++++----
 .../llvm/TargetParser/RISCVTargetParser.h     |  3 +-
 llvm/lib/TargetParser/RISCVTargetParser.cpp   | 21 +++++++---
 llvm/test/TableGen/riscv-target-def.td        | 10 ++---
 llvm/utils/TableGen/RISCVTargetDefEmitter.cpp |  9 ++---
 10 files changed, 85 insertions(+), 39 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cf1ba02cbc4b2..a8a7286176733 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -949,6 +949,11 @@ RISC-V Support
 
 - ``__attribute__((rvv_vector_bits(N)))`` is now supported for RVV vbool*_t types.
 - Profile names in ``-march`` option are now supported.
+- ``-m[no-]scalar-strict-align`` and ``-m[no-]vector-strict-align`` options have
+  been added to give separate control of whether scalar or vector misaligned
+  accesses may be created.
+- ``-mi[no-]strict-align`` is now an alias of ``-m[no-]scalar-strict-align`` and
+  only affects scalar memory accesses.
 
 CUDA/HIP Language Changes
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d44faa55c456f..5b15a848c7e9f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4822,6 +4822,14 @@ def mstrict_align : Flag<["-"], "mstrict-align">, Group<m_Group>,
   HelpText<"Force all memory accesses to be aligned (AArch64/LoongArch/RISC-V only)">;
 def mno_strict_align : Flag<["-"], "mno-strict-align">, Group<m_Group>,
   HelpText<"Allow memory accesses to be unaligned (AArch64/LoongArch/RISC-V only)">;
+def mscalar_strict_align : Flag<["-"], "mscalar-strict-align">, Group<m_Group>,
+  HelpText<"Force all scalar memory accesses to be aligned (RISC-V only)">;
+def mno_scalar_strict_align : Flag<["-"], "mno-scalar-strict-align">, Group<m_Group>,
+  HelpText<"Allow scalar memory accesses to be unaligned (RISC-V only)">;
+def mvector_strict_align : Flag<["-"], "mvector-strict-align">, Group<m_Group>,
+  HelpText<"Force all vector memory accesses to be aligned (RISC-V only)">;
+def mno_vector_strict_align : Flag<["-"], "mno-vector-strict-align">, Group<m_Group>,
+  HelpText<"Allow vector memory accesses to be unaligned (RISC-V only)">;
 def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>;
 def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>,
   HelpText<"Disallow generation of complex IT blocks. It is off by default.">;
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index a7ce9dda34bdd..d513c08086487 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -211,7 +211,7 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
     Builder.defineMacro("__riscv_v_fixed_vlen",
                         Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
 
-  if (FastUnalignedAccess)
+  if (FastScalarUnalignedAccess)
     Builder.defineMacro("__riscv_misaligned_fast");
   else
     Builder.defineMacro("__riscv_misaligned_avoid");
@@ -353,8 +353,8 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
   if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx"))
     HasLegalHalfType = true;
 
-  FastUnalignedAccess = llvm::is_contained(Features, "+unaligned-scalar-mem") &&
-                        llvm::is_contained(Features, "+unaligned-vector-mem");
+  FastScalarUnalignedAccess =
+      llvm::is_contained(Features, "+unaligned-scalar-mem");
 
   if (llvm::is_contained(Features, "+experimental"))
     HasExperimental = true;
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index d0e9cdc6da07b..d5df6344bedc0 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -30,7 +30,7 @@ class RISCVTargetInfo : public TargetInfo {
   std::unique_ptr<llvm::RISCVISAInfo> ISAInfo;
 
 private:
-  bool FastUnalignedAccess;
+  bool FastScalarUnalignedAccess;
   bool HasExperimental = false;
 
 public:
diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 26789b0ba6e09..c29d0bcf9727d 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -77,7 +77,8 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   if (!getArchFeatures(D, MArch, Features, Args))
     return;
 
-  bool CPUFastUnaligned = false;
+  bool CPUFastScalarUnaligned = false;
+  bool CPUFastVectorUnaligned = false;
 
   // If users give march and mcpu, get std extension feature from MArch
   // and other features (ex. mirco architecture feature) from mcpu
@@ -88,8 +89,10 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
 
     getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features);
 
-    if (llvm::RISCV::hasFastUnalignedAccess(CPU))
-      CPUFastUnaligned = true;
+    if (llvm::RISCV::hasFastScalarUnalignedAccess(CPU))
+      CPUFastScalarUnaligned = true;
+    if (llvm::RISCV::hasFastVectorUnalignedAccess(CPU))
+      CPUFastVectorUnaligned = true;
   }
 
   // Handle features corresponding to "-ffixed-X" options
@@ -169,20 +172,34 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
     Features.push_back("-relax");
   }
 
-  // If -mstrict-align or -mno-strict-align is passed, use it. Otherwise, the
-  // unaligned-*-mem is enabled if the CPU supports it or the target is
+  // If -mstrict-align, -mno-strict-align, -mscalar-strict-align, or
+  // -mno-scalar-strict-align is passed, use it. Otherwise, the
+  // unaligned-scalar-mem is enabled if the CPU supports it or the target is
   // Android.
-  if (const Arg *A = Args.getLastArg(options::OPT_mno_strict_align,
-                                     options::OPT_mstrict_align)) {
-    if (A->getOption().matches(options::OPT_mno_strict_align)) {
+  if (const Arg *A = Args.getLastArg(
+          options::OPT_mno_strict_align, options::OPT_mscalar_strict_align,
+          options::OPT_mstrict_align, options::OPT_mno_scalar_strict_align)) {
+    if (A->getOption().matches(options::OPT_mno_strict_align) ||
+        A->getOption().matches(options::OPT_mno_scalar_strict_align)) {
       Features.push_back("+unaligned-scalar-mem");
-      Features.push_back("+unaligned-vector-mem");
     } else {
       Features.push_back("-unaligned-scalar-mem");
-      Features.push_back("-unaligned-vector-mem");
     }
-  } else if (CPUFastUnaligned || Triple.isAndroid()) {
+  } else if (CPUFastScalarUnaligned || Triple.isAndroid()) {
     Features.push_back("+unaligned-scalar-mem");
+  }
+
+  // If -mvector-strict-align or -mno-vector-strict-align is passed, use it.
+  // Otherwise, the unaligned-vector-mem is enabled if the CPU supports it or
+  // the target is Android.
+  if (const Arg *A = Args.getLastArg(options::OPT_mno_vector_strict_align,
+                                     options::OPT_mvector_strict_align)) {
+    if (A->getOption().matches(options::OPT_mno_vector_strict_align)) {
+      Features.push_back("+unaligned-vector-mem");
+    } else {
+      Features.push_back("-unaligned-vector-mem");
+    }
+  } else if (CPUFastVectorUnaligned || Triple.isAndroid()) {
     Features.push_back("+unaligned-vector-mem");
   }
 
diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c
index cfe293cd4667f..69795b35001f9 100644
--- a/clang/test/Driver/riscv-features.c
+++ b/clang/test/Driver/riscv-features.c
@@ -1,8 +1,8 @@
 // RUN: %clang --target=riscv32-unknown-elf -### %s -fsyntax-only 2>&1 | FileCheck %s
 // RUN: %clang --target=riscv64-unknown-elf -### %s -fsyntax-only 2>&1 | FileCheck %s
-// RUN: %clang --target=riscv64-linux-android -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ANDROID,DEFAULT,FAST-UNALIGNED-ACCESS
-// RUN: %clang -mabi=lp64d --target=riscv64-linux-android -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ANDROID,DEFAULT,FAST-UNALIGNED-ACCESS
-// RUN: %clang -mabi=lp64d --target=riscv64-linux-android -mstrict-align -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=NO-FAST-UNALIGNED-ACCESS
+// RUN: %clang --target=riscv64-linux-android -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ANDROID,DEFAULT,FAST-SCALAR-UNALIGNED-ACCESS,FAST-VECTOR-UNALIGNED-ACCESS
+// RUN: %clang -mabi=lp64d --target=riscv64-linux-android -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ANDROID,DEFAULT,FAST-SCALAR-UNALIGNED-ACCESS,FAST-VECTOR-UNALIGNED-ACCESS
+// RUN: %clang -mabi=lp64d --target=riscv64-linux-android -mstrict-align -mvector-strict-align -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=NO-FAST-SCALAR-UNALIGNED-ACCESS,NO-FAST-VECTOR-UNALIGNED-ACCESS
 
 
 // CHECK: fno-signed-char
@@ -35,13 +35,20 @@
 // NO-FORCE-SW-SCS: "-target-feature" "-forced-sw-shadow-stack"
 // DEFAULT-NOT: "-target-feature" "+forced-sw-shadow-stack"
 
-// RUN: %clang --target=riscv32-unknown-elf -### %s -mno-strict-align 2>&1 | FileCheck %s -check-prefix=FAST-UNALIGNED-ACCESS
-// RUN: %clang --target=riscv32-unknown-elf -### %s -mstrict-align 2>&1 | FileCheck %s -check-prefix=NO-FAST-UNALIGNED-ACCESS
+// RUN: %clang --target=riscv32-unknown-elf -### %s -mno-strict-align 2>&1 | FileCheck %s -check-prefix=FAST-SCALAR-UNALIGNED-ACCESS
+// RUN: %clang --target=riscv32-unknown-elf -### %s -mstrict-align 2>&1 | FileCheck %s -check-prefix=NO-FAST-SCALAR-UNALIGNED-ACCESS
+// RUN: %clang --target=riscv32-unknown-elf -### %s -mno-scalar-strict-align 2>&1 | FileCheck %s -check-prefix=FAST-SCALAR-UNALIGNED-ACCESS
+// RUN: %clang --target=riscv32-unknown-elf -### %s -mscalar-strict-align 2>&1 | FileCheck %s -check-prefix=NO-FAST-SCALAR-UNALIGNED-ACCESS
 // RUN: touch %t.o
 // RUN: %clang --target=riscv32-unknown-elf -### %t.o -mno-strict-align -mstrict-align
 
-// FAST-UNALIGNED-ACCESS: "-target-feature" "+unaligned-scalar-mem" "-target-feature" "+unaligned-vector-mem"
-// NO-FAST-UNALIGNED-ACCESS: "-target-feature" "-unaligned-scalar-mem" "-target-feature" "-unaligned-vector-mem"
+// FAST-SCALAR-UNALIGNED-ACCESS: "-target-feature" "+unaligned-scalar-mem"
+// NO-FAST-SCALAR-UNALIGNED-ACCESS: "-target-feature" "-unaligned-scalar-mem"
+
+// RUN: %clang --target=riscv32-unknown-elf -### %s -mno-vector-strict-align 2>&1 | FileCheck %s -check-prefix=FAST-VECTOR-UNALIGNED-ACCESS
+// RUN: %clang --target=riscv32-unknown-elf -### %s -mvector-strict-align 2>&1 | FileCheck %s -check-prefix=NO-FAST-VECTOR-UNALIGNED-ACCESS
+// FAST-VECTOR-UNALIGNED-ACCESS: "-target-feature" "+unaligned-vector-mem"
+// NO-FAST-VECTOR-UNALIGNED-ACCESS: "-target-feature" "-unaligned-vector-mem"
 
 // RUN: %clang --target=riscv32-unknown-elf -### %s 2>&1 | FileCheck %s -check-prefix=NOUWTABLE
 // RUN: %clang --target=riscv32-unknown-elf -fasynchronous-unwind-tables -### %s 2>&1 | FileCheck %s -check-prefix=UWTABLE
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index 5b1494efe7bdc..7421dac2744b6 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -35,7 +35,8 @@ bool parseTuneCPU(StringRef CPU, bool IsRV64);
 StringRef getMArchFromMcpu(StringRef CPU);
 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
-bool hasFastUnalignedAccess(StringRef CPU);
+bool hasFastScalarUnalignedAccess(StringRef CPU);
+bool hasFastVectorUnalignedAccess(StringRef CPU);
 
 } // namespace RISCV
 
diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp
index 9003f9beffa7e..db1b5f689d7da 100644
--- a/llvm/lib/TargetParser/RISCVTargetParser.cpp
+++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp
@@ -21,7 +21,9 @@ namespace llvm {
 namespace RISCV {
 
 enum CPUKind : unsigned {
-#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGN) CK_##ENUM,
+#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN,                   \
+             FAST_VECTOR_UNALIGN)                                              \
+  CK_##ENUM,
 #define TUNE_PROC(ENUM, NAME) CK_##ENUM,
 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
 };
@@ -29,13 +31,15 @@ enum CPUKind : unsigned {
 struct CPUInfo {
   StringLiteral Name;
   StringLiteral DefaultMarch;
-  bool FastUnalignedAccess;
+  bool FastScalarUnalignedAccess;
+  bool FastVectorUnalignedAccess;
   bool is64Bit() const { return DefaultMarch.starts_with("rv64"); }
 };
 
 constexpr CPUInfo RISCVCPUInfo[] = {
-#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGN)                          \
-  {NAME, DEFAULT_MARCH, FAST_UNALIGN},
+#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN,                   \
+             FAST_VECTOR_UNALIGN)                                              \
+  {NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, FAST_VECTOR_UNALIGN},
 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
 };
 
@@ -46,9 +50,14 @@ static const CPUInfo *getCPUInfoByName(StringRef CPU) {
   return nullptr;
 }
 
-bool hasFastUnalignedAccess(StringRef CPU) {
+bool hasFastScalarUnalignedAccess(StringRef CPU) {
   const CPUInfo *Info = getCPUInfoByName(CPU);
-  return Info && Info->FastUnalignedAccess;
+  return Info && Info->FastScalarUnalignedAccess;
+}
+
+bool hasFastVectorUnalignedAccess(StringRef CPU) {
+  const CPUInfo *Info = getCPUInfoByName(CPU);
+  return Info && Info->FastVectorUnalignedAccess;
 }
 
 bool parseCPU(StringRef CPU, bool IsRV64) {
diff --git a/llvm/test/TableGen/riscv-target-def.td b/llvm/test/TableGen/riscv-target-def.td
index fb58448d7ce88..7137cf96fd3d4 100644
--- a/llvm/test/TableGen/riscv-target-def.td
+++ b/llvm/test/TableGen/riscv-target-def.td
@@ -153,13 +153,13 @@ def ROCKET : RISCVTuneProcessorModel<"rocket",
 // CHECK:      #endif // GET_SUPPORTED_PROFILES
 
 // CHECK:      #ifndef PROC
-// CHECK-NEXT: #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGNED_ACCESS)
+// CHECK-NEXT: #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, FAST_VECTOR_UNALIGN)
 // CHECK-NEXT: #endif
 
-// CHECK:      PROC(GENERIC_RV32, {"generic-rv32"}, {"rv32i2p1"}, 0)
-// CHECK-NEXT: PROC(GENERIC_RV64, {"generic-rv64"}, {"rv64i2p1"}, 0)
-// CHECK-NEXT: PROC(ROCKET_RV32, {"rocket-rv32"}, {"rv32i2p1_zicsr2p0_zidummy0p1_zifencei2p0"}, 0)
-// CHECK-NEXT: PROC(ROCKET_RV64, {"rocket-rv64"}, {"rv64i2p1_zicsr2p0_zidummy0p1_zifencei2p0"}, 0)
+// CHECK:      PROC(GENERIC_RV32, {"generic-rv32"}, {"rv32i2p1"}, 0, 0)
+// CHECK-NEXT: PROC(GENERIC_RV64, {"generic-rv64"}, {"rv64i2p1"}, 0, 0)
+// CHECK-NEXT: PROC(ROCKET_RV32, {"rocket-rv32"}, {"rv32i2p1_zicsr2p0_zidummy0p1_zifencei2p0"}, 0, 0)
+// CHECK-NEXT: PROC(ROCKET_RV64, {"rocket-rv64"}, {"rv64i2p1_zicsr2p0_zidummy0p1_zifencei2p0"}, 0, 0)
 
 // CHECK: #undef PROC
 
diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
index b76ba05954aa5..04e9e0fa48db0 100644
--- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
@@ -164,7 +164,8 @@ static void emitRISCVProfiles(RecordKeeper &Records, raw_ostream &OS) {
 
 static void emitRISCVProcs(RecordKeeper &RK, raw_ostream &OS) {
   OS << "#ifndef PROC\n"
-     << "#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGNED_ACCESS)\n"
+     << "#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN"
+     << ", FAST_VECTOR_UNALIGN)\n"
      << "#endif\n\n";
 
   // Iterate on all definition records.
@@ -180,9 +181,6 @@ static void emitRISCVProcs(RecordKeeper &RK, raw_ostream &OS) {
       return Feature->getValueAsString("Name") == "unaligned-vector-mem";
     });
 
-    bool FastUnalignedAccess =
-        FastScalarUnalignedAccess && FastVectorUnalignedAccess;
-
     OS << "PROC(" << Rec->getName() << ", {\"" << Rec->getValueAsString("Name")
        << "\"}, {\"";
 
@@ -193,7 +191,8 @@ static void emitRISCVProcs(RecordKeeper &RK, raw_ostream &OS) {
       printMArch(OS, Features);
     else
       OS << MArch;
-    OS << "\"}, " << FastUnalignedAccess << ")\n";
+    OS << "\"}, " << FastScalarUnalignedAccess << ", "
+       << FastVectorUnalignedAccess << ")\n";
   }
   OS << "\n#undef PROC\n";
   OS << "\n";



More information about the cfe-commits mailing list