[llvm] 28c5a2c - [Clang][HLSL][GVN] Prevent phi codgen of isTokenLike types (#162363)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 10 12:38:28 PDT 2025


Author: Farzon Lotfi
Date: 2025-10-10T15:38:24-04:00
New Revision: 28c5a2c46d810b70040b711afbb2532374a5b67d

URL: https://github.com/llvm/llvm-project/commit/28c5a2c46d810b70040b711afbb2532374a5b67d
DIFF: https://github.com/llvm/llvm-project/commit/28c5a2c46d810b70040b711afbb2532374a5b67d.diff

LOG: [Clang][HLSL][GVN] Prevent phi codgen of isTokenLike types (#162363)

fixes #161754

When the GVN pass calls `PerformLoadPRE` or `processNonLocalLoad` it can
invoke the `SSAUpdater` which adds a phi node for our tokenLike type. If
we check for if the load is on a token like type at the `processLoad` we
can cover both cases. This is because if we don't GVN will use the
SSAUpdater to insert a phi node to reduce duplicate resource.getpointer
calls.

Because in an earlier commit:
https://github.com/llvm/llvm-project/commit/01c0a8409a21344c822deba9467bd9d547f6e5d8
we made the verifier error with `PHI nodes cannot have token type!`

This test case will fail today if we try to perform this load
optimization
https://godbolt.org/z/xM69fY8zM

This will impact clang aswell because `isTokenLikeTy` also checks for
`isTokenTy` Clang is likely also failing validation with token types but
just doesn't have a test case because the validator would error if it
were in a phi node.

Added: 
    llvm/test/Transforms/GVN/PRE/no-pre-load-for-token-like.ll

Modified: 
    llvm/lib/Transforms/Scalar/GVN.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 3a8ade8051bbd..42db42402a7c3 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -2156,6 +2156,9 @@ bool GVNPass::processLoad(LoadInst *L) {
   if (!L->isUnordered())
     return false;
 
+  if (L->getType()->isTokenLikeTy())
+    return false;
+
   if (L->use_empty()) {
     salvageAndRemoveInstruction(L);
     return true;

diff  --git a/llvm/test/Transforms/GVN/PRE/no-pre-load-for-token-like.ll b/llvm/test/Transforms/GVN/PRE/no-pre-load-for-token-like.ll
new file mode 100644
index 0000000000000..1b36aba6bca09
--- /dev/null
+++ b/llvm/test/Transforms/GVN/PRE/no-pre-load-for-token-like.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=gvn %s | FileCheck %s
+
+; NOTE: A test to confirm GVN doesn't collapse loads of token-like types into
+; NOTE: phi nodes.
+
+define ptr @main() {
+; CHECK-LABEL: define ptr @main() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br i1 false, label %[[ENTRY_IF_END_I_CRIT_EDGE:.*]], label %[[IF_THEN_I:.*]]
+; CHECK:       [[ENTRY_IF_END_I_CRIT_EDGE]]:
+; CHECK-NEXT:    br label %[[IF_END_I:.*]]
+; CHECK:       [[IF_THEN_I]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = load target("dx.RawBuffer", half, 1, 0), ptr null, align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f16_1_0t(target("dx.RawBuffer", half, 1, 0) [[TMP0]], i32 0)
+; CHECK-NEXT:    br label %[[IF_END_I]]
+; CHECK:       [[IF_END_I]]:
+; CHECK-NEXT:    [[TMP2:%.*]] = load target("dx.RawBuffer", half, 1, 0), ptr null, align 4
+; CHECK-NEXT:    [[TMP3:%.*]] = tail call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f16_1_0t(target("dx.RawBuffer", half, 1, 0) [[TMP2]], i32 0)
+; CHECK-NEXT:    ret ptr [[TMP3]]
+;
+entry:
+  br i1 false, label %if.end.i, label %if.then.i
+
+if.then.i:                                        ; preds = %entry
+  %0 = load target("dx.RawBuffer", half, 1, 0), ptr null, align 4
+  %1 = tail call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f16_1_0t(target("dx.RawBuffer", half, 1, 0) %0, i32 0)
+  br label %if.end.i
+
+if.end.i:                                         ; preds = %if.then.i, %entry
+  %2 = load target("dx.RawBuffer", half, 1, 0), ptr null, align 4
+  %3 = tail call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f16_1_0t(target("dx.RawBuffer", half, 1, 0) %2, i32 0)
+  ret ptr %3
+}


        


More information about the llvm-commits mailing list