Skip to content

[NVPTX] Don't use underlying alignment to align param #96793

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

Merged

Conversation

hdelan
Copy link

@hdelan hdelan commented Jun 26, 2024

Previously, if a ptr had align N, then the NVPTX lowering was taking this align N to refer to the alignment of the pointer type itself, as opposed to the alignment of the memory that it points to.

As such, if a kernel with signature

define void @foo(ptr align 4 %_arg_ptr)

takes align 4 to be the alignment of the parameter, this would result in breaking the ld.param into two separate loads like so:

	ld.param.u32 	%rd1, [foo_param_0+4];
	shl.b64 	%rd2, %rd1, 32;
	ld.param.u32 	%rd3, [foo_param_0];
	or.b64  	%rd4, %rd2, %rd3;

It isn't necessary as far as I can tell from the PTX ISA documents to specify the alignment of params, nor to break the loading of params into smaller loads based on their alignment. So this patch changes the codegen to the better:

	ld.param.u64 	%rd1, [foo_param_0];

Ping @frasercrmck @ldrumm

@llvmbot
Copy link
Member

llvmbot commented Jun 26, 2024

@llvm/pr-subscribers-backend-nvptx

Author: Hugh Delaney (hdelan)

Changes

Previously, if a ptr had align N, then the NVPTX lowering was taking this align N to refer to the alignment of the pointer type itself, as opposed to the alignment of the memory that it points to.

As such, if a kernel of the form:

define void @<!-- -->foo(ptr align 4 %_arg_ptr)

Would take align 4 to be the alignment of the parameter, which would result in breaking the ld.param into two separate loads.

	ld.param.u32 	%rd1, [foo_param_0+4];
	shl.b64 	%rd2, %rd1, 32;
	ld.param.u32 	%rd3, [foo_param_0];
	or.b64  	%rd4, %rd2, %rd3;

It isn't necessary as far as I can tell from the PTX ISA documents to specify the alignment of the parameters themselves. So this patch changes the codegen to the better:

	ld.param.u64 	%rd1, [foo_param_0];

Ping @frasercrmck @ldrumm


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

2 Files Affected:

  • (modified) llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp (+1-3)
  • (modified) llvm/test/CodeGen/NVPTX/param-align.ll (+36)
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
index 982c191875750..63cbdb0acfab6 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -3232,9 +3232,7 @@ SDValue NVPTXTargetLowering::LowerFormalArguments(
             if (NumElts != 1)
               return std::nullopt;
             Align PartAlign =
-                (Offsets[parti] == 0 && PAL.getParamAlignment(i))
-                    ? PAL.getParamAlignment(i).value()
-                    : DL.getABITypeAlign(EltVT.getTypeForEVT(F->getContext()));
+                DL.getABITypeAlign(EltVT.getTypeForEVT(F->getContext()));
             return commonAlignment(PartAlign, Offsets[parti]);
           }();
           SDValue P = DAG.getLoad(VecVT, dl, Root, VecAddr,
diff --git a/llvm/test/CodeGen/NVPTX/param-align.ll b/llvm/test/CodeGen/NVPTX/param-align.ll
index 5435ee238c88d..6ef284aa4b5eb 100644
--- a/llvm/test/CodeGen/NVPTX/param-align.ll
+++ b/llvm/test/CodeGen/NVPTX/param-align.ll
@@ -69,3 +69,39 @@ define ptx_device void @t6() {
   call void %fp(ptr byval(i8) null);
   ret void
 }
+
+; CHECK: .func check_ptr_align1(
+; CHECK: 	ld.param.u64 	%rd1
+; CHECK: 	ret;
+define void @check_ptr_align1(ptr align 1 %_arg_ptr) {
+entry:
+  store i32 1, ptr %_arg_ptr, align 1
+  ret void
+}
+
+; CHECK: .func check_ptr_align2(
+; CHECK: 	ld.param.u64 	%rd1
+; CHECK: 	ret;
+define void @check_ptr_align2(ptr align 2 %_arg_ptr) {
+entry:
+  store i32 2, ptr %_arg_ptr, align 2
+  ret void
+}
+
+; CHECK: .func check_ptr_align4(
+; CHECK: 	ld.param.u64 	%rd1
+; CHECK: 	ret;
+define void @check_ptr_align4(ptr align 4 %_arg_ptr) {
+entry:
+  store i32 4, ptr %_arg_ptr, align 4
+  ret void
+}
+
+; CHECK: .func check_ptr_align8(
+; CHECK: 	ld.param.u64 	%rd1
+; CHECK: 	ret;
+define void @check_ptr_align8(ptr align 8 %_arg_ptr) {
+entry:
+  store i32 8, ptr %_arg_ptr, align 8
+  ret void
+}

@hdelan
Copy link
Author

hdelan commented Jun 26, 2024

Ping for review, please @Artem-B @AlexMaclean

Copy link
Member

@jlebar jlebar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo the comments already here. Nice catch.

@hdelan hdelan force-pushed the dont-align-ptr-on-underlying-alignment branch 2 times, most recently from 24af04f to f84714b Compare June 26, 2024 16:37
Previously, if a ptr had align N, then the NVPTX lowering was taking
this align N to refer to the alignment of the pointer type itself, as
opposed to the alignment of the memory that it points to.

As such, if a kernel of the form:

define void @foo(ptr align 4 %_arg_ptr)

Would take align 4 to be the alignment of the parameter, which would
result in breaking the ld.param into two separate loads.

	ld.param.u32 	%rd1, [foo_param_0+4];
	shl.b64 	%rd2, %rd1, 32;
	ld.param.u32 	%rd3, [foo_param_0];
	or.b64  	%rd4, %rd2, %rd3;

It isn't necessary as far as I can tell from the PTX ISA documents to
specify the alignment of the parameters themselves. So this patch
changes the codegen to the better:

	ld.param.u64 	%rd1, [foo_param_0];
@hdelan hdelan force-pushed the dont-align-ptr-on-underlying-alignment branch from f84714b to 4d7d9c6 Compare June 26, 2024 16:42
@AlexMaclean
Copy link
Member

LGTM

@frasercrmck frasercrmck merged commit 6c2f5d6 into llvm:main Jun 27, 2024
7 checks passed
@hdelan hdelan deleted the dont-align-ptr-on-underlying-alignment branch June 27, 2024 09:19
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jun 27, 2024

LLVM Buildbot has detected a new failure on builder clangd-ubuntu-tsan running on clangd-ubuntu-clang while building llvm at step 6 "test-build-clangd-clangd-index-server-clangd-indexer-check-clangd".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/134/builds/733

Here is the relevant piece of the build log for the reference:

Step 6 (test-build-clangd-clangd-index-server-clangd-indexer-check-clangd) failure: test (failure)
******************** TEST 'Clangd :: target_info.test' FAILED ********************
Exit Code: 66

Command Output (stderr):
--
RUN: at line 5: rm -rf /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir && mkdir -p /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir
+ rm -rf /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir
+ mkdir -p /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir
RUN: at line 7: echo '[{"directory": "/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir", "command": "/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir/armv7-clang -x c++ the-file.cpp -v", "file": "the-file.cpp"}]' > /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir/compile_commands.json
+ echo '[{"directory": "/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir", "command": "/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir/armv7-clang -x c++ the-file.cpp -v", "file": "the-file.cpp"}]'
RUN: at line 9: sed -e "s|INPUT_DIR|/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir|g" /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/llvm-project/clang-tools-extra/clangd/test/target_info.test > /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.test.1
+ sed -e 's|INPUT_DIR|/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.dir|g' /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/llvm-project/clang-tools-extra/clangd/test/target_info.test
RUN: at line 12: sed -E -e 's|"file://([A-Z]):/|"file:///\1:/|g' /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.test.1 > /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.test
+ sed -E -e 's|"file://([A-Z]):/|"file:///\1:/|g' /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.test.1
RUN: at line 14: clangd -lit-test < /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.test 2>&1 | /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/bin/FileCheck -strict-whitespace /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.test
+ clangd -lit-test
+ /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/bin/FileCheck -strict-whitespace /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/tools/clang/tools/extra/clangd/test/Output/target_info.test.tmp.test

--

********************


lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
Previously, if a ptr had align N, then the NVPTX lowering was taking
this align N to refer to the alignment of the pointer type itself, as
opposed to the alignment of the memory that it points to.

As such, if a kernel with signature

```
define void @foo(ptr align 4 %_arg_ptr)
```

takes align 4 to be the alignment of the parameter, this would result in
breaking the ld.param into two separate loads like so:

```
	ld.param.u32 	%rd1, [foo_param_0+4];
	shl.b64 	%rd2, %rd1, 32;
	ld.param.u32 	%rd3, [foo_param_0];
	or.b64  	%rd4, %rd2, %rd3;
```

It isn't necessary as far as I can tell from the PTX ISA documents to
specify the alignment of params, nor to break the loading of params into
smaller loads based on their alignment. So this patch changes the
codegen to the better:

```
	ld.param.u64 	%rd1, [foo_param_0];
```
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
Previously, if a ptr had align N, then the NVPTX lowering was taking
this align N to refer to the alignment of the pointer type itself, as
opposed to the alignment of the memory that it points to.

As such, if a kernel with signature

```
define void @foo(ptr align 4 %_arg_ptr)
```

takes align 4 to be the alignment of the parameter, this would result in
breaking the ld.param into two separate loads like so:

```
	ld.param.u32 	%rd1, [foo_param_0+4];
	shl.b64 	%rd2, %rd1, 32;
	ld.param.u32 	%rd3, [foo_param_0];
	or.b64  	%rd4, %rd2, %rd3;
```

It isn't necessary as far as I can tell from the PTX ISA documents to
specify the alignment of params, nor to break the loading of params into
smaller loads based on their alignment. So this patch changes the
codegen to the better:

```
	ld.param.u64 	%rd1, [foo_param_0];
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants