Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AMDGPU] -fcf-protection=full should not be applied to GPU targets in heterogenous code #86450

Open
AngryLoki opened this issue Mar 24, 2024 · 11 comments · May be fixed by #88402
Open

[AMDGPU] -fcf-protection=full should not be applied to GPU targets in heterogenous code #86450

AngryLoki opened this issue Mar 24, 2024 · 11 comments · May be fixed by #88402

Comments

@AngryLoki
Copy link
Contributor

AngryLoki commented Mar 24, 2024

In Gentoo 23.0 (upcoming) and hardened profile -fcf-protection=full is added automatically via /etc/clang/x86_64-pc-linux-gnu-clang++.cfg (as well as other flags). However this flag does not work well with heterogeneous hip code:

cd /tmp && wget https://raw.githubusercontent.com/ROCm-Developer-Tools/HIP-CPU/master/examples/vadd_hip/vadd_hip.cpp

# -fcf-protection=full is added manually for demonstration
/usr/lib/llvm/18/bin/clang++ --offload-arch=native -x hip vadd_hip.cpp -o vadd_hip \
-fno-stack-protector --hip-link -fcf-protection=full -nogpulib

error: option 'cf-protection=return' cannot be specified on this target

Although it is possible to use -fcf-protection=full -Xarch_device -fcf-protection=none to override this, it is irritating, as it can not be added to all files, as it produces warning: argument unused during compilation: '-Xarch_device -fcf-protection=none' for non-hip files.

In #70799 you added code to "not emit the stack protector metadata on unsupported architectures". Can you do the same for -fcf-protection=..., to apply CET only for host code? Thanks!

@AngryLoki
Copy link
Contributor Author

CC @jhuber6 as an author of stack-protector PR.

@AngryLoki AngryLoki changed the title [AMDGPU] Do not emit -fcf-protection=full on GPU architectures [AMDGPU] -fcf-protection=full should not be applied to GPU targets in heterogenous code Mar 24, 2024
@llvmbot
Copy link

llvmbot commented Mar 24, 2024

@llvm/issue-subscribers-backend-amdgpu

Author: None (AngryLoki)

In Gentoo 23.0 (upcoming) and hardened profile `-fcf-protection=full` is added automatically via `/etc/clang/x86_64-pc-linux-gnu-clang++.cfg` (as well as [other flags](https://wiki.gentoo.org/wiki/Hardened/Toolchain#Changes)). However this flag does not work well with heterogeneous hip code:
cd /tmp && wget https://raw.githubusercontent.com/ROCm-Developer-Tools/HIP-CPU/master/examples/vadd_hip/vadd_hip.cpp

# -fcf-protection=full is added manually for demonstration
/usr/lib/llvm/18/bin/clang++ --offload-arch=native -x hip vadd_hip.cpp -o vadd_hip -fno-stack-protector --hip-link -fcf-protection=full -nogpulib

error: option 'cf-protection=return' cannot be specified on this target

Although it is possible to use -fcf-protection=full -Xarch_device -fcf-protection=none, to override this, but it is very irritating and it can not be added to all files, as it produces warning: argument unused during compilation: '-Xarch_device -fcf-protection=none' for non-hip files.

In #70799 you added code to "not emit the stack protector metadata on unsupported architectures". Can you do the same for -fcf-protection=..., to apply CET only for host code? Thanks!

@jhuber6
Copy link
Contributor

jhuber6 commented Mar 24, 2024

The stack protector stuff was kind of hacky, I remember some similar case that @yxsamliu and @MaskRay looked into but forget which flag it was.

@AngryLoki
Copy link
Contributor Author

AngryLoki commented Mar 24, 2024

Huh, actually, after submitting this bug, I remembered flag -Xarch_host. So I reported additional bug to Gentoo to consider rewriting /etc/clang/gentoo-hardened.cfg with:

-Xarch_host -fstack-clash-protection
-Xarch_host -fstack-protector-strong
-Xarch_host -fPIE
-include "/usr/include/gentoo/fortify.h"
-Xarch_host -fcf-protection=full

However I still think the best solution is to solve this in Clang. As far as I know, there are already many flags that are not passed to GPU codegen (even turning -O2 into -O3) and -fcf-protection is just one of them.

(edit: fix copy&paste mistake)

@jhuber6
Copy link
Contributor

jhuber6 commented Mar 24, 2024

Huh, actually, after submitting this bug, I remembered flag -Xarch_device. So I reported additional bug to Gentoo to consider rewriting /etc/clang/gentoo-hardened.cfg with:

-Xarch_device -fstack-clash-protection
-Xarch_device -fstack-protector-strong
-Xarch_device -fPIE
-include "/usr/include/gentoo/fortify.h"
-Xarch_device -fcf-protection=full

I'm assuming you mean -Xarch_host? That will apply all of those to the device build.

However I still think the best solution is to solve this in Clang. As far as I know, there are already many flags that are not passed to GPU codegen (even turning -O2 into -O3) and -fcf-protection is just one of them.

Currently we kind of just treat this on a case-by-case basis. There's a lot of pain that come from these single source languages where we try to mash two separate targets into a single compiler invocation. Same problem with all of our numerous hacks around the glibc headers when included from the GPU.

@AngryLoki
Copy link
Contributor Author

I'm assuming you mean -Xarch_host?

Yes, copy&paste mistake.

yretenai added a commit to yretenai/neptune-overlay that referenced this issue Mar 25, 2024
AngryLoki added a commit to AngryLoki/gentoo that referenced this issue Mar 26, 2024
…ags to fix GPU compilation

Add -Xarch_host to CPU-specific flags, so that it does not affects heterogenous code (e. g. HIP).

For stack-protector flags: fixes compiler crashes like llvm/llvm-project#83777
Clang 18.1.0 does not try to apply these flags to GPU code, but current ROCm libraries use Clang 17, so add "-Xarch_host" there too.
This will allow to drop "-fno-stack-protector" patches from rocm-comgr, hip and hipcc eventually.

For -fcf-protection: fixes error: option 'cf-protection=return' cannot be specified on this target.

For -fPIE: do not touch, as at least since Clang 15 it only affects host relocation model.
See also: https://github.com/llvm/llvm-project/blob/llvmorg-15.0.7/clang/test/Driver/hip-fpie-option.hip

Related upstream bug: llvm/llvm-project#86450
Closes: https://bugs.gentoo.org/927752
Signed-off-by: Sv. Lockal <lockalsash@gmail.com>
gentoo-bot pushed a commit to gentoo/gentoo that referenced this issue Mar 26, 2024
Add -Xarch_host to CPU-specific flags, so that it does not affects
heterogenous code (e. g. HIP).

For stack-protector flags: fixes compiler crashes like
llvm/llvm-project#83777.  Clang 18.1.0 does
not try to apply these flags to GPU code, but current ROCm libraries use
Clang 17, so add "-Xarch_host" there too.  This will allow to drop
"-fno-stack-protector" patches from rocm-comgr, hip and hipcc
eventually.

For -fcf-protection: fixes error: option 'cf-protection=return' cannot
be specified on this target.

For -fPIE: do not touch, as at least since Clang 15 it only affects host
relocation model.  See also:
https://github.com/llvm/llvm-project/blob/llvmorg-15.0.7/clang/test/Driver/hip-fpie-option.hip

Bug: llvm/llvm-project#86450
Closes: https://bugs.gentoo.org/927752
Signed-off-by: Sv. Lockal <lockalsash@gmail.com>
Closes: #35926
Signed-off-by: Michał Górny <mgorny@gentoo.org>
@stalkerg
Copy link

stalkerg commented Apr 7, 2024

The same issue with dev-libs/libclc package.

@stalkerg
Copy link

stalkerg commented Apr 9, 2024

@jhuber6
Copy link
Contributor

jhuber6 commented Apr 9, 2024

These things are permanent issues caused by pretending that two separate compilations for two separate architectures is a single compiler invocation. The easiest solution would be the following that simply prevents the option from being forwarded to the offloading device, essentially making it behave like -Xarch_host was always added.

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 766a9b91e3c0..0d19c67778e0 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6866,9 +6866,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (Args.hasArg(options::OPT_nogpulib))
     CmdArgs.push_back("-nogpulib");
 
-  if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
-    CmdArgs.push_back(
-        Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+  if (JA.getOffloadingDeviceKind() == Action::OFK_None) {
+    if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+    }
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ))

However, this would prevent users from enabling it intentionally or overriding that behavior.

@yxsamliu
Copy link
Collaborator

These things are permanent issues caused by pretending that two separate compilations for two separate architectures is a single compiler invocation. The easiest solution would be the following that simply prevents the option from being forwarded to the offloading device, essentially making it behave like -Xarch_host was always added.

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 766a9b91e3c0..0d19c67778e0 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6866,9 +6866,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (Args.hasArg(options::OPT_nogpulib))
     CmdArgs.push_back("-nogpulib");
 
-  if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
-    CmdArgs.push_back(
-        Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+  if (JA.getOffloadingDeviceKind() == Action::OFK_None) {
+    if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+    }
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ))

However, this would prevent users from enabling it intentionally or overriding that behavior.

It seems currently we do not have a better way to handle this. If a target starts to support these options we could re-enable them for that target.

jhuber6 added a commit to jhuber6/llvm-project that referenced this issue Apr 11, 2024
Summary:
This patch prevents the `-fcf-protection=` flag from being passed to the
device compilation during offloading. This is not supported on CUDA and
AMD devices, but if the user is compiling with fcf protection for the
host it will fail to compile.

We have a lot of these cases with various hacked together solutions, it
would be nice to have a single solution to detect from the driver if a
feature like this can be used for offloading, but for now this should
resolve the issue.

Fixe: llvm#86450
jhuber6 added a commit to jhuber6/llvm-project that referenced this issue Apr 11, 2024
Summary:
This patch prevents the `-fcf-protection=` flag from being passed to the
device compilation during offloading. This is not supported on CUDA and
AMD devices, but if the user is compiling with fcf protection for the
host it will fail to compile.

We have a lot of these cases with various hacked together solutions, it
would be nice to have a single solution to detect from the driver if a
feature like this can be used for offloading, but for now this should
resolve the issue.

Fixe: llvm#86450
@arsenm
Copy link
Contributor

arsenm commented Apr 12, 2024

It seems currently we do not have a better way to handle this. If a target starts to support these options we could re-enable them for that target.

We could just implement this, but it's probably not what anyone wants by default. I think we should interpret the flag as host-only, but I think it would be good to allow enabling it specifically for the device

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants