[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-09 Thread Keith Packard via cfe-commits


@@ -238,6 +236,7 @@ END_COMPILERRT_OUTLINE_FUNCTION(__arm_sc_memcpy)
 
 DEFINE_COMPILERRT_FUNCTION_ALIAS(__arm_sc_memmove, __arm_sc_memcpy)
 
+#if defined(__aarch64__) && __ARM_FP != 0

keith-packard wrote:

Good plan. I've stuck a comment in both .c and .S files about why this function 
is implemented in both files.

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-09 Thread Keith Packard via cfe-commits


@@ -1,5 +1,20 @@
 #include 
 
+#if __ARM_FP == 0
+// WARNING: When building the scalar versions of these functions you need to
+// use the compiler flag "-mllvm -disable-loop-idiom-all" to prevent clang

keith-packard wrote:

I just checked -- the CMakeLists.txt file already uses `-fno-builtins`:
```
set_source_files_properties(aarch64/sme-libc-routines.c PROPERTIES 
COMPILE_FLAGS "-fno-builtin")
```
I've removed this mis-leading comment; we need `-fno-builtin` for every 
function in this file, and the memchr version doesn't talk about it.

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-09 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/111235

>From 08ed820b2bc6235998e47c49eb3029b7945b5fec Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:06:37 -0700
Subject: [PATCH 1/2] [libunwind] Support aarch64 without FPU

Skip save/restore of FPU registers on targets without them.

Signed-off-by: Keith Packard 
---
 libunwind/src/UnwindRegistersRestore.S | 4 ++--
 libunwind/src/UnwindRegistersSave.S| 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/libunwind/src/UnwindRegistersRestore.S 
b/libunwind/src/UnwindRegistersRestore.S
index 180a66582f41b5..1702d016c368ba 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -658,7 +658,7 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpx26,x27, [x0, #0x0D0]
   ldpx28,x29, [x0, #0x0E0]
   ldrx30, [x0, #0x100]  // restore pc into lr
-
+#if defined(__ARM_FP) && __ARM_FP != 0
   ldpd0, d1,  [x0, #0x110]
   ldpd2, d3,  [x0, #0x120]
   ldpd4, d5,  [x0, #0x130]
@@ -676,7 +676,7 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpd28,d29, [x0, #0x1F0]
   ldrd30, [x0, #0x200]
   ldrd31, [x0, #0x208]
-
+#endif
   // Finally, restore sp. This must be done after the last read from the
   // context struct, because it is allocated on the stack, and an exception
   // could clobber the de-allocated portion of the stack after sp has been
diff --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index fab234fcd6f318..a489a8ba6df159 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -746,6 +746,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   strx1,  [x0, #0x0F8]
   strx30, [x0, #0x100]// store return address as pc
   // skip cpsr
+#if defined(__ARM_FP) && __ARM_FP != 0
   stpd0, d1,  [x0, #0x110]
   stpd2, d3,  [x0, #0x120]
   stpd4, d5,  [x0, #0x130]
@@ -763,6 +764,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   stpd28,d29, [x0, #0x1F0]
   strd30, [x0, #0x200]
   strd31, [x0, #0x208]
+#endif
   movx0, #0   // return UNW_ESUCCESS
   ret
 

>From 474ae35242eb23f37689a1d933d018c74f2597d5 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:08:17 -0700
Subject: [PATCH 2/2] [compiler-rt] Support aarch64 targets without FPU

Fall back to the old C implementation of __arm_sc_memset when
the target doesn't have an FPU.

Signed-off-by: Keith Packard 
---
 .../lib/builtins/aarch64/sme-libc-mem-routines.S |  5 ++---
 compiler-rt/lib/builtins/aarch64/sme-libc-routines.c | 12 
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S 
b/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
index 0318d9a6f1ebd2..6e13a03691cfd6 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
+++ b/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
@@ -6,8 +6,6 @@
 
 #include "../assembly.h"
 
-#ifdef __aarch64__
-
 #define L(l) .L ## l
 
 //
@@ -238,7 +236,8 @@ END_COMPILERRT_OUTLINE_FUNCTION(__arm_sc_memcpy)
 
 DEFINE_COMPILERRT_FUNCTION_ALIAS(__arm_sc_memmove, __arm_sc_memcpy)
 
-
+// This version uses FP registers. Use this only on targets with them
+#if defined(__aarch64__) && __ARM_FP != 0
 //
 //  __arm_sc_memset
 //
diff --git a/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c 
b/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
index 315490e73ea2b1..07d6681485556b 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
@@ -1,5 +1,17 @@
 #include 
 
+/* The asm version uses FP registers. Use this on targets without them */
+#if __ARM_FP == 0
+void *__arm_sc_memset(void *dest, int c, size_t n) __arm_streaming_compatible {
+  unsigned char *destp = (unsigned char *)dest;
+  unsigned char c8 = (unsigned char)c;
+  for (size_t i = 0; i < n; ++i)
+destp[i] = c8;
+
+  return dest;
+}
+#endif
+
 const void *__arm_sc_memchr(const void *src, int c,
 size_t n) __arm_streaming_compatible {
   const unsigned char *srcp = (const unsigned char *)src;

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-09 Thread Keith Packard via cfe-commits

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-07 Thread Keith Packard via cfe-commits


@@ -6,7 +6,7 @@
 
 #include "../assembly.h"
 
-#ifdef __aarch64__
+#if defined(__aarch64__) && __ARM_FP != 0

keith-packard wrote:

Yeah, I've updated the patch after adapting some tests to make sure these all 
work on non-FPU hardware. That leaves only `__arm_sc_memset`.

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-10 Thread Keith Packard via cfe-commits


@@ -238,7 +236,8 @@ END_COMPILERRT_OUTLINE_FUNCTION(__arm_sc_memcpy)
 
 DEFINE_COMPILERRT_FUNCTION_ALIAS(__arm_sc_memmove, __arm_sc_memcpy)
 
-
+// This version uses FP registers. Use this only on targets with them
+#if defined(__aarch64__) && __ARM_FP != 0

keith-packard wrote:

I'm not sure; the previous version protected this with `#ifdef __aarch64__`, so 
I just kept that in place. Seemed odd to me as well.

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


[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-06 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/110928

>From 34ec006112994e99c27569c8811ee53e4a5c8c63 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] [PowerPC][ISelLowering] Support
 -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

To keep Linux targets from also getting another load
due to LOAD_STACK_GUARD, kill that instruction when using
"tls" mode. We can't use LOAD_STACK_GUARD for this new case
as that is gated by useLoadStackGuardNode() and that function
doesn't have a reference to the Module where we could test
for "tls" mode.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 18 ++
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 20 
 llvm/lib/Target/PowerPC/PPCISelLowering.h   |  1 +
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp|  6 ++
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c9baca00ec6f3b..2b465915054a0c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3605,7 +3605,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3645,7 +3645,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
-if (EffectiveTriple.isRISCV()) {
+if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
   if (Value != "tls" && Value != "global") {
 D.Diag(diag::err_drv_invalid_value_with_suggestion)
 << A->getOption().getName() << Value << "tls global";
@@ -3666,7 +3666,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3686,7 +3686,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3703,6 +3703,16 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "tp";
   return;
 }
+if (EffectiveTriple.isPPC64() && Value != "r13") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r13";
+  return;
+}
+if (EffectiveTriple.isPPC32() && Value != "r2") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r2";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d9847a21489e63..089c866af11b5e 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -17913,6 +17913,26 @@ Value *PPCTargetLowering::getSDagStackGuard(const 
Module &M) const {
   return TargetLowering::getSDagStackGuard(M);
 }
 
+static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
+  Module *M = IRB.GetInsertBlock()->getModule();
+  Function *ThreadPointerFunc =
+  Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
+  return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
+IRB.CreateCall(ThreadPointerFunc), Offset);
+}
+
+Value *PPCTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Specially, some users may customize the base reg and offset.
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-06 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/110928

>From 05c0a80977564496094a55ca0ca0b54b8048a30b Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] [PowerPC][ISelLowering] Support
 -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

To keep Linux targets from also getting another load
due to LOAD_STACK_GUARD, kill that instruction when using
"tls" mode. We can't use LOAD_STACK_GUARD for this new case
as that is gated by useLoadStackGuardNode() and that function
doesn't have a reference to the Module where we could test
for "tls" mode.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 18 ++
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 20 
 llvm/lib/Target/PowerPC/PPCISelLowering.h   |  1 +
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp|  6 ++
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c9baca00ec6f3b..2b465915054a0c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3605,7 +3605,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3645,7 +3645,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
-if (EffectiveTriple.isRISCV()) {
+if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
   if (Value != "tls" && Value != "global") {
 D.Diag(diag::err_drv_invalid_value_with_suggestion)
 << A->getOption().getName() << Value << "tls global";
@@ -3666,7 +3666,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3686,7 +3686,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3703,6 +3703,16 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "tp";
   return;
 }
+if (EffectiveTriple.isPPC64() && Value != "r13") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r13";
+  return;
+}
+if (EffectiveTriple.isPPC32() && Value != "r2") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r2";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d9847a21489e63..089c866af11b5e 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -17913,6 +17913,26 @@ Value *PPCTargetLowering::getSDagStackGuard(const 
Module &M) const {
   return TargetLowering::getSDagStackGuard(M);
 }
 
+static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
+  Module *M = IRB.GetInsertBlock()->getModule();
+  Function *ThreadPointerFunc =
+  Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
+  return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
+IRB.CreateCall(ThreadPointerFunc), Offset);
+}
+
+Value *PPCTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Specially, some users may customize the base reg and offset.
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-07 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/110928

>From 05c0a80977564496094a55ca0ca0b54b8048a30b Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/5] [PowerPC][ISelLowering] Support
 -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

To keep Linux targets from also getting another load
due to LOAD_STACK_GUARD, kill that instruction when using
"tls" mode. We can't use LOAD_STACK_GUARD for this new case
as that is gated by useLoadStackGuardNode() and that function
doesn't have a reference to the Module where we could test
for "tls" mode.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 18 ++
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 20 
 llvm/lib/Target/PowerPC/PPCISelLowering.h   |  1 +
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp|  6 ++
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c9baca00ec6f3b..2b465915054a0c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3605,7 +3605,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3645,7 +3645,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
-if (EffectiveTriple.isRISCV()) {
+if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
   if (Value != "tls" && Value != "global") {
 D.Diag(diag::err_drv_invalid_value_with_suggestion)
 << A->getOption().getName() << Value << "tls global";
@@ -3666,7 +3666,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3686,7 +3686,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3703,6 +3703,16 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "tp";
   return;
 }
+if (EffectiveTriple.isPPC64() && Value != "r13") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r13";
+  return;
+}
+if (EffectiveTriple.isPPC32() && Value != "r2") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r2";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d9847a21489e63..089c866af11b5e 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -17913,6 +17913,26 @@ Value *PPCTargetLowering::getSDagStackGuard(const 
Module &M) const {
   return TargetLowering::getSDagStackGuard(M);
 }
 
+static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
+  Module *M = IRB.GetInsertBlock()->getModule();
+  Function *ThreadPointerFunc =
+  Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
+  return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
+IRB.CreateCall(ThreadPointerFunc), Offset);
+}
+
+Value *PPCTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Specially, some users may customize the base reg and offset.
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-07 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/110928

>From 6fc295312f31915cb691fb612a290fa245e5f9f6 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Sun, 6 Oct 2024 23:19:30 -0700
Subject: [PATCH 1/5] [CodeGen] Provide Module to useLoadStackGuardNode

Use of LOAD_STACK_GUARD may depend upon compilation parameters; the
Module has access to all of the stack guard parameter methods.

Allow targets to only implement the old interface by providing a
wrapper. Mark the old interface protected to catch callers who fail to
pass the Module.

Signed-off-by: Keith Packard 
---
 llvm/include/llvm/CodeGen/TargetLowering.h| 8 ++--
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  | 4 ++--
 llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ---
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h 
b/llvm/include/llvm/CodeGen/TargetLowering.h
index 3842af56e6b3d7..dc6136686fe4cf 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5586,8 +5586,8 @@ class TargetLowering : public TargetLoweringBase {
 
   /// If this function returns true, SelectionDAGBuilder emits a
   /// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector.
-  virtual bool useLoadStackGuardNode() const {
-return false;
+  virtual bool useLoadStackGuardNode(const Module &M) const {
+return useLoadStackGuardNode();
   }
 
   virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
@@ -5616,6 +5616,10 @@ class TargetLowering : public TargetLoweringBase {
 return true;
   }
 
+protected:
+  // Simple interface for targets without a Module dependency
+  virtual bool useLoadStackGuardNode() const { return false; }
+
 private:
   SDValue foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
const SDLoc &DL, DAGCombinerInfo &DCI) const;
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp 
b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 40360b0b0f1d86..7b57db149a 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -2377,7 +2377,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst 
&CI, Intrinsic::ID ID,
   case Intrinsic::stackprotector: {
 LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL);
 Register GuardVal;
-if (TLI->useLoadStackGuardNode()) {
+if (TLI->useLoadStackGuardNode(*CI.getModule())) {
   GuardVal = MRI->createGenericVirtualRegister(PtrTy);
   getStackGuard(GuardVal, MIRBuilder);
 } else
@@ -3868,7 +3868,7 @@ bool 
IRTranslator::emitSPDescriptorParent(StackProtectorDescriptor &SPD,
 
   // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
   // Otherwise, emit a volatile load to retrieve the stack guard value.
-  if (TLI->useLoadStackGuardNode()) {
+  if (TLI->useLoadStackGuardNode(*ParentBB->getBasicBlock()->getModule())) {
 Guard =
 MRI->createGenericVirtualRegister(LLT::scalar(PtrTy.getSizeInBits()));
 getStackGuard(Guard, *CurBuilder);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 25213f587116d5..138058ce192470 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3138,7 +3138,7 @@ void 
SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
   // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
   // Otherwise, emit a volatile load to retrieve the stack guard value.
   SDValue Chain = DAG.getEntryNode();
-  if (TLI.useLoadStackGuardNode()) {
+  if (TLI.useLoadStackGuardNode(M)) {
 Guard = getLoadStackGuard(DAG, dl, Chain);
   } else {
 const Value *IRGuard = TLI.getSDagStackGuard(M);
@@ -7331,7 +7331,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const 
CallInst &I,
 const Module &M = *MF.getFunction().getParent();
 EVT PtrTy = TLI.getValueType(DAG.getDataLayout(), I.getType());
 SDValue Chain = getRoot();
-if (TLI.useLoadStackGuardNode()) {
+if (TLI.useLoadStackGuardNode(M)) {
   Res = getLoadStackGuard(DAG, sdl, Chain);
   Res = DAG.getPtrExtOrTrunc(Res, sdl, PtrTy);
 } else {
@@ -7351,9 +7351,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const 
CallInst &I,
 // Emit code into the DAG to store the stack guard onto the stack.
 MachineFunction &MF = DAG.getMachineFunction();
 MachineFrameInfo &MFI = MF.getFrameInfo();
+const Module &M = *MF.getFunction().getParent();
 SDValue Src, Chain = getRoot();
 
-if (TLI.useLoadStackGuardNode())
+if (TLI.useLoadStackGuardNode(M))
   Src = getLoadStackGuard(DAG, sdl, Chain);
 else
   Src = getValue(I.getArgOperand(0));   // The guard's value.

>From 77a0a017917894b33095b7f7ae94047430cc8f6e Mon Sep 17 00:00:00 

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-07 Thread Keith Packard via cfe-commits

keith-packard wrote:

Ok, I think this is a lot closer now -- I'm using the non-deprecated mechanism 
for generating the canary load instruction, although that required reworking 
the guard function API a bit.

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-04 Thread Keith Packard via cfe-commits

https://github.com/keith-packard created 
https://github.com/llvm/llvm-project/pull/111235

These two libraries don't build for `-march=armv8-a+nofp -mabi=aapcs-soft` as a 
couple of uses of floating point instructions and registers have crept in.

>From 6201bc34f1213e9f8c477421757509c9c4e678ce Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:06:37 -0700
Subject: [PATCH 1/2] [libunwind] Support aarch64 without FPU

ldp and stp instructions both require an FPU. Use pairs of ldr or str
instructions when the target doesn't have one.

Signed-off-by: Keith Packard 
---
 libunwind/src/UnwindRegistersRestore.S | 36 +++--
 libunwind/src/UnwindRegistersSave.S| 37 +++---
 2 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/libunwind/src/UnwindRegistersRestore.S 
b/libunwind/src/UnwindRegistersRestore.S
index 180a66582f41b5..13a40d080c4c2d 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -633,6 +633,12 @@ Lnovec:
 .arch_extension gcs
 #endif
 
+#if defined(__ARM_FP) && __ARM_FP != 0
+#define LDP(a,b,r,o,p) stp a, b, [r, o]
+#else
+#define LDP(a,b,r,o,p) ldr a, [r, o] ; ldr b, [r, p]
+#endif
+
 //
 // extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
 //
@@ -642,23 +648,24 @@ Lnovec:
   .p2align 2
 DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   // skip restore of x0,x1 for now
-  ldpx2, x3,  [x0, #0x010]
-  ldpx4, x5,  [x0, #0x020]
-  ldpx6, x7,  [x0, #0x030]
-  ldpx8, x9,  [x0, #0x040]
-  ldpx10,x11, [x0, #0x050]
-  ldpx12,x13, [x0, #0x060]
-  ldpx14,x15, [x0, #0x070]
+  LDP(x2, x3, x0, #0x010, #0x018)
+  LDP(x4, x5, x0, #0x020, #0x028)
+  LDP(x6, x7, x0, #0x030, #0x038)
+  LDP(x8, x9, x0, #0x040, #0x048)
+  LDP(x10, x11, x0, #0x050, #0x058)
+  LDP(x12, x13, x0, #0x060, #0x068)
+  LDP(x14, x15, x0, #0x070, #0x078)
   // x16 and x17 were clobbered by the call into the unwinder, so no point in
   // restoring them.
-  ldpx18,x19, [x0, #0x090]
-  ldpx20,x21, [x0, #0x0A0]
-  ldpx22,x23, [x0, #0x0B0]
-  ldpx24,x25, [x0, #0x0C0]
-  ldpx26,x27, [x0, #0x0D0]
-  ldpx28,x29, [x0, #0x0E0]
+  LDP(x18, x19, x0, #0x090, #0x098)
+  LDP(x20, x21, x0, #0x0A0, #0x0A8)
+  LDP(x22, x23, x0, #0x0B0, #0x0B8)
+  LDP(x24, x25, x0, #0x0C0, #0x0C8)
+  LDP(x26, x27, x0, #0x0D0, #0x0D8)
+  LDP(x28, x29, x0, #0x0E0, #0x0E8)
   ldrx30, [x0, #0x100]  // restore pc into lr
 
+#if defined(__ARM_FP) && __ARM_FP != 0
   ldpd0, d1,  [x0, #0x110]
   ldpd2, d3,  [x0, #0x120]
   ldpd4, d5,  [x0, #0x130]
@@ -676,13 +683,14 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpd28,d29, [x0, #0x1F0]
   ldrd30, [x0, #0x200]
   ldrd31, [x0, #0x208]
+#endif
 
   // Finally, restore sp. This must be done after the last read from the
   // context struct, because it is allocated on the stack, and an exception
   // could clobber the de-allocated portion of the stack after sp has been
   // restored.
   ldrx16, [x0, #0x0F8]
-  ldpx0, x1,  [x0, #0x000]  // restore x0,x1
+  LDP(x0, x1, x0, #0x000, #0x008)  // restore x0,x1
   movsp,x16 // restore sp
 #if defined(__ARM_FEATURE_GCS_DEFAULT)
   // If GCS is enabled we need to push the address we're returning to onto the
diff --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index fab234fcd6f318..922469bc11aa22 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -718,6 +718,12 @@ LnoR2Fix:
 
 #elif defined(__aarch64__)
 
+#if defined(__ARM_FP) && __ARM_FP != 0
+#define STP(a,b,r,o,p) stp a, b, [r, o]
+#else
+#define STP(a,b,r,o,p) str a, [r, o] ; str b, [r, p]
+#endif
+
 //
 // extern int __unw_getcontext(unw_context_t* thread_state)
 //
@@ -726,21 +732,21 @@ LnoR2Fix:
 //
   .p2align 2
 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
-  stpx0, x1,  [x0, #0x000]
-  stpx2, x3,  [x0, #0x010]
-  stpx4, x5,  [x0, #0x020]
-  stpx6, x7,  [x0, #0x030]
-  stpx8, x9,  [x0, #0x040]
-  stpx10,x11, [x0, #0x050]
-  stpx12,x13, [x0, #0x060]
-  stpx14,x15, [x0, #0x070]
-  stpx16,x17, [x0, #0x080]
-  stpx18,x19, [x0, #0x090]
-  stpx20,x21, [x0, #0x0A0]
-  stpx22,x23, [x0, #0x0B0]
-  stpx24,x25, [x0, #0x0C0]
-  stpx26,x27, [x0, #0x0D0]
-  stpx28,x29, [x0, #0x0E0]
+  STP(x0, x1, x0, #0x000, #0x008)
+  STP(x2, x3, x0, #0x010, #0x018)
+  STP(x4, x5, x0, #0x020, #0x028)
+  STP(x6, x7, x0, #0x030, #0x038)
+  STP(x8, x9, x0, #0x040, #0x048)
+  STP(x10, x11, x0, #0x050, #0x058)
+  STP(x12, x13, x0, #0x060, #0x068)
+  STP(x14, x15, x0, #0x070, #0x078)
+  STP(x16, x17, x0, #0x080, #0x088)
+  STP(x18, x19, x0, #0x090, #0x098)
+  STP(x20, x21, x0, #0x0A0, #0x0A8)
+  STP(x22, x23, x0, #0x0B0, #0x0B8)
+  STP(x24, x25, x0, #0x0C0, #0x0C8)
+  STP(x26, x27, x0, #0x0D0, #0x0D8)
+  STP(x28, x29, x0, #0x0E0, #0x0E8)
   s

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-07 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/110928

>From ad3d5b03886aa7939d67aef10e31734db7c43834 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Sun, 6 Oct 2024 23:19:30 -0700
Subject: [PATCH 1/5] [CodeGen] Provide Module to useLoadStackGuardNode

Use of LOAD_STACK_GUARD may depend upon compilation parameters; the
Module has access to all of the stack guard parameter methods.

Signed-off-by: Keith Packard 
---
 llvm/include/llvm/CodeGen/TargetLowering.h| 4 +---
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  | 4 ++--
 llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp   | 4 ++--
 llvm/lib/Target/AArch64/AArch64ISelLowering.h | 2 +-
 llvm/lib/Target/ARM/ARMISelLowering.cpp   | 2 +-
 llvm/lib/Target/ARM/ARMISelLowering.h | 2 +-
 llvm/lib/Target/Sparc/SparcISelLowering.cpp   | 4 ++--
 llvm/lib/Target/Sparc/SparcISelLowering.h | 2 +-
 llvm/lib/Target/SystemZ/SystemZISelLowering.h | 4 +---
 llvm/lib/Target/X86/X86ISelLowering.cpp   | 2 +-
 llvm/lib/Target/X86/X86ISelLowering.h | 2 +-
 12 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h 
b/llvm/include/llvm/CodeGen/TargetLowering.h
index 3842af56e6b3d7..54054ed38050ea 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5586,9 +5586,7 @@ class TargetLowering : public TargetLoweringBase {
 
   /// If this function returns true, SelectionDAGBuilder emits a
   /// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector.
-  virtual bool useLoadStackGuardNode() const {
-return false;
-  }
+  virtual bool useLoadStackGuardNode(const Module &M) const { return false; }
 
   virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
   const SDLoc &DL) const {
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp 
b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 40360b0b0f1d86..7b57db149a 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -2377,7 +2377,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst 
&CI, Intrinsic::ID ID,
   case Intrinsic::stackprotector: {
 LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL);
 Register GuardVal;
-if (TLI->useLoadStackGuardNode()) {
+if (TLI->useLoadStackGuardNode(*CI.getModule())) {
   GuardVal = MRI->createGenericVirtualRegister(PtrTy);
   getStackGuard(GuardVal, MIRBuilder);
 } else
@@ -3868,7 +3868,7 @@ bool 
IRTranslator::emitSPDescriptorParent(StackProtectorDescriptor &SPD,
 
   // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
   // Otherwise, emit a volatile load to retrieve the stack guard value.
-  if (TLI->useLoadStackGuardNode()) {
+  if (TLI->useLoadStackGuardNode(*ParentBB->getBasicBlock()->getModule())) {
 Guard =
 MRI->createGenericVirtualRegister(LLT::scalar(PtrTy.getSizeInBits()));
 getStackGuard(Guard, *CurBuilder);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 25213f587116d5..138058ce192470 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3138,7 +3138,7 @@ void 
SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
   // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
   // Otherwise, emit a volatile load to retrieve the stack guard value.
   SDValue Chain = DAG.getEntryNode();
-  if (TLI.useLoadStackGuardNode()) {
+  if (TLI.useLoadStackGuardNode(M)) {
 Guard = getLoadStackGuard(DAG, dl, Chain);
   } else {
 const Value *IRGuard = TLI.getSDagStackGuard(M);
@@ -7331,7 +7331,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const 
CallInst &I,
 const Module &M = *MF.getFunction().getParent();
 EVT PtrTy = TLI.getValueType(DAG.getDataLayout(), I.getType());
 SDValue Chain = getRoot();
-if (TLI.useLoadStackGuardNode()) {
+if (TLI.useLoadStackGuardNode(M)) {
   Res = getLoadStackGuard(DAG, sdl, Chain);
   Res = DAG.getPtrExtOrTrunc(Res, sdl, PtrTy);
 } else {
@@ -7351,9 +7351,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const 
CallInst &I,
 // Emit code into the DAG to store the stack guard onto the stack.
 MachineFunction &MF = DAG.getMachineFunction();
 MachineFrameInfo &MFI = MF.getFrameInfo();
+const Module &M = *MF.getFunction().getParent();
 SDValue Src, Chain = getRoot();
 
-if (TLI.useLoadStackGuardNode())
+if (TLI.useLoadStackGuardNode(M))
   Src = getLoadStackGuard(DAG, sdl, Chain);
 else
   Src = getValue(I.getArgOperand(0));   // The guard's value.
diff --git a/llvm/lib

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-07 Thread Keith Packard via cfe-commits


@@ -5616,6 +5616,10 @@ class TargetLowering : public TargetLoweringBase {
 return true;
   }
 
+protected:
+  // Simple interface for targets without a Module dependency

keith-packard wrote:

Yup, that makes things look cleaner. Good idea.

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-07 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/111235

>From 08ed820b2bc6235998e47c49eb3029b7945b5fec Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:06:37 -0700
Subject: [PATCH 1/2] [libunwind] Support aarch64 without FPU

Skip save/restore of FPU registers on targets without them.

Signed-off-by: Keith Packard 
---
 libunwind/src/UnwindRegistersRestore.S | 4 ++--
 libunwind/src/UnwindRegistersSave.S| 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/libunwind/src/UnwindRegistersRestore.S 
b/libunwind/src/UnwindRegistersRestore.S
index 180a66582f41b5..1702d016c368ba 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -658,7 +658,7 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpx26,x27, [x0, #0x0D0]
   ldpx28,x29, [x0, #0x0E0]
   ldrx30, [x0, #0x100]  // restore pc into lr
-
+#if defined(__ARM_FP) && __ARM_FP != 0
   ldpd0, d1,  [x0, #0x110]
   ldpd2, d3,  [x0, #0x120]
   ldpd4, d5,  [x0, #0x130]
@@ -676,7 +676,7 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpd28,d29, [x0, #0x1F0]
   ldrd30, [x0, #0x200]
   ldrd31, [x0, #0x208]
-
+#endif
   // Finally, restore sp. This must be done after the last read from the
   // context struct, because it is allocated on the stack, and an exception
   // could clobber the de-allocated portion of the stack after sp has been
diff --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index fab234fcd6f318..a489a8ba6df159 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -746,6 +746,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   strx1,  [x0, #0x0F8]
   strx30, [x0, #0x100]// store return address as pc
   // skip cpsr
+#if defined(__ARM_FP) && __ARM_FP != 0
   stpd0, d1,  [x0, #0x110]
   stpd2, d3,  [x0, #0x120]
   stpd4, d5,  [x0, #0x130]
@@ -763,6 +764,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   stpd28,d29, [x0, #0x1F0]
   strd30, [x0, #0x200]
   strd31, [x0, #0x208]
+#endif
   movx0, #0   // return UNW_ESUCCESS
   ret
 

>From afdaba612d84092bd7eed9d3161ba297094ef9e6 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:08:17 -0700
Subject: [PATCH 2/2] [compiler-rt] Support aarch64 targets without FPU

Fall back to the old C implementation of __arm_sc_memset when
the target doesn't have an FPU.

Signed-off-by: Keith Packard 
---
 .../lib/builtins/aarch64/sme-libc-mem-routines.S  |  3 +--
 .../lib/builtins/aarch64/sme-libc-routines.c  | 15 +++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S 
b/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
index 0318d9a6f1ebd2..9cd4c5eacf2773 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
+++ b/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
@@ -6,8 +6,6 @@
 
 #include "../assembly.h"
 
-#ifdef __aarch64__
-
 #define L(l) .L ## l
 
 //
@@ -238,6 +236,7 @@ END_COMPILERRT_OUTLINE_FUNCTION(__arm_sc_memcpy)
 
 DEFINE_COMPILERRT_FUNCTION_ALIAS(__arm_sc_memmove, __arm_sc_memcpy)
 
+#if defined(__aarch64__) && __ARM_FP != 0
 
 //
 //  __arm_sc_memset
diff --git a/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c 
b/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
index 315490e73ea2b1..122e3e58f78a7a 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
@@ -1,5 +1,20 @@
 #include 
 
+#if __ARM_FP == 0
+// WARNING: When building the scalar versions of these functions you need to
+// use the compiler flag "-mllvm -disable-loop-idiom-all" to prevent clang
+// from recognising a loop idiom and planting calls to memcpy!
+
+void *__arm_sc_memset(void *dest, int c, size_t n) __arm_streaming_compatible {
+  unsigned char *destp = (unsigned char *)dest;
+  unsigned char c8 = (unsigned char)c;
+  for (size_t i = 0; i < n; ++i)
+destp[i] = c8;
+
+  return dest;
+}
+#endif
+
 const void *__arm_sc_memchr(const void *src, int c,
 size_t n) __arm_streaming_compatible {
   const unsigned char *srcp = (const unsigned char *)src;

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


[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-07 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/110928

>From ad3d5b03886aa7939d67aef10e31734db7c43834 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Sun, 6 Oct 2024 23:19:30 -0700
Subject: [PATCH 1/5] [CodeGen] Provide Module to useLoadStackGuardNode

Use of LOAD_STACK_GUARD may depend upon compilation parameters; the
Module has access to all of the stack guard parameter methods.

Signed-off-by: Keith Packard 
---
 llvm/include/llvm/CodeGen/TargetLowering.h| 4 +---
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  | 4 ++--
 llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp   | 4 ++--
 llvm/lib/Target/AArch64/AArch64ISelLowering.h | 2 +-
 llvm/lib/Target/ARM/ARMISelLowering.cpp   | 2 +-
 llvm/lib/Target/ARM/ARMISelLowering.h | 2 +-
 llvm/lib/Target/Sparc/SparcISelLowering.cpp   | 4 ++--
 llvm/lib/Target/Sparc/SparcISelLowering.h | 2 +-
 llvm/lib/Target/SystemZ/SystemZISelLowering.h | 4 +---
 llvm/lib/Target/X86/X86ISelLowering.cpp   | 2 +-
 llvm/lib/Target/X86/X86ISelLowering.h | 2 +-
 12 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h 
b/llvm/include/llvm/CodeGen/TargetLowering.h
index 3842af56e6b3d7..54054ed38050ea 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5586,9 +5586,7 @@ class TargetLowering : public TargetLoweringBase {
 
   /// If this function returns true, SelectionDAGBuilder emits a
   /// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector.
-  virtual bool useLoadStackGuardNode() const {
-return false;
-  }
+  virtual bool useLoadStackGuardNode(const Module &M) const { return false; }
 
   virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
   const SDLoc &DL) const {
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp 
b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 40360b0b0f1d86..7b57db149a 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -2377,7 +2377,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst 
&CI, Intrinsic::ID ID,
   case Intrinsic::stackprotector: {
 LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL);
 Register GuardVal;
-if (TLI->useLoadStackGuardNode()) {
+if (TLI->useLoadStackGuardNode(*CI.getModule())) {
   GuardVal = MRI->createGenericVirtualRegister(PtrTy);
   getStackGuard(GuardVal, MIRBuilder);
 } else
@@ -3868,7 +3868,7 @@ bool 
IRTranslator::emitSPDescriptorParent(StackProtectorDescriptor &SPD,
 
   // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
   // Otherwise, emit a volatile load to retrieve the stack guard value.
-  if (TLI->useLoadStackGuardNode()) {
+  if (TLI->useLoadStackGuardNode(*ParentBB->getBasicBlock()->getModule())) {
 Guard =
 MRI->createGenericVirtualRegister(LLT::scalar(PtrTy.getSizeInBits()));
 getStackGuard(Guard, *CurBuilder);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 25213f587116d5..138058ce192470 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3138,7 +3138,7 @@ void 
SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
   // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
   // Otherwise, emit a volatile load to retrieve the stack guard value.
   SDValue Chain = DAG.getEntryNode();
-  if (TLI.useLoadStackGuardNode()) {
+  if (TLI.useLoadStackGuardNode(M)) {
 Guard = getLoadStackGuard(DAG, dl, Chain);
   } else {
 const Value *IRGuard = TLI.getSDagStackGuard(M);
@@ -7331,7 +7331,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const 
CallInst &I,
 const Module &M = *MF.getFunction().getParent();
 EVT PtrTy = TLI.getValueType(DAG.getDataLayout(), I.getType());
 SDValue Chain = getRoot();
-if (TLI.useLoadStackGuardNode()) {
+if (TLI.useLoadStackGuardNode(M)) {
   Res = getLoadStackGuard(DAG, sdl, Chain);
   Res = DAG.getPtrExtOrTrunc(Res, sdl, PtrTy);
 } else {
@@ -7351,9 +7351,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const 
CallInst &I,
 // Emit code into the DAG to store the stack guard onto the stack.
 MachineFunction &MF = DAG.getMachineFunction();
 MachineFrameInfo &MFI = MF.getFrameInfo();
+const Module &M = *MF.getFunction().getParent();
 SDValue Src, Chain = getRoot();
 
-if (TLI.useLoadStackGuardNode())
+if (TLI.useLoadStackGuardNode(M))
   Src = getLoadStackGuard(DAG, sdl, Chain);
 else
   Src = getValue(I.getArgOperand(0));   // The guard's value.
diff --git a/llvm/lib

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-07 Thread Keith Packard via cfe-commits

keith-packard wrote:

btw, I'm testing this using Linux from 
https://git.kernel.org/pub/scm/linux/kernel/git/nathan/linux.git/log/?h=b4/powerpc-fix-stackprotector-test-clang

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-07 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/111235

>From f0546a52bc25327007f75e7267654a858637a76d Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:06:37 -0700
Subject: [PATCH 1/2] Support aarch64 without FPU

Skip save/restore of FPU registers on targets without them.

Signed-off-by: Keith Packard 
---
 libunwind/src/UnwindRegistersRestore.S | 4 ++--
 libunwind/src/UnwindRegistersSave.S| 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/libunwind/src/UnwindRegistersRestore.S 
b/libunwind/src/UnwindRegistersRestore.S
index 180a66582f41b5..1702d016c368ba 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -658,7 +658,7 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpx26,x27, [x0, #0x0D0]
   ldpx28,x29, [x0, #0x0E0]
   ldrx30, [x0, #0x100]  // restore pc into lr
-
+#if defined(__ARM_FP) && __ARM_FP != 0
   ldpd0, d1,  [x0, #0x110]
   ldpd2, d3,  [x0, #0x120]
   ldpd4, d5,  [x0, #0x130]
@@ -676,7 +676,7 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpd28,d29, [x0, #0x1F0]
   ldrd30, [x0, #0x200]
   ldrd31, [x0, #0x208]
-
+#endif
   // Finally, restore sp. This must be done after the last read from the
   // context struct, because it is allocated on the stack, and an exception
   // could clobber the de-allocated portion of the stack after sp has been
diff --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index fab234fcd6f318..a489a8ba6df159 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -746,6 +746,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   strx1,  [x0, #0x0F8]
   strx30, [x0, #0x100]// store return address as pc
   // skip cpsr
+#if defined(__ARM_FP) && __ARM_FP != 0
   stpd0, d1,  [x0, #0x110]
   stpd2, d3,  [x0, #0x120]
   stpd4, d5,  [x0, #0x130]
@@ -763,6 +764,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   stpd28,d29, [x0, #0x1F0]
   strd30, [x0, #0x200]
   strd31, [x0, #0x208]
+#endif
   movx0, #0   // return UNW_ESUCCESS
   ret
 

>From 43aa8d2b859314fcee174febb24fe72f80bd241c Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:08:17 -0700
Subject: [PATCH 2/2] Support aarch64 targets without FPU

Fall back to the old C implementations of various routines when
the target doesn't have an FPU.

Signed-off-by: Keith Packard 
---
 .../builtins/aarch64/sme-libc-mem-routines.S  |  2 +-
 .../lib/builtins/aarch64/sme-libc-routines.c  | 77 +++
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S 
b/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
index 0318d9a6f1ebd2..72d87fb4fa8586 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
+++ b/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
@@ -6,7 +6,7 @@
 
 #include "../assembly.h"
 
-#ifdef __aarch64__
+#if defined(__aarch64__) && __ARM_FP != 0
 
 #define L(l) .L ## l
 
diff --git a/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c 
b/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
index 315490e73ea2b1..92fb953c03a376 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
@@ -1,5 +1,82 @@
 #include 
 
+#if __ARM_FP == 0
+// WARNING: When building the scalar versions of these functions you need to
+// use the compiler flag "-mllvm -disable-loop-idiom-all" to prevent clang
+// from recognising a loop idiom and planting calls to memcpy!
+
+static void *__arm_sc_memcpy_fwd(void *dest, const void *src,
+ size_t n) __arm_streaming_compatible {
+  unsigned char *destp = (unsigned char *)dest;
+  const unsigned char *srcp = (const unsigned char *)src;
+  for (size_t i = 0; i < n; ++i)
+destp[i] = srcp[i];
+
+  return dest;
+}
+
+// If dest and src overlap then behaviour is undefined, hence we can add the
+// restrict keywords here. This also matches the definition of the libc memcpy
+// according to the man page.
+void *__arm_sc_memcpy(void *__restrict__ dest, const void *__restrict__ src,
+  size_t n) __arm_streaming_compatible {
+  return __arm_sc_memcpy_fwd(dest, src, n);
+}
+
+void *__arm_sc_memset(void *dest, int c, size_t n) __arm_streaming_compatible {
+  unsigned char *destp = (unsigned char *)dest;
+  unsigned char c8 = (unsigned char)c;
+  for (size_t i = 0; i < n; ++i)
+destp[i] = c8;
+
+  return dest;
+}
+
+static void *__arm_sc_memcpy_rev(void *dest, const void *src,
+ size_t n) __arm_streaming_compatible {
+  unsigned char *destp = (unsigned char *)dest;
+  const unsigned char *srcp = (const unsigned char *)src;
+  // TODO: Improve performance by copying larger chun

[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-07 Thread Keith Packard via cfe-commits


@@ -633,6 +633,13 @@ Lnovec:
 .arch_extension gcs
 #endif
 
+#if defined(__ARM_FP) && __ARM_FP != 0
+#define LDP(a,b,r,o,p) stp a, b, [r, o]
+#else
+/* In reverse order so that the last LDP(x0,x1,x0) works. */
+#define LDP(a,b,r,o,p) ldr b, [r, p] ; ldr a, [r, o]

keith-packard wrote:

Yup, I applied too large a hammer here. Updated and tested.

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


[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-07 Thread Keith Packard via cfe-commits

keith-packard wrote:

> With [my series to fix 
> `arch/powerpc`](https://git.kernel.org/pub/scm/linux/kernel/git/nathan/linux.git/log/?h=b4/powerpc-fix-stackprotector-test-clang)
>  for this implementation applied to Linux, `CONFIG_HAVE_STACKPROTECTOR` is 
> properly set and the Linux kernel dump test module (LKDTM)’s 
> `REPORT_STACK_CANARY` test works correctly for both 32-bit and 64-bit. I 
> think with a PowerPC specific review, we should be ready to land this.

Stewart reviewed the PowerPC aspects of the patch (he used to work at IBM on 
OPAL, firmware for OpenPOWER systems).

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-10-02 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From f91cf985d10a07af617b6098f50d023108d060a4 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Wed, 2 Oct 2024 12:37:30 -0700
Subject: [PATCH 1/5] [RISCV][ISelLowering] Use getModule() instead of
 getParent()->getParent()

This is a simple clean-up motivated by review of changes adding TLS
support for the stack canary. Using getModule() is a shorter and
clearer expression of the desired operation.

Signed-off-by: Keith Packard 
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4f77bba2968988..ef1ca110c4703b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21304,7 +21304,7 @@ bool RISCVTargetLowering::preferScalarizeSplat(SDNode 
*N) const {
 }
 
 static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
-  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+  Module *M = IRB.GetInsertBlock()->getModule();
   Function *ThreadPointerFunc =
   Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
   return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),

>From bc4cde4b367b3083eba91d3e3850fda988552090 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 2/5] [RISCV][ISelLowering] Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index b9987288d82d10..c9baca00ec6f3b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index ef1ca110c4703b..a0f885695c2051 10

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-10-02 Thread Keith Packard via cfe-commits

keith-packard wrote:

I've retitled the commit messages to match llvm conventions and added a 
clean-up to replace another instance of `getParent()->getParent()` with 
`getModule()`.

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-10-05 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/111235

>From 048cb1b0ea65fb758e104376c0bff345eab67623 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:06:37 -0700
Subject: [PATCH 1/2] [libunwind] Support aarch64 without FPU

ldp and stp instructions both require an FPU. Use pairs of ldr or str
instructions when the target doesn't have one.

Signed-off-by: Keith Packard 
---
 libunwind/src/UnwindRegistersRestore.S | 37 +++--
 libunwind/src/UnwindRegistersSave.S| 38 --
 2 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/libunwind/src/UnwindRegistersRestore.S 
b/libunwind/src/UnwindRegistersRestore.S
index 180a66582f41b5..9422a21503ebc0 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -633,6 +633,13 @@ Lnovec:
 .arch_extension gcs
 #endif
 
+#if defined(__ARM_FP) && __ARM_FP != 0
+#define LDP(a,b,r,o,p) stp a, b, [r, o]
+#else
+/* In reverse order so that the last LDP(x0,x1,x0) works. */
+#define LDP(a,b,r,o,p) ldr b, [r, p] ; ldr a, [r, o]
+#endif
+
 //
 // extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
 //
@@ -642,23 +649,24 @@ Lnovec:
   .p2align 2
 DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   // skip restore of x0,x1 for now
-  ldpx2, x3,  [x0, #0x010]
-  ldpx4, x5,  [x0, #0x020]
-  ldpx6, x7,  [x0, #0x030]
-  ldpx8, x9,  [x0, #0x040]
-  ldpx10,x11, [x0, #0x050]
-  ldpx12,x13, [x0, #0x060]
-  ldpx14,x15, [x0, #0x070]
+  LDP(x2, x3, x0, #0x010, #0x018)
+  LDP(x4, x5, x0, #0x020, #0x028)
+  LDP(x6, x7, x0, #0x030, #0x038)
+  LDP(x8, x9, x0, #0x040, #0x048)
+  LDP(x10, x11, x0, #0x050, #0x058)
+  LDP(x12, x13, x0, #0x060, #0x068)
+  LDP(x14, x15, x0, #0x070, #0x078)
   // x16 and x17 were clobbered by the call into the unwinder, so no point in
   // restoring them.
-  ldpx18,x19, [x0, #0x090]
-  ldpx20,x21, [x0, #0x0A0]
-  ldpx22,x23, [x0, #0x0B0]
-  ldpx24,x25, [x0, #0x0C0]
-  ldpx26,x27, [x0, #0x0D0]
-  ldpx28,x29, [x0, #0x0E0]
+  LDP(x18, x19, x0, #0x090, #0x098)
+  LDP(x20, x21, x0, #0x0A0, #0x0A8)
+  LDP(x22, x23, x0, #0x0B0, #0x0B8)
+  LDP(x24, x25, x0, #0x0C0, #0x0C8)
+  LDP(x26, x27, x0, #0x0D0, #0x0D8)
+  LDP(x28, x29, x0, #0x0E0, #0x0E8)
   ldrx30, [x0, #0x100]  // restore pc into lr
 
+#if defined(__ARM_FP) && __ARM_FP != 0
   ldpd0, d1,  [x0, #0x110]
   ldpd2, d3,  [x0, #0x120]
   ldpd4, d5,  [x0, #0x130]
@@ -676,13 +684,14 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpd28,d29, [x0, #0x1F0]
   ldrd30, [x0, #0x200]
   ldrd31, [x0, #0x208]
+#endif
 
   // Finally, restore sp. This must be done after the last read from the
   // context struct, because it is allocated on the stack, and an exception
   // could clobber the de-allocated portion of the stack after sp has been
   // restored.
   ldrx16, [x0, #0x0F8]
-  ldpx0, x1,  [x0, #0x000]  // restore x0,x1
+  LDP(x0, x1, x0, #0x000, #0x008)  // restore x0,x1
   movsp,x16 // restore sp
 #if defined(__ARM_FEATURE_GCS_DEFAULT)
   // If GCS is enabled we need to push the address we're returning to onto the
diff --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index fab234fcd6f318..19c7ed20a8cf67 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -718,6 +718,12 @@ LnoR2Fix:
 
 #elif defined(__aarch64__)
 
+#if defined(__ARM_FP) && __ARM_FP != 0
+#define STP(a,b,r,o,p) stp a, b, [r, o]
+#else
+#define STP(a,b,r,o,p) str a, [r, o] ; str b, [r, p]
+#endif
+
 //
 // extern int __unw_getcontext(unw_context_t* thread_state)
 //
@@ -726,26 +732,27 @@ LnoR2Fix:
 //
   .p2align 2
 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
-  stpx0, x1,  [x0, #0x000]
-  stpx2, x3,  [x0, #0x010]
-  stpx4, x5,  [x0, #0x020]
-  stpx6, x7,  [x0, #0x030]
-  stpx8, x9,  [x0, #0x040]
-  stpx10,x11, [x0, #0x050]
-  stpx12,x13, [x0, #0x060]
-  stpx14,x15, [x0, #0x070]
-  stpx16,x17, [x0, #0x080]
-  stpx18,x19, [x0, #0x090]
-  stpx20,x21, [x0, #0x0A0]
-  stpx22,x23, [x0, #0x0B0]
-  stpx24,x25, [x0, #0x0C0]
-  stpx26,x27, [x0, #0x0D0]
-  stpx28,x29, [x0, #0x0E0]
+  STP(x0, x1, x0, #0x000, #0x008)
+  STP(x2, x3, x0, #0x010, #0x018)
+  STP(x4, x5, x0, #0x020, #0x028)
+  STP(x6, x7, x0, #0x030, #0x038)
+  STP(x8, x9, x0, #0x040, #0x048)
+  STP(x10, x11, x0, #0x050, #0x058)
+  STP(x12, x13, x0, #0x060, #0x068)
+  STP(x14, x15, x0, #0x070, #0x078)
+  STP(x16, x17, x0, #0x080, #0x088)
+  STP(x18, x19, x0, #0x090, #0x098)
+  STP(x20, x21, x0, #0x0A0, #0x0A8)
+  STP(x22, x23, x0, #0x0B0, #0x0B8)
+  STP(x24, x25, x0, #0x0C0, #0x0C8)
+  STP(x26, x27, x0, #0x0D0, #0x0D8)
+  STP(x28, x29, x0, #0x0E0, #0x0E8)
   strx30, [x0, #0x0F0]
   movx1,sp
   strx1,  [x0, #0x0F8]
   strx30, 

[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-11-04 Thread Keith Packard via cfe-commits


@@ -238,7 +236,8 @@ END_COMPILERRT_OUTLINE_FUNCTION(__arm_sc_memcpy)
 
 DEFINE_COMPILERRT_FUNCTION_ALIAS(__arm_sc_memmove, __arm_sc_memcpy)
 
-
+// This version uses FP registers. Use this only on targets with them
+#if defined(__aarch64__) && __ARM_FP != 0

keith-packard wrote:

I've rebased today; what else would I need to do to "submit it upstream"?

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


[compiler-rt] [libunwind] [AArch64] Fix nofp regressions in compiler-rt and libunwind (PR #111235)

2024-11-04 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/111235

>From 7002f226e15145c3791cc5587f2397bed8f362a4 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:06:37 -0700
Subject: [PATCH 1/2] [libunwind] Support aarch64 without FPU

Skip save/restore of FPU registers on targets without them.

Signed-off-by: Keith Packard 
---
 libunwind/src/UnwindRegistersRestore.S | 4 ++--
 libunwind/src/UnwindRegistersSave.S| 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/libunwind/src/UnwindRegistersRestore.S 
b/libunwind/src/UnwindRegistersRestore.S
index 180a66582f41b5..1702d016c368ba 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -658,7 +658,7 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpx26,x27, [x0, #0x0D0]
   ldpx28,x29, [x0, #0x0E0]
   ldrx30, [x0, #0x100]  // restore pc into lr
-
+#if defined(__ARM_FP) && __ARM_FP != 0
   ldpd0, d1,  [x0, #0x110]
   ldpd2, d3,  [x0, #0x120]
   ldpd4, d5,  [x0, #0x130]
@@ -676,7 +676,7 @@ 
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldpd28,d29, [x0, #0x1F0]
   ldrd30, [x0, #0x200]
   ldrd31, [x0, #0x208]
-
+#endif
   // Finally, restore sp. This must be done after the last read from the
   // context struct, because it is allocated on the stack, and an exception
   // could clobber the de-allocated portion of the stack after sp has been
diff --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index fab234fcd6f318..a489a8ba6df159 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -746,6 +746,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   strx1,  [x0, #0x0F8]
   strx30, [x0, #0x100]// store return address as pc
   // skip cpsr
+#if defined(__ARM_FP) && __ARM_FP != 0
   stpd0, d1,  [x0, #0x110]
   stpd2, d3,  [x0, #0x120]
   stpd4, d5,  [x0, #0x130]
@@ -763,6 +764,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   stpd28,d29, [x0, #0x1F0]
   strd30, [x0, #0x200]
   strd31, [x0, #0x208]
+#endif
   movx0, #0   // return UNW_ESUCCESS
   ret
 

>From 90d4f6a91fcb3d2997c2abec2ba54469acaea3f0 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Fri, 4 Oct 2024 21:08:17 -0700
Subject: [PATCH 2/2] [compiler-rt] Support aarch64 targets without FPU

Fall back to the old C implementation of __arm_sc_memset when
the target doesn't have an FPU.

Signed-off-by: Keith Packard 
---
 .../lib/builtins/aarch64/sme-libc-mem-routines.S |  5 ++---
 compiler-rt/lib/builtins/aarch64/sme-libc-routines.c | 12 
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S 
b/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
index 0318d9a6f1ebd2..6e13a03691cfd6 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
+++ b/compiler-rt/lib/builtins/aarch64/sme-libc-mem-routines.S
@@ -6,8 +6,6 @@
 
 #include "../assembly.h"
 
-#ifdef __aarch64__
-
 #define L(l) .L ## l
 
 //
@@ -238,7 +236,8 @@ END_COMPILERRT_OUTLINE_FUNCTION(__arm_sc_memcpy)
 
 DEFINE_COMPILERRT_FUNCTION_ALIAS(__arm_sc_memmove, __arm_sc_memcpy)
 
-
+// This version uses FP registers. Use this only on targets with them
+#if defined(__aarch64__) && __ARM_FP != 0
 //
 //  __arm_sc_memset
 //
diff --git a/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c 
b/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
index 315490e73ea2b1..07d6681485556b 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-libc-routines.c
@@ -1,5 +1,17 @@
 #include 
 
+/* The asm version uses FP registers. Use this on targets without them */
+#if __ARM_FP == 0
+void *__arm_sc_memset(void *dest, int c, size_t n) __arm_streaming_compatible {
+  unsigned char *destp = (unsigned char *)dest;
+  unsigned char c8 = (unsigned char)c;
+  for (size_t i = 0; i < n; ++i)
+destp[i] = c8;
+
+  return dest;
+}
+#endif
+
 const void *__arm_sc_memchr(const void *src, int c,
 size_t n) __arm_streaming_compatible {
   const unsigned char *srcp = (const unsigned char *)src;

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-22 Thread Keith Packard via cfe-commits


@@ -0,0 +1,19 @@
+; RUN: llc -mtriple=riscv64-unknown-elf < %s | \

keith-packard wrote:

Thanks. I wondered how that was supposed to work.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getParent()->getParent();

keith-packard wrote:

Thanks, will review.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 156b989feea26694b291cde9be637947be9aca67 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/3] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..0593fbf403dfcb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From c4ebffa39a10b35c094fccf026228222b6346e23 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/3] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  9 +
 clang/test/Driver/stack-protector-guard.c  | 12 
 2 files changed, 21 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc8753966 100644
--- a/clang/test/C

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getParent()->getParent();

keith-packard wrote:

Yup, getModule is just `return getParent()->getParent();`. Done.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 156b989feea26694b291cde9be637947be9aca67 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..0593fbf403dfcb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 32cf791269138c2d983741617c5581109aa96864 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/4] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  9 +
 clang/test/Driver/stack-protector-guard.c  | 19 +++
 2 files changed, 28 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc8753966 100644
--- a/clang

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {

keith-packard wrote:

Added a test to make sure -mstack-protector-guard=global still works correctly 
after the patch. Also added positive tests to make sure valid driver arguments 
get passed through to the backend.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-22 Thread Keith Packard via cfe-commits


@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {

keith-packard wrote:

Yes, that's the existing non-TLS version which uses `__stack_chk_guard`. It's 
the default mode. I could add a test to make sure it still works?

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-22 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From a295c6d8057ddd712097e3bf659cdbe3bb4ec869 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/3] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..c52ef550495052 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Specially, some users may customize the base reg and offset.
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 2453a5114aeae2b2661628f321c0af868b8c3c4e Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/3] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  9 +
 clang/test/Driver/stack-protector-guard.c  | 12 
 2 files changed, 21 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-22 Thread Keith Packard via cfe-commits


@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)

keith-packard wrote:

Thanks, I missed that one. Added.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-22 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 60ad4f7793701bc50d1c65db4fe665558678fd7b Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/3] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..8fa85a684db5a4 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 0689e2f930b59377ef9777482f316646557eaead Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/3] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  9 +
 clang/test/Driver/stack-protector-guard.c  | 12 
 2 files changed, 21 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc8753966 100644
--- a

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 156b989feea26694b291cde9be637947be9aca67 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..0593fbf403dfcb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 90678b54ca324f691c80e9868a446827a5cf Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/4] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  8 
 clang/test/Driver/stack-protector-guard.c  | 19 +++
 2 files changed, 27 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..4777367c94e733 100644
--- a/clang/

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64-unknown-elf -verify-machineinstrs < %s \
+; RUN: | FileCheck %s
+
+define void @foo(i64 %t) sspstrong {

keith-packard wrote:

Thanks for your patience. Yes, adding nounwind eliminates the unwind 
information from the test output, which seems like a useful simplification.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 156b989feea26694b291cde9be637947be9aca67 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..0593fbf403dfcb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 90678b54ca324f691c80e9868a446827a5cf Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/4] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  8 
 clang/test/Driver/stack-protector-guard.c  | 19 +++
 2 files changed, 27 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..4777367c94e733 100644
--- a/clang/

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -verify-machineinstrs < %s | \
+; RUN: FileCheck %s
+
+target triple = "riscv64-unknown-linux-gnu"
+
+define dso_local void @foo(i64 %t) local_unnamed_addr #0 {
+; CHECK-LABEL: foo:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:addi sp, sp, -32
+; CHECK-NEXT:.cfi_def_cfa_offset 32
+; CHECK-NEXT:sd ra, 24(sp) # 8-byte Folded Spill
+; CHECK-NEXT:sd s0, 16(sp) # 8-byte Folded Spill
+; CHECK-NEXT:sd s1, 8(sp) # 8-byte Folded Spill
+; CHECK-NEXT:.cfi_offset ra, -8
+; CHECK-NEXT:.cfi_offset s0, -16
+; CHECK-NEXT:.cfi_offset s1, -24
+; CHECK-NEXT:addi s0, sp, 32
+; CHECK-NEXT:.cfi_def_cfa s0, 0
+; CHECK-NEXT:lui s1, %hi(__stack_chk_guard)
+; CHECK-NEXT:ld a1, %lo(__stack_chk_guard)(s1)
+; CHECK-NEXT:sd a1, -32(s0)
+; CHECK-NEXT:slli a0, a0, 2
+; CHECK-NEXT:addi a0, a0, 15
+; CHECK-NEXT:andi a0, a0, -16
+; CHECK-NEXT:sub a0, sp, a0
+; CHECK-NEXT:mv sp, a0
+; CHECK-NEXT:call baz
+; CHECK-NEXT:ld a0, %lo(__stack_chk_guard)(s1)
+; CHECK-NEXT:ld a1, -32(s0)
+; CHECK-NEXT:bne a0, a1, .LBB0_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:addi sp, s0, -32
+; CHECK-NEXT:ld ra, 24(sp) # 8-byte Folded Reload
+; CHECK-NEXT:ld s0, 16(sp) # 8-byte Folded Reload
+; CHECK-NEXT:ld s1, 8(sp) # 8-byte Folded Reload
+; CHECK-NEXT:addi sp, sp, 32
+; CHECK-NEXT:ret
+; CHECK-NEXT:  .LBB0_2:
+; CHECK-NEXT:call __stack_chk_fail
+  %vla = alloca i32, i64 %t, align 4
+  call void @baz(ptr nonnull %vla)

keith-packard wrote:

Inherited from ARM/stack-guard-tls.ll, so I didn't consider it. But, no, it's 
not necessary.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 156b989feea26694b291cde9be637947be9aca67 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..0593fbf403dfcb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 32cf791269138c2d983741617c5581109aa96864 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/4] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  9 +
 clang/test/Driver/stack-protector-guard.c  | 19 +++
 2 files changed, 28 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc8753966 100644
--- a/clang

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -verify-machineinstrs < %s | \
+; RUN: FileCheck %s
+
+target triple = "riscv64-unknown-linux-gnu"
+
+define dso_local void @foo(i64 %t) local_unnamed_addr #0 {
+; CHECK-LABEL: foo:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:addi sp, sp, -32
+; CHECK-NEXT:.cfi_def_cfa_offset 32
+; CHECK-NEXT:sd ra, 24(sp) # 8-byte Folded Spill
+; CHECK-NEXT:sd s0, 16(sp) # 8-byte Folded Spill
+; CHECK-NEXT:sd s1, 8(sp) # 8-byte Folded Spill
+; CHECK-NEXT:.cfi_offset ra, -8
+; CHECK-NEXT:.cfi_offset s0, -16
+; CHECK-NEXT:.cfi_offset s1, -24
+; CHECK-NEXT:addi s0, sp, 32
+; CHECK-NEXT:.cfi_def_cfa s0, 0
+; CHECK-NEXT:lui s1, %hi(__stack_chk_guard)
+; CHECK-NEXT:ld a1, %lo(__stack_chk_guard)(s1)
+; CHECK-NEXT:sd a1, -32(s0)
+; CHECK-NEXT:slli a0, a0, 2
+; CHECK-NEXT:addi a0, a0, 15
+; CHECK-NEXT:andi a0, a0, -16
+; CHECK-NEXT:sub a0, sp, a0
+; CHECK-NEXT:mv sp, a0
+; CHECK-NEXT:call baz
+; CHECK-NEXT:ld a0, %lo(__stack_chk_guard)(s1)
+; CHECK-NEXT:ld a1, -32(s0)
+; CHECK-NEXT:bne a0, a1, .LBB0_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:addi sp, s0, -32
+; CHECK-NEXT:ld ra, 24(sp) # 8-byte Folded Reload
+; CHECK-NEXT:ld s0, 16(sp) # 8-byte Folded Reload
+; CHECK-NEXT:ld s1, 8(sp) # 8-byte Folded Reload
+; CHECK-NEXT:addi sp, sp, 32
+; CHECK-NEXT:ret
+; CHECK-NEXT:  .LBB0_2:
+; CHECK-NEXT:call __stack_chk_fail
+  %vla = alloca i32, i64 %t, align 4
+  call void @baz(ptr nonnull %vla)
+  ret void
+}
+
+declare void @baz(ptr)
+
+attributes #0 = { sspstrong uwtable }

keith-packard wrote:

nope, it's been removed.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits




keith-packard wrote:

yup, all fixes mirrored over there. Thanks for your careful review!

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 156b989feea26694b291cde9be637947be9aca67 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..0593fbf403dfcb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 32cf791269138c2d983741617c5581109aa96864 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/4] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  9 +
 clang/test/Driver/stack-protector-guard.c  | 19 +++
 2 files changed, 28 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc8753966 100644
--- a/clang

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -verify-machineinstrs < %s | \
+; RUN: FileCheck %s
+
+target triple = "riscv64-unknown-linux-gnu"

keith-packard wrote:

sorry, copied this from llvm/test/CodeGen/AArch64/stack-guard-sysreg.ll which 
did it this way. I'll switch.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -verify-machineinstrs < %s | \
+; RUN: FileCheck %s
+
+target triple = "riscv64-unknown-linux-gnu"
+
+define dso_local void @foo(i64 %t) local_unnamed_addr #0 {

keith-packard wrote:

Thanks, much cleaner looking now.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 156b989feea26694b291cde9be637947be9aca67 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..0593fbf403dfcb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 32cf791269138c2d983741617c5581109aa96864 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/4] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  9 +
 clang/test/Driver/stack-protector-guard.c  | 19 +++
 2 files changed, 28 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc8753966 100644
--- a/clang

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -verify-machineinstrs < %s | \
+; RUN: FileCheck %s

keith-packard wrote:

Thanks. After moving the triple into the RUN line, it's long enough that 
wrapping looks cleaner. I found a couple of examples using indentation on the 
continuation line to follow.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits

keith-packard wrote:

> LGTM

Thanks so much for all the review and help here; really appreciate it.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64-unknown-elf -verify-machineinstrs < %s \

keith-packard wrote:

I kinda wondered -- the existing tests are all over the place with triples. 
I've switched to just 'riscv64'.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-23 Thread Keith Packard via cfe-commits


@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64-unknown-elf -verify-machineinstrs < %s \
+; RUN: | FileCheck %s
+
+define void @foo(i64 %t) sspstrong {

keith-packard wrote:

You were right, it doesn't need nounwind; we're just testing the stack 
protector code here.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-19 Thread Keith Packard via cfe-commits


@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {

keith-packard wrote:

Yeah, I went for the easiest-to-review mechanism that just created new RISC-V 
specific clauses instead of attempting to mix them into the existing ones. It's 
not exactly a performance-critical area of code.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-19 Thread Keith Packard via cfe-commits


@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {

keith-packard wrote:

Could probably be, but I felt it would be easier to review if I didn't attempt 
to refactor the code at the same time new functionality was being added.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-19 Thread Keith Packard via cfe-commits


@@ -3664,12 +3680,18 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && (Offset <= -2048 || Offset >= 2048)) {

keith-packard wrote:

Done, and new bits pushed.

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-18 Thread Keith Packard via cfe-commits

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-19 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From a295c6d8057ddd712097e3bf659cdbe3bb4ec869 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/3] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..76692bf8176cf5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..c52ef550495052 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Specially, some users may customize the base reg and offset.
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 85ed8bedd59c8770df02d395895cb30f001094ce Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/3] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c | 9 +
 clang/test/Driver/stack-protector-guard.c  | 7 +++
 2 files changed, 16 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc8753966

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-18 Thread Keith Packard via cfe-commits


@@ -3664,12 +3680,18 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && (Offset <= -2048 || Offset >= 2048)) {

keith-packard wrote:

Yeah, this is used as an offset from the TLS base register (tp). GCC doesn't 
allow arbitrary offsets for this value, permitting only a value that can be 
encoded as an immediate value in the load instruction. I mirrored those limits 
(slightly incorrectly) in my patch. Given that llvm can support arbitrary 
values as the compiler is happy to use multiple instructions as required, I 
think it's probably best to just remove this test instead of introducing an 
artificial limit to match gcc's behavior?

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


[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-02 Thread Keith Packard via cfe-commits

https://github.com/keith-packard created 
https://github.com/llvm/llvm-project/pull/110928

Add support for using a thread-local variable with a specified offset for 
holding the stack guard canary value. This supports both 32- and 64- bit 
PowerPC targets.

This mirrors changes from #108942 but targeting PowerPC instead of RISCV. 
Because both of these PRs modify the same driver functions, this series is 
stack on top of the RISC-V one.


>From f91cf985d10a07af617b6098f50d023108d060a4 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Wed, 2 Oct 2024 12:37:30 -0700
Subject: [PATCH 1/9] [RISCV][ISelLowering] Use getModule() instead of
 getParent()->getParent()

This is a simple clean-up motivated by review of changes adding TLS
support for the stack canary. Using getModule() is a shorter and
clearer expression of the desired operation.

Signed-off-by: Keith Packard 
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4f77bba2968988..ef1ca110c4703b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21304,7 +21304,7 @@ bool RISCVTargetLowering::preferScalarizeSplat(SDNode 
*N) const {
 }
 
 static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
-  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+  Module *M = IRB.GetInsertBlock()->getModule();
   Function *ThreadPointerFunc =
   Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
   return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),

>From bc4cde4b367b3083eba91d3e3850fda988552090 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 2/9] [RISCV][ISelLowering] Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index b9987288d82d10..c9baca00ec6f3b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTrip

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-10-02 Thread Keith Packard via cfe-commits

keith-packard wrote:

> LGTM. I assume you need someone to push it?

Yes please! The PowerPC one is waiting in the wings :-)

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


[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-10-02 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/108942

>From 1ca3c96bc0e07a2fdae982736017f1d31147e4e4 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 28 ++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index b9987288d82d10..c9baca00ec6f3b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4f77bba2968988..50f0adb3818c0d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21323,6 +21323,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Users must specify the offset explicitly
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 2beba985ae8ee8393c8f813d3e43d94fbad5277d Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/4] Driver: add stack protector tests for riscv

Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.

Signed-off-by: Keith Packard 
---
 clang/test/CodeGen/stack-protector-guard.c |  8 
 clang/test/Driver/stack-protector-guard.c  | 19 +++
 2 files changed, 27 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..4777367c94e733 100644
--- a/clang/

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-03 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/110928

>From 74b14206ea2ec0772063ce55440531834a8a0ae7 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] [PowerPC][ISelLowering] Support
 -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 18 ++
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 21 +
 llvm/lib/Target/PowerPC/PPCISelLowering.h   |  1 +
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c9baca00ec6f3b..2b465915054a0c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3605,7 +3605,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3645,7 +3645,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
-if (EffectiveTriple.isRISCV()) {
+if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
   if (Value != "tls" && Value != "global") {
 D.Diag(diag::err_drv_invalid_value_with_suggestion)
 << A->getOption().getName() << Value << "tls global";
@@ -3666,7 +3666,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3686,7 +3686,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3703,6 +3703,16 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "tp";
   return;
 }
+if (EffectiveTriple.isPPC64() && Value != "r13") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r13";
+  return;
+}
+if (EffectiveTriple.isPPC32() && Value != "r2") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r2";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d9847a21489e63..455b62aed4c027 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -17913,6 +17913,27 @@ Value *PPCTargetLowering::getSDagStackGuard(const 
Module &M) const {
   return TargetLowering::getSDagStackGuard(M);
 }
 
+static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
+  Module *M = IRB.GetInsertBlock()->getModule();
+  Function *ThreadPointerFunc =
+  Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
+  return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
+IRB.CreateCall(ThreadPointerFunc), Offset);
+}
+
+Value *PPCTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Specially, some users may customize the base reg and offset.
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
+  return TargetLowering::getIRStackGuard(IRB);
+}
+
+
 bool PPCTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
  bool ForCodeSize) const {
   if (!VT.isSimple() || !Subtarget.hasVSX())
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h 
b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 8907c3c5a81c3c..8d993d467f

[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-03 Thread Keith Packard via cfe-commits


@@ -3605,7 +3605,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC64() &&
+!EffectiveTriple.isPPC32())

keith-packard wrote:

None at all -- I started adding just PPC64 support and realized that it would 
be easy to just do both 32 and 64 in the same series, but didn't go back and 
re-factor. Thanks for catching this. I've rebased on top of main so that the 
RISC-V changes aren't mixed into this PR.

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


[clang] [llvm] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls (PR #110928)

2024-10-03 Thread Keith Packard via cfe-commits

https://github.com/keith-packard updated 
https://github.com/llvm/llvm-project/pull/110928

>From 3ac025bd12d42b9318edf7aefe1d93a6d06b95bb Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/4] [PowerPC][ISelLowering] Support
 -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 18 ++
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 20 
 llvm/lib/Target/PowerPC/PPCISelLowering.h   |  1 +
 3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c9baca00ec6f3b..2b465915054a0c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3605,7 +3605,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3645,7 +3645,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
-if (EffectiveTriple.isRISCV()) {
+if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
   if (Value != "tls" && Value != "global") {
 D.Diag(diag::err_drv_invalid_value_with_suggestion)
 << A->getOption().getName() << Value << "tls global";
@@ -3666,7 +3666,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3686,7 +3686,7 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isRISCV())
+!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3703,6 +3703,16 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "tp";
   return;
 }
+if (EffectiveTriple.isPPC64() && Value != "r13") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r13";
+  return;
+}
+if (EffectiveTriple.isPPC32() && Value != "r2") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "r2";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d9847a21489e63..089c866af11b5e 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -17913,6 +17913,26 @@ Value *PPCTargetLowering::getSDagStackGuard(const 
Module &M) const {
   return TargetLowering::getSDagStackGuard(M);
 }
 
+static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
+  Module *M = IRB.GetInsertBlock()->getModule();
+  Function *ThreadPointerFunc =
+  Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
+  return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
+IRB.CreateCall(ThreadPointerFunc), Offset);
+}
+
+Value *PPCTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Specially, some users may customize the base reg and offset.
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
+  return TargetLowering::getIRStackGuard(IRB);
+}
+
 bool PPCTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
  bool ForCodeSize) const {
   if (!VT.isSimple() || !Subtarget.hasVSX())
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h 
b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 8907c3c5a81c3c..8d993d467f2b0

[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)

2024-09-17 Thread Keith Packard via cfe-commits

https://github.com/keith-packard created 
https://github.com/llvm/llvm-project/pull/108942

Add support for using a thread-local variable with a specified offsetfor 
holding the stack guard canary value.

>From 7822a1ee2eed923a3014577668bdd8f1c8145d4c Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/3] riscv: Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard 
---
 clang/lib/Driver/ToolChains/Clang.cpp   | 33 +++--
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 +
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..4c7756b3883b8c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value << "sysreg global";
   return;
 }
+if (EffectiveTriple.isRISCV()) {
+  if (Value != "tls" && Value != "global") {
+D.Diag(diag::err_drv_invalid_value_with_suggestion)
+<< A->getOption().getName() << Value << "tls global";
+return;
+  }
+  if (Value == "tls") {
+if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+  D.Diag(diag::err_drv_ssp_missing_offset_argument)
+  << A->getAsString(Args);
+  return;
+}
+  }
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
 StringRef Value = A->getValue();
 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-!EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 int Offset;
@@ -3664,12 +3680,18 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && (Offset <= -2048 || Offset >= 2048)) {
+  D.Diag(diag::err_drv_invalid_int_value)
+  << A->getOption().getName() << Value;
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
 StringRef Value = A->getValue();
-if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+!EffectiveTriple.isRISCV())
   D.Diag(diag::err_drv_unsupported_opt_for_target)
   << A->getAsString(Args) << TripleStr;
 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3703,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
   return;
 }
+if (EffectiveTriple.isRISCV() && Value != "tp") {
+  D.Diag(diag::err_drv_invalid_value_with_suggestion)
+  << A->getOption().getName() << Value << "tp";
+  return;
+}
 A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..c52ef550495052 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
 return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+
+  if (M->getStackProtectorGuard() == "tls") {
+// Specially, some users may customize the base reg and offset.
+int Offset = M->getStackProtectorGuardOffset();
+return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 9f589d801fa62a1bb46c2b8f3d56b653396028c6 Mon Sep 17 00:00:00 2001
From: Keith Packard 
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/3] Driver: add stack protector tests for riscv

Ad