llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Sarah Spall (spall)

<details>
<summary>Changes</summary>

Currently, which is not demonstrated through any existing tests
The following code produces the following AST and IR
```
struct Empty {
};

export void call12(Empty E1) {
  Empty E3 = {E1};
}
```
AST:
```
FunctionDecl {{.*}} used call12 'void (Empty)'
|-ParmVarDecl {{.*}} used E1 'Empty'
`-CompoundStmt 
  `-DeclStmt
    `-VarDecl {{.*}} E3 'Empty' cinit
      `-CXXConstructExpr {{.*}} 'Empty' 'void (const Empty &amp;) noexcept' list
        `-ImplicitCastExpr {{.*}} 'const Empty' lvalue &lt;NoOp&gt;
          `-DeclRefExpr {{.*}} 'Empty' lvalue ParmVar {{.*}} 'E1' 'Empty'
```
IR:
```
%struct.Empty = type { i8 }

define void @<!-- -->call12(Empty)(ptr noundef byval(%struct.Empty) align 1 
%E1) #<!-- -->0 !dbg !11 {
entry:
  %E3 = alloca %struct.Empty, align 1
  ret void, !dbg !23
}
```
The InitListExpr returned by HLSL's transformInitList contains E1 so E3 is 
initialized using the copy constructor.  

The change this PR introduces is making 
```
Empty E3 = {E1};
```
equivalent to
```
Empty E3 = {};
```
which will perform list initialization instead which will work better with 
removing constructors from HLSL.

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


3 Files Affected:

- (modified) clang/lib/Sema/SemaHLSL.cpp (+3-1) 
- (modified) clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl (+18) 
- (modified) clang/test/SemaHLSL/Language/InitListAST.hlsl (+27) 


``````````diff
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 0619295cd2fbb..0037982662bcc 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -5681,8 +5681,10 @@ bool SemaHLSL::transformInitList(const InitializedEntity 
&Entity,
   }
   size_t ExpectedSize = ILT.DestTypes.size();
   size_t ActualSize = ILT.ArgExprs.size();
-  if (ExpectedSize == 0 && ActualSize == 0)
+  if (ExpectedSize == 0 && ActualSize == 0) {
+    Init->resizeInits(Ctx, 0);
     return true;
+  }
 
   // Reject empty initializer if *any* incomplete array exists structurally
   if (ActualSize == 0 && containsIncompleteArrayType(Entity.getType())) {
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl 
b/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl
index b785a033b7ca7..5d395744af1ba 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl
@@ -1126,6 +1126,24 @@ void case26(TwoInts TI) {
   float4 F = float4(TI, 1, 2);
   float3 F2 = float3(3, TI);
 }
+
+// CHECK-LABEL: define hidden void @_Z6case275Empty
+// CHECK: [[E1:%.*]] = alloca %struct.Empty, align 1
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[E1]], ptr align 1 
@__const._Z6case275Empty.E1, i32 1, i1 false)
+// CHECK: ret void
+void case27(Empty E) {
+  Empty E1 = {E};
+  // This is equivalent to Empty E1 = {};
+}
+
+// CHECK-LABEL: define hidden void @_Z6case2811UnnamedOnly
+// CHECK: [[UO2:%.*]] = alloca %struct.UnnamedOnly, align 1
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[UO2]], ptr align 1 
@__const._Z6case2811UnnamedOnly.UO2, i32 1, i1 false)
+// CHECK: ret void
+void case28(UnnamedOnly UO) {
+  UnnamedOnly UO2 = {UO};
+  // This is equivalent to UnnamedOnly UO2 = {};
+}
 //.
 // CHECK: [[META3]] = !{}
 // CHECK: [[META4]] = !{i64 4}
diff --git a/clang/test/SemaHLSL/Language/InitListAST.hlsl 
b/clang/test/SemaHLSL/Language/InitListAST.hlsl
index 460ec38bb44af..faf81d8ffb84d 100644
--- a/clang/test/SemaHLSL/Language/InitListAST.hlsl
+++ b/clang/test/SemaHLSL/Language/InitListAST.hlsl
@@ -49,6 +49,13 @@ struct SlicyBits {
   int W : 8;
 };
 
+struct Empty {
+};
+
+struct UnnamedOnly {
+  int : 8;
+};
+
 // Case 1: Extraneous braces get ignored in literal instantiation.
 // CHECK-LABEL: Dumping case1
 // CHECK: VarDecl {{.*}} used TF1 'TwoFloats' nrvo cinit
@@ -1059,3 +1066,23 @@ float case17() {
   float Floats[] = {Structs, Structs};
   return Floats[7];
 }
+
+// CHECK-LABEL: Dumping case18
+// CHECK: ParmVarDecl {{.*}} used E 'Empty'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: DeclStmt
+// CHECK-NEXT: VarDecl {{.*}} E1 'Empty' cinit
+// CHECK-NEXT: InitListExpr {{.*}} 'Empty'
+void case18(Empty E) {
+  Empty E1 = {E};
+}
+
+// CHECK-LABEL: Dumping case19
+// CHECK: ParmVarDecl {{.*}} used UO 'UnnamedOnly'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: DeclStmt
+// CHECK-NEXT: VarDecl {{.*}} UO2 'UnnamedOnly' cinit
+// CHECK-NEXT: InitListExpr {{.*}} 'UnnamedOnly'
+void case19(UnnamedOnly UO) {
+  UnnamedOnly UO2 = {UO};
+}
\ No newline at end of file

``````````

</details>


https://github.com/llvm/llvm-project/pull/187773
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to