Skip to content

InferAddressSpaces: Handle llvm.fake.use #109567

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
merged 2 commits into from
Oct 9, 2024

Conversation

arsenm
Copy link
Contributor

@arsenm arsenm commented Sep 22, 2024

No description provided.

Copy link
Contributor Author

arsenm commented Sep 22, 2024

This stack of pull requests is managed by Graphite. Learn more about stacking.

Join @arsenm and the rest of your teammates on Graphite Graphite

@arsenm arsenm changed the title InferAddressSpaces: Add llvm.fake.use baseline tests InferAddressSpaces: Handle llvm.fake.use Sep 22, 2024
@arsenm arsenm marked this pull request as ready for review September 22, 2024 07:03
@llvmbot
Copy link
Member

llvmbot commented Sep 22, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Matt Arsenault (arsenm)

Changes

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

2 Files Affected:

  • (modified) llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp (+14)
  • (added) llvm/test/Transforms/InferAddressSpaces/fake-use.ll (+97)
diff --git a/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp b/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp
index 566cdc51f6e74a..60fd2a286119b3 100644
--- a/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp
@@ -414,6 +414,10 @@ bool InferAddressSpacesImpl::rewriteIntrinsicOperands(IntrinsicInst *II,
     II->setCalledFunction(NewDecl);
     return true;
   }
+  case Intrinsic::fake_use: {
+    II->replaceUsesOfWith(OldV, NewV);
+    return true;
+  }
   default: {
     Value *Rewrite = TTI->rewriteIntrinsicWithAddressSpace(II, OldV, NewV);
     if (!Rewrite)
@@ -455,6 +459,16 @@ void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
     appendsFlatAddressExpressionToPostorderStack(II->getArgOperand(1),
                                                  PostorderStack, Visited);
     break;
+  case Intrinsic::fake_use: {
+    for (Value *Op : II->operands()) {
+      if (Op->getType()->isPtrOrPtrVectorTy()) {
+        appendsFlatAddressExpressionToPostorderStack(Op, PostorderStack,
+                                                     Visited);
+      }
+    }
+
+    break;
+  }
   default:
     SmallVector<int, 2> OpIndexes;
     if (TTI->collectFlatAddressOperands(OpIndexes, IID)) {
diff --git a/llvm/test/Transforms/InferAddressSpaces/fake-use.ll b/llvm/test/Transforms/InferAddressSpaces/fake-use.ll
new file mode 100644
index 00000000000000..ad7f621dc40e85
--- /dev/null
+++ b/llvm/test/Transforms/InferAddressSpaces/fake-use.ll
@@ -0,0 +1,97 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=infer-address-spaces -assume-default-is-flat-addrspace %s | FileCheck %s
+
+declare void @llvm.fake.use(...)
+
+@gv = internal addrspace(3) global float 0.0, align 4
+
+define void @one_fake_use(ptr addrspace(1) %global.ptr) {
+; CHECK-LABEL: define void @one_fake_use(
+; CHECK-SAME: ptr addrspace(1) [[GLOBAL_PTR:%.*]]) {
+; CHECK-NEXT:    call void (...) @llvm.fake.use(ptr addrspace(1) [[GLOBAL_PTR]])
+; CHECK-NEXT:    ret void
+;
+  %cast0 = addrspacecast ptr addrspace(1) %global.ptr to ptr
+  call void (...) @llvm.fake.use(ptr %cast0)
+  ret void
+}
+
+define void @one_fake_use_repeat_operands(ptr addrspace(1) %global.ptr) {
+; CHECK-LABEL: define void @one_fake_use_repeat_operands(
+; CHECK-SAME: ptr addrspace(1) [[GLOBAL_PTR:%.*]]) {
+; CHECK-NEXT:    call void (...) @llvm.fake.use(ptr addrspace(1) [[GLOBAL_PTR]], ptr addrspace(1) [[GLOBAL_PTR]])
+; CHECK-NEXT:    ret void
+;
+  %cast0 = addrspacecast ptr addrspace(1) %global.ptr to ptr
+  call void (...) @llvm.fake.use(ptr %cast0, ptr %cast0)
+  ret void
+}
+
+define void @one_fake_use_refers_original_ptr(ptr addrspace(1) %global.ptr) {
+; CHECK-LABEL: define void @one_fake_use_refers_original_ptr(
+; CHECK-SAME: ptr addrspace(1) [[GLOBAL_PTR:%.*]]) {
+; CHECK-NEXT:    call void (...) @llvm.fake.use(ptr addrspace(1) [[GLOBAL_PTR]], ptr addrspace(1) [[GLOBAL_PTR]])
+; CHECK-NEXT:    ret void
+;
+  %cast0 = addrspacecast ptr addrspace(1) %global.ptr to ptr
+  call void (...) @llvm.fake.use(ptr %cast0, ptr addrspace(1) %global.ptr)
+  ret void
+}
+
+define void @multiple_inferrable_fake_use(ptr addrspace(1) %global.ptr0, ptr addrspace(1) %global.ptr1) {
+; CHECK-LABEL: define void @multiple_inferrable_fake_use(
+; CHECK-SAME: ptr addrspace(1) [[GLOBAL_PTR0:%.*]], ptr addrspace(1) [[GLOBAL_PTR1:%.*]]) {
+; CHECK-NEXT:    call void (...) @llvm.fake.use(ptr addrspace(1) [[GLOBAL_PTR0]], ptr addrspace(1) [[GLOBAL_PTR1]])
+; CHECK-NEXT:    ret void
+;
+  %cast0 = addrspacecast ptr addrspace(1) %global.ptr0 to ptr
+  %cast1 = addrspacecast ptr addrspace(1) %global.ptr1 to ptr
+  call void (...) @llvm.fake.use(ptr %cast0, ptr %cast1)
+  ret void
+}
+
+define void @multiple_fake_use_one_inferrable(ptr %flat.ptr0, ptr addrspace(1) %global.ptr1) {
+; CHECK-LABEL: define void @multiple_fake_use_one_inferrable(
+; CHECK-SAME: ptr [[FLAT_PTR0:%.*]], ptr addrspace(1) [[GLOBAL_PTR1:%.*]]) {
+; CHECK-NEXT:    call void (...) @llvm.fake.use(ptr [[FLAT_PTR0]], ptr addrspace(1) [[GLOBAL_PTR1]])
+; CHECK-NEXT:    call void (...) @llvm.fake.use(ptr addrspace(1) [[GLOBAL_PTR1]], ptr [[FLAT_PTR0]])
+; CHECK-NEXT:    ret void
+;
+  %cast1 = addrspacecast ptr addrspace(1) %global.ptr1 to ptr
+  call void (...) @llvm.fake.use(ptr %flat.ptr0, ptr %cast1)
+  call void (...) @llvm.fake.use(ptr %cast1, ptr %flat.ptr0)
+  ret void
+}
+
+define void @vector_of_pointers(<2 x ptr addrspace(1)> %global.ptr) {
+; CHECK-LABEL: define void @vector_of_pointers(
+; CHECK-SAME: <2 x ptr addrspace(1)> [[GLOBAL_PTR:%.*]]) {
+; CHECK-NEXT:    call void (...) @llvm.fake.use(<2 x ptr addrspace(1)> [[GLOBAL_PTR]])
+; CHECK-NEXT:    ret void
+;
+  %cast0 = addrspacecast <2 x ptr addrspace(1)> %global.ptr to <2 x ptr>
+  call void (...) @llvm.fake.use(<2 x ptr> %cast0)
+  ret void
+}
+
+define void @use_global_var() {
+; CHECK-LABEL: define void @use_global_var() {
+; CHECK-NEXT:    call void (...) @llvm.fake.use(ptr addrspace(3) @gv)
+; CHECK-NEXT:    ret void
+;
+  call void (...) @llvm.fake.use(ptr addrspacecast (ptr addrspace(3) @gv to ptr))
+  ret void
+}
+
+define void @use_gep_cast(ptr addrspace(1) %global.ptr) {
+; CHECK-LABEL: define void @use_gep_cast(
+; CHECK-SAME: ptr addrspace(1) [[GLOBAL_PTR:%.*]]) {
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[GLOBAL_PTR]], i64 16
+; CHECK-NEXT:    call void (...) @llvm.fake.use(ptr addrspace(1) [[GEP]], ptr addrspace(1) [[GLOBAL_PTR]])
+; CHECK-NEXT:    ret void
+;
+  %cast0 = addrspacecast ptr addrspace(1) %global.ptr to ptr
+  %gep = getelementptr i8, ptr %cast0, i64 16
+  call void (...) @llvm.fake.use(ptr %gep, ptr %cast0)
+  ret void
+}

Copy link
Contributor

@SLTozer SLTozer left a comment

Choose a reason for hiding this comment

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

Although llvm.fake.use is variadic, it's actually an error to have more than one argument (not enforced in the verifier, I'll add a patch for that) - the variadic type is only used to allow it to be generic, since the expectation is that it can take any type (and we don't want a unique declaration for every type that may be used). The tests can be updated to remove the multiple_ cases, and the code can assume that there is only one operand. Aside from that, this LGTM, acknowledging that I have limited understanding of InferAddressSpaces (but gave the relevant functions a read to make sure the updates make sense).

@arsenm
Copy link
Contributor Author

arsenm commented Sep 23, 2024

Although llvm.fake.use is variadic, it's actually an error to have more than one argument (not enforced in the verifier, I'll add a patch for that)

I do not think this is a reasonable restriction to have. It adds a new constraint any IR pass has to consider. Any of the many flavors of CSE would need to deal with it, for example. If this wants to be a minimally intrusive intrinsic, it needs to have as few constraints as possible

@SLTozer
Copy link
Contributor

SLTozer commented Sep 23, 2024

I do not think this is a reasonable restriction to have.

That might be fine - I'm not the original author so I don't know the justification for the restriction when it was written, but it's likely simply that we never produce fake use intrinsics with more than one argument, and so code that handles it uses the hardcoded assumption that there is one argument; now that this intrinsic is part of upstream LLVM, allowing it to be used as a full variadic would be reasonable unless there are other technical constraints.

@arsenm
Copy link
Contributor Author

arsenm commented Sep 24, 2024

I do not think this is a reasonable restriction to have.

That might be fine - I'm not the original author so I don't know the justification for the restriction when it was written, but it's likely simply that we never produce fake use intrinsics with more than one argument, and so code that handles it uses the hardcoded assumption that there is one argument; now that this intrinsic is part of upstream LLVM, allowing it to be used as a full variadic would be reasonable unless there are other technical constraints.

OK, I misread this. I was interpreting this as a single value cannot appear multiple times in the argument list. If the restriction is only one argument, that's a more reasonable restriction

Copy link
Contributor Author

@arsenm arsenm left a comment

Choose a reason for hiding this comment

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

I'm inclined to go ahead with this, including tests for multiple uses. In the absence of a verifier check this is valid IR that must be handled correctly.

I also still don't see a reason why fake.use would need to have this restriction

Copy link
Contributor

@SLTozer SLTozer left a comment

Choose a reason for hiding this comment

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

I don't think there's a problem with landing this as-is; for full context, the current state of llvm.fake.use is that there is no verifier check to enforce having exactly one operand, but the documentation states that it is an error for it to have more than one operand, and SelectionDAG currently assumes a single operand only.
To my knowledge there's not a principled reason for this to be the case, it just simplified the implementation (particularly around ISel), so I'm fine to make the change for variadic fake uses to be properly supported in a future patch, or else if it turns out to cause problems then the verifier check can be added and the tests that depend on it being variadic can be adjusted or removed.

@arsenm arsenm merged commit fbd2a91 into main Oct 9, 2024
12 checks passed
@arsenm arsenm deleted the users/arsenm/infer-address-spaces-handle-fake-use branch October 9, 2024 05:24
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 9, 2024

LLVM Buildbot has detected a new failure on builder clang-hip-vega20 running on hip-vega20-0 while building llvm at step 3 "annotate".

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

Here is the relevant piece of the build log for the reference
Step 3 (annotate) failure: '../llvm-zorg/zorg/buildbot/builders/annotated/hip-build.sh --jobs=' (failure)
...
[38/40] : && /buildbot/hip-vega20-0/clang-hip-vega20/llvm/bin/clang++ -O3 -DNDEBUG  External/HIP/CMakeFiles/memmove-hip-6.0.2.dir/memmove.hip.o -o External/HIP/memmove-hip-6.0.2  --rocm-path=/buildbot/Externals/hip/rocm-6.0.2 --hip-link -rtlib=compiler-rt -unwindlib=libgcc -frtlib-add-rpath && cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP && /usr/local/bin/cmake -E create_symlink /buildbot/llvm-test-suite/External/HIP/memmove.reference_output /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/memmove.reference_output-hip-6.0.2
[39/40] /buildbot/hip-vega20-0/clang-hip-vega20/llvm/bin/clang++ -DNDEBUG  -O3 -DNDEBUG   -w -Werror=date-time --rocm-path=/buildbot/Externals/hip/rocm-6.0.2 --offload-arch=gfx908 --offload-arch=gfx90a --offload-arch=gfx1030 --offload-arch=gfx1100 -xhip -mfma -MD -MT External/HIP/CMakeFiles/TheNextWeek-hip-6.0.2.dir/workload/ray-tracing/TheNextWeek/main.cc.o -MF External/HIP/CMakeFiles/TheNextWeek-hip-6.0.2.dir/workload/ray-tracing/TheNextWeek/main.cc.o.d -o External/HIP/CMakeFiles/TheNextWeek-hip-6.0.2.dir/workload/ray-tracing/TheNextWeek/main.cc.o -c /buildbot/llvm-test-suite/External/HIP/workload/ray-tracing/TheNextWeek/main.cc
[40/40] : && /buildbot/hip-vega20-0/clang-hip-vega20/llvm/bin/clang++ -O3 -DNDEBUG  External/HIP/CMakeFiles/TheNextWeek-hip-6.0.2.dir/workload/ray-tracing/TheNextWeek/main.cc.o -o External/HIP/TheNextWeek-hip-6.0.2  --rocm-path=/buildbot/Externals/hip/rocm-6.0.2 --hip-link -rtlib=compiler-rt -unwindlib=libgcc -frtlib-add-rpath && cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP && /usr/local/bin/cmake -E create_symlink /buildbot/llvm-test-suite/External/HIP/TheNextWeek.reference_output /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/TheNextWeek.reference_output-hip-6.0.2
+ build_step 'Testing HIP test-suite'
+ echo '@@@BUILD_STEP Testing HIP test-suite@@@'
@@@BUILD_STEP Testing HIP test-suite@@@
+ ninja -v check-hip-simple
[0/1] cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP && /buildbot/hip-vega20-0/clang-hip-vega20/llvm/bin/llvm-lit -sv empty-hip-6.0.2.test with-fopenmp-hip-6.0.2.test saxpy-hip-6.0.2.test memmove-hip-6.0.2.test InOneWeekend-hip-6.0.2.test TheNextWeek-hip-6.0.2.test blender.test
-- Testing: 7 tests, 7 workers --
Testing:  0.. 10.. 20.. 30.. 40
FAIL: test-suite :: External/HIP/InOneWeekend-hip-6.0.2.test (4 of 7)
******************** TEST 'test-suite :: External/HIP/InOneWeekend-hip-6.0.2.test' FAILED ********************

/buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/tools/timeit-target --timeout 7200 --limit-core 0 --limit-cpu 7200 --limit-file-size 209715200 --limit-rss-size 838860800 --append-exitstatus --redirect-output /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/Output/InOneWeekend-hip-6.0.2.test.out --redirect-input /dev/null --summary /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/Output/InOneWeekend-hip-6.0.2.test.time /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/InOneWeekend-hip-6.0.2
cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP ; /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/tools/fpcmp-target /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/Output/InOneWeekend-hip-6.0.2.test.out InOneWeekend.reference_output-hip-6.0.2

+ cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP
+ /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/tools/fpcmp-target /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/Output/InOneWeekend-hip-6.0.2.test.out InOneWeekend.reference_output-hip-6.0.2
/buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/tools/fpcmp-target: Comparison failed, textual difference between 'M' and 'i'

Input 1:
Memory access fault by GPU node-1 (Agent handle: 0x5617a9f09ac0) on address (nil). Reason: Page not present or supervisor privilege.
exit 134

Input 2:
image width = 1200 height = 675
block size = (16, 16) grid size = (75, 43)
Start rendering by GPU.
Done.
gpu.ppm and ref.ppm are the same.
exit 0

********************
/usr/bin/strip: /bin/bash.stripped: Bad file descriptor
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
********************
Failed Tests (1):
  test-suite :: External/HIP/InOneWeekend-hip-6.0.2.test


Testing Time: 369.93s

Total Discovered Tests: 7
  Passed: 6 (85.71%)
  Failed: 1 (14.29%)
FAILED: External/HIP/CMakeFiles/check-hip-simple-hip-6.0.2 
cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP && /buildbot/hip-vega20-0/clang-hip-vega20/llvm/bin/llvm-lit -sv empty-hip-6.0.2.test with-fopenmp-hip-6.0.2.test saxpy-hip-6.0.2.test memmove-hip-6.0.2.test InOneWeekend-hip-6.0.2.test TheNextWeek-hip-6.0.2.test blender.test
ninja: build stopped: subcommand failed.
Step 12 (Testing HIP test-suite) failure: Testing HIP test-suite (failure)
@@@BUILD_STEP Testing HIP test-suite@@@
+ ninja -v check-hip-simple
[0/1] cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP && /buildbot/hip-vega20-0/clang-hip-vega20/llvm/bin/llvm-lit -sv empty-hip-6.0.2.test with-fopenmp-hip-6.0.2.test saxpy-hip-6.0.2.test memmove-hip-6.0.2.test InOneWeekend-hip-6.0.2.test TheNextWeek-hip-6.0.2.test blender.test
-- Testing: 7 tests, 7 workers --
Testing:  0.. 10.. 20.. 30.. 40
FAIL: test-suite :: External/HIP/InOneWeekend-hip-6.0.2.test (4 of 7)
******************** TEST 'test-suite :: External/HIP/InOneWeekend-hip-6.0.2.test' FAILED ********************

/buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/tools/timeit-target --timeout 7200 --limit-core 0 --limit-cpu 7200 --limit-file-size 209715200 --limit-rss-size 838860800 --append-exitstatus --redirect-output /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/Output/InOneWeekend-hip-6.0.2.test.out --redirect-input /dev/null --summary /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/Output/InOneWeekend-hip-6.0.2.test.time /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/InOneWeekend-hip-6.0.2
cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP ; /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/tools/fpcmp-target /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/Output/InOneWeekend-hip-6.0.2.test.out InOneWeekend.reference_output-hip-6.0.2

+ cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP
+ /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/tools/fpcmp-target /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP/Output/InOneWeekend-hip-6.0.2.test.out InOneWeekend.reference_output-hip-6.0.2
/buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/tools/fpcmp-target: Comparison failed, textual difference between 'M' and 'i'

Input 1:
Memory access fault by GPU node-1 (Agent handle: 0x5617a9f09ac0) on address (nil). Reason: Page not present or supervisor privilege.
exit 134

Input 2:
image width = 1200 height = 675
block size = (16, 16) grid size = (75, 43)
Start rendering by GPU.
Done.
gpu.ppm and ref.ppm are the same.
exit 0

********************
/usr/bin/strip: /bin/bash.stripped: Bad file descriptor
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
********************
Failed Tests (1):
  test-suite :: External/HIP/InOneWeekend-hip-6.0.2.test


Testing Time: 369.93s

Total Discovered Tests: 7
  Passed: 6 (85.71%)
  Failed: 1 (14.29%)
FAILED: External/HIP/CMakeFiles/check-hip-simple-hip-6.0.2 
cd /buildbot/hip-vega20-0/clang-hip-vega20/test-suite-build/External/HIP && /buildbot/hip-vega20-0/clang-hip-vega20/llvm/bin/llvm-lit -sv empty-hip-6.0.2.test with-fopenmp-hip-6.0.2.test saxpy-hip-6.0.2.test memmove-hip-6.0.2.test InOneWeekend-hip-6.0.2.test TheNextWeek-hip-6.0.2.test blender.test
ninja: build stopped: subcommand failed.
program finished with exit code 1
elapsedTime=482.517785

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.

4 participants