Skip to content

Conversation

s-perron
Copy link
Contributor

@s-perron s-perron commented Sep 3, 2025

The OpaqueValueVisitor was not correctly traversing the AST to find all
OpaqueValueExprs. This resulted in some expressions not being correctly
initialized. This change fixes the visitor to correctly traverse the AST.

Fixes #156786

The OpaqueValueVisitor was not correctly traversing the AST to find all
OpaqueValueExprs. This resulted in some expressions not being correctly
initialized. This change fixes the visitor to correctly traverse the AST.

A test for this change will be included as part of the work in
llvm#156075.

See discussion in
https://github.com/llvm/llvm-project/pull/156075/files#r2317231524.
@s-perron s-perron requested a review from hekota September 3, 2025 20:14
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. HLSL HLSL Language Support labels Sep 3, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 3, 2025

@llvm/pr-subscribers-hlsl

@llvm/pr-subscribers-clang

Author: Steven Perron (s-perron)

Changes

The OpaqueValueVisitor was not correctly traversing the AST to find all
OpaqueValueExprs. This resulted in some expressions not being correctly
initialized. This change fixes the visitor to correctly traverse the AST.

A test for this change will be included as part of the work in
#156075.

See discussion in
https://github.com/llvm/llvm-project/pull/156075/files#r2317231524.


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

1 Files Affected:

  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+18-2)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 442d8505cc0ed..c5660bc518712 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -828,11 +828,27 @@ llvm::Instruction *CGHLSLRuntime::getConvergenceToken(BasicBlock &BB) {
 
 class OpaqueValueVisitor : public RecursiveASTVisitor<OpaqueValueVisitor> {
 public:
-  llvm::SmallPtrSet<OpaqueValueExpr *, 8> OVEs;
+  llvm::SmallVector<OpaqueValueExpr *, 8> OVEs;
+  llvm::SmallPtrSet<OpaqueValueExpr *, 8> Visited;
   OpaqueValueVisitor() {}
 
+  bool VisitHLSLOutArgExpr(HLSLOutArgExpr *) {
+    // These need to be bound in CodeGenFunction::EmitHLSLOutArgLValues
+    // or CodeGenFunction::EmitHLSLOutArgExpr. If they are part of this
+    // traversal, the temporary containing the copy out will not have
+    // been created yet.
+    return false;
+  }
+
   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
-    OVEs.insert(E);
+    // Traverse the source expression first.
+    if (E->getSourceExpr())
+      TraverseStmt(E->getSourceExpr());
+
+    // Then add this OVE if we haven't seen it before.
+    if (Visited.insert(E).second)
+      OVEs.push_back(E);
+
     return true;
   }
 };

@llvmbot
Copy link
Member

llvmbot commented Sep 3, 2025

@llvm/pr-subscribers-clang-codegen

Author: Steven Perron (s-perron)

Changes

The OpaqueValueVisitor was not correctly traversing the AST to find all
OpaqueValueExprs. This resulted in some expressions not being correctly
initialized. This change fixes the visitor to correctly traverse the AST.

A test for this change will be included as part of the work in
#156075.

See discussion in
https://github.com/llvm/llvm-project/pull/156075/files#r2317231524.


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

1 Files Affected:

  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+18-2)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 442d8505cc0ed..c5660bc518712 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -828,11 +828,27 @@ llvm::Instruction *CGHLSLRuntime::getConvergenceToken(BasicBlock &BB) {
 
 class OpaqueValueVisitor : public RecursiveASTVisitor<OpaqueValueVisitor> {
 public:
-  llvm::SmallPtrSet<OpaqueValueExpr *, 8> OVEs;
+  llvm::SmallVector<OpaqueValueExpr *, 8> OVEs;
+  llvm::SmallPtrSet<OpaqueValueExpr *, 8> Visited;
   OpaqueValueVisitor() {}
 
+  bool VisitHLSLOutArgExpr(HLSLOutArgExpr *) {
+    // These need to be bound in CodeGenFunction::EmitHLSLOutArgLValues
+    // or CodeGenFunction::EmitHLSLOutArgExpr. If they are part of this
+    // traversal, the temporary containing the copy out will not have
+    // been created yet.
+    return false;
+  }
+
   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
-    OVEs.insert(E);
+    // Traverse the source expression first.
+    if (E->getSourceExpr())
+      TraverseStmt(E->getSourceExpr());
+
+    // Then add this OVE if we haven't seen it before.
+    if (Visited.insert(E).second)
+      OVEs.push_back(E);
+
     return true;
   }
 };

Copy link
Member

@hekota hekota left a comment

Choose a reason for hiding this comment

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

You should probably remove the XFAIL from clang/test/CodeGenHLSL/BasicFeatures/InitLists.hls as part of this change.

@s-perron s-perron requested a review from hekota September 8, 2025 20:05
Copy link
Member

@hekota hekota left a comment

Choose a reason for hiding this comment

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

LGTM!

@s-perron
Copy link
Contributor Author

s-perron commented Sep 9, 2025

Failure are unrelated to my change. I can see the same failures on other PRs.

@s-perron s-perron merged commit f587e00 into llvm:main Sep 9, 2025
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category HLSL HLSL Language Support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[HLSL] OVE as a subexpression of an OVE is not properly handled
3 participants