[clang] 9fac59a - [HLSL] Allow arrays to be returned by value in HLSL (#127896)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 24 11:51:07 PST 2025
Author: Sarah Spall
Date: 2025-02-24T11:51:01-08:00
New Revision: 9fac59a0db7c7adaa354a47df385cd35d761ec77
URL: https://github.com/llvm/llvm-project/commit/9fac59a0db7c7adaa354a47df385cd35d761ec77
DIFF: https://github.com/llvm/llvm-project/commit/9fac59a0db7c7adaa354a47df385cd35d761ec77.diff
LOG: [HLSL] Allow arrays to be returned by value in HLSL (#127896)
Enable Arrays to be returned in HLSL, and a test for this.
Closes #126568
Added:
clang/test/CodeGenHLSL/BasicFeatures/ArrayReturn.hlsl
Modified:
clang/include/clang/Basic/LangOptions.h
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaType.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 651b3b67b1058..34d75aff43fab 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -816,6 +816,8 @@ class LangOptions : public LangOptionsBase {
VisibilityForcedKinds::ForceHidden;
}
+ bool allowArrayReturnTypes() const { return HLSL; }
+
/// Remap path prefix according to -fmacro-prefix-path option.
void remapPathPrefix(SmallVectorImpl<char> &Path) const;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 316a59cb80e60..1738663327453 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -20679,7 +20679,8 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) {
const FunctionType *FnType = CalleeType->castAs<FunctionType>();
// Verify that this is a legal result type of a function.
- if (DestType->isArrayType() || DestType->isFunctionType()) {
+ if ((DestType->isArrayType() && !S.getLangOpts().allowArrayReturnTypes()) ||
+ DestType->isFunctionType()) {
unsigned diagID = diag::err_func_returning_array_function;
if (Kind == FK_BlockPointer)
diagID = diag::err_block_returning_array_function;
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index db0177f9750e0..60096eebfdb6f 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2530,7 +2530,8 @@ QualType Sema::BuildMatrixType(QualType ElementTy, Expr *NumRows, Expr *NumCols,
}
bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {
- if (T->isArrayType() || T->isFunctionType()) {
+ if ((T->isArrayType() && !getLangOpts().allowArrayReturnTypes()) ||
+ T->isFunctionType()) {
Diag(Loc, diag::err_func_returning_array_function)
<< T->isFunctionType() << T;
return true;
@@ -4934,7 +4935,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// C99 6.7.5.3p1: The return type may not be a function or array type.
// For conversion functions, we'll diagnose this particular error later.
- if (!D.isInvalidType() && (T->isArrayType() || T->isFunctionType()) &&
+ if (!D.isInvalidType() &&
+ ((T->isArrayType() && !S.getLangOpts().allowArrayReturnTypes()) ||
+ T->isFunctionType()) &&
(D.getName().getKind() !=
UnqualifiedIdKind::IK_ConversionFunctionId)) {
unsigned diagID = diag::err_func_returning_array_function;
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/ArrayReturn.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/ArrayReturn.hlsl
new file mode 100644
index 0000000000000..832c4ac9b10f5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/BasicFeatures/ArrayReturn.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s
+
+typedef int Foo[2];
+
+// CHECK-LABEL: define void {{.*}}boop{{.*}}(ptr dead_on_unwind noalias writable sret([2 x i32]) align 4 %agg.result)
+// CHECK: [[G:%.*]] = alloca [2 x i32], align 4
+// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[G]], ptr align 4 {{.*}}, i32 8, i1 false)
+// CHECK-NEXT: [[AIB:%.*]] = getelementptr inbounds [2 x i32], ptr %agg.result, i32 0, i32 0
+// CHECK-NEXT: br label %arrayinit.body
+// CHECK: arrayinit.body:
+// CHECK-NEXT: [[AII:%.*]] = phi i32 [ 0, %entry ], [ %arrayinit.next, %arrayinit.body ]
+// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds i32, ptr [[AIB]], i32 [[AII]]
+// CHECK-NEXT: [[AI:%.*]] = getelementptr inbounds nuw [2 x i32], ptr [[G]], i32 0, i32 [[AII]]
+// CHECK-NEXT: [[Y:%.*]] = load i32, ptr [[AI]], align 4
+// CHECK-NEXT: store i32 [[Y]], ptr [[X]], align 4
+// CHECK-NEXT: [[AIN:%.*]] = add nuw i32 [[AII]], 1
+// CHECK-NEXT: [[AID:%.*]] = icmp eq i32 [[AIN]], 2
+// CHECK-NEXT: br i1 [[AID]], label %arrayinit.end, label %arrayinit.body
+// CHECK: arrayinit.end:
+// CHECK-NEXT: ret void
+export Foo boop() {
+ Foo G = {1,2};
+ return G;
+}
+
+// CHECK-LABEL: define void {{.*}}foo{{.*}}(ptr dead_on_unwind noalias writable sret([2 x i32]) align 4 %agg.result)
+// CHECK: store i32 1, ptr %agg.result, align 4
+// CHECK-NEXT: [[E:%.*]] = getelementptr inbounds i32, ptr %agg.result, i32 1
+// CHECK-NEXT: store i32 2, ptr [[E]], align 4
+// CHECK-NEXT: ret void
+export int foo()[2] {
+ return {1,2};
+}
More information about the cfe-commits
mailing list