Skip to content

Commit 28c5a2c

Browse files
authored
[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: 01c0a84 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.
1 parent bd3ddcf commit 28c5a2c

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,6 +2156,9 @@ bool GVNPass::processLoad(LoadInst *L) {
21562156
if (!L->isUnordered())
21572157
return false;
21582158

2159+
if (L->getType()->isTokenLikeTy())
2160+
return false;
2161+
21592162
if (L->use_empty()) {
21602163
salvageAndRemoveInstruction(L);
21612164
return true;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
2+
; RUN: opt -S -passes=gvn %s | FileCheck %s
3+
4+
; NOTE: A test to confirm GVN doesn't collapse loads of token-like types into
5+
; NOTE: phi nodes.
6+
7+
define ptr @main() {
8+
; CHECK-LABEL: define ptr @main() {
9+
; CHECK-NEXT: [[ENTRY:.*:]]
10+
; CHECK-NEXT: br i1 false, label %[[ENTRY_IF_END_I_CRIT_EDGE:.*]], label %[[IF_THEN_I:.*]]
11+
; CHECK: [[ENTRY_IF_END_I_CRIT_EDGE]]:
12+
; CHECK-NEXT: br label %[[IF_END_I:.*]]
13+
; CHECK: [[IF_THEN_I]]:
14+
; CHECK-NEXT: [[TMP0:%.*]] = load target("dx.RawBuffer", half, 1, 0), ptr null, align 4
15+
; 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)
16+
; CHECK-NEXT: br label %[[IF_END_I]]
17+
; CHECK: [[IF_END_I]]:
18+
; CHECK-NEXT: [[TMP2:%.*]] = load target("dx.RawBuffer", half, 1, 0), ptr null, align 4
19+
; 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)
20+
; CHECK-NEXT: ret ptr [[TMP3]]
21+
;
22+
entry:
23+
br i1 false, label %if.end.i, label %if.then.i
24+
25+
if.then.i: ; preds = %entry
26+
%0 = load target("dx.RawBuffer", half, 1, 0), ptr null, align 4
27+
%1 = tail call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f16_1_0t(target("dx.RawBuffer", half, 1, 0) %0, i32 0)
28+
br label %if.end.i
29+
30+
if.end.i: ; preds = %if.then.i, %entry
31+
%2 = load target("dx.RawBuffer", half, 1, 0), ptr null, align 4
32+
%3 = tail call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f16_1_0t(target("dx.RawBuffer", half, 1, 0) %2, i32 0)
33+
ret ptr %3
34+
}

0 commit comments

Comments
 (0)