https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/109323

>From f4d72ce6faca5498f184069b7c5d22841a449e74 Mon Sep 17 00:00:00 2001
From: Sarah Spall <sp...@planetbauer.com>
Date: Wed, 18 Sep 2024 22:19:07 +0000
Subject: [PATCH 1/3] enable array by value assignment

---
 clang/include/clang/AST/CanonicalType.h |  1 +
 clang/lib/AST/ExprClassification.cpp    |  3 ++-
 clang/lib/Sema/SemaOverload.cpp         | 11 ++++++++---
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/CanonicalType.h 
b/clang/include/clang/AST/CanonicalType.h
index dde08f0394c98d..6102eb01793530 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -299,6 +299,7 @@ class CanProxyBase {
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantArrayType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
diff --git a/clang/lib/AST/ExprClassification.cpp 
b/clang/lib/AST/ExprClassification.cpp
index 5dde923312698f..9d97633309ada2 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -704,7 +704,8 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, 
const Expr *E,
     return Cl::CM_ConstAddrSpace;
 
   // Arrays are not modifiable, only their elements are.
-  if (CT->isArrayType())
+  if (CT->isArrayType() &&
+      !(Ctx.getLangOpts().HLSL && CT->isConstantArrayType()))
     return Cl::CM_ArrayType;
   // Incomplete types are not modifiable.
   if (CT->isIncompleteType())
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 0c1e054f7c30a4..2cde8131108fbe 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -2232,16 +2232,21 @@ static bool IsStandardConversion(Sema &S, Expr* From, 
QualType ToType,
     // just strip the qualifiers because they don't matter.
     FromType = FromType.getUnqualifiedType();
   } else if (S.getLangOpts().HLSL && FromType->isConstantArrayType() &&
-             ToType->isArrayParameterType()) {
+             ToType->isConstantArrayType()) {
     // HLSL constant array parameters do not decay, so if the argument is a
     // constant array and the parameter is an ArrayParameterType we have 
special
     // handling here.
-    FromType = S.Context.getArrayParameterType(FromType);
+    if (ToType->isArrayParameterType()) {
+      FromType = S.Context.getArrayParameterType(FromType);
+      SCS.First = ICK_HLSL_Array_RValue;
+    } else {
+      SCS.First = ICK_Identity;
+    }
+
     if (S.Context.getCanonicalType(FromType) !=
         S.Context.getCanonicalType(ToType))
       return false;
 
-    SCS.First = ICK_HLSL_Array_RValue;
     SCS.setAllToTypes(ToType);
     return true;
   } else if (FromType->isArrayType()) {

>From 76c7a7d2be4427b7660773566f203ba56ec573b2 Mon Sep 17 00:00:00 2001
From: Sarah Spall <sp...@planetbauer.com>
Date: Thu, 19 Sep 2024 19:33:39 +0000
Subject: [PATCH 2/3] test assignable arrays

---
 clang/test/AST/HLSL/ArrayAssignable.hlsl      | 80 +++++++++++++++++++
 clang/test/CodeGenHLSL/ArrayAssignable.hlsl   | 50 ++++++++++++
 .../test/SemaHLSL/ArrayAssignable_errors.hlsl | 29 +++++++
 3 files changed, 159 insertions(+)
 create mode 100644 clang/test/AST/HLSL/ArrayAssignable.hlsl
 create mode 100644 clang/test/CodeGenHLSL/ArrayAssignable.hlsl
 create mode 100644 clang/test/SemaHLSL/ArrayAssignable_errors.hlsl

diff --git a/clang/test/AST/HLSL/ArrayAssignable.hlsl 
b/clang/test/AST/HLSL/ArrayAssignable.hlsl
new file mode 100644
index 00000000000000..52c9918aa85334
--- /dev/null
+++ b/clang/test/AST/HLSL/ArrayAssignable.hlsl
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump %s 
| FileCheck %s
+
+// CHECK-LABEL: arr_assign1
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[A]] 'Arr' 
'int[2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[B]] 'Arr2' 
'int[2]'
+void arr_assign1() {
+  int Arr[2] = {0, 1};
+  int Arr2[2] = {0, 0};
+  Arr = Arr2;
+}
+
+// CHECK-LABEL: arr_assign2
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[C:0x[0-9a-f]+]] {{.*}} col:7 used Arr3 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 2
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 2
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[A]] 'Arr' 
'int[2]'
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[B]] 'Arr2' 
'int[2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[C]] 'Arr3' 
'int[2]'
+void arr_assign2() {
+  int Arr[2] = {0, 1};
+  int Arr2[2] = {0, 0};
+  int Arr3[2] = {2, 2};
+  Arr = Arr2 = Arr3;
+}
+
+// CHECK-LABEL: arr_assign3
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2][2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]'
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 2
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 3
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2][2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]'
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue Var [[A]] 
'Arr' 'int[2][2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue Var [[B]] 
'Arr2' 'int[2][2]'
+void arr_assign3() {
+  int Arr[2][2] = {{0, 1}, {2, 3}};
+  int Arr2[2][2] = {{0, 0}, {1, 1}};
+  Arr = Arr2;
+}
\ No newline at end of file
diff --git a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl 
b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl
new file mode 100644
index 00000000000000..769154df2bfb43
--- /dev/null
+++ b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm 
-disable-llvm-passes -o - %s | FileCheck %s --enable-var-scope
+
+// CHECK-LABEL: define void {{.*}}arr_assign1
+// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr]], i32 8, i1 false)
+// CHECK: ret void
+void arr_assign1() {
+  int Arr[2] = {0, 1};
+  int Arr2[2] = {0, 0};
+  Arr = Arr2;
+}
+
+// CHECK-LABEL: define void {{.*}}arr_assign2
+// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr3:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr2]], ptr align 4 
[[Arr3]], i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr]], i32 8, i1 false)
+// CHECK: ret void
+void arr_assign2() {
+  int Arr[2] = {0, 1};
+  int Arr2[2] = {0, 0};
+  int Arr3[2] = {3, 4};
+  Arr = Arr2 = Arr3;
+}
+
+// CHECK-LABEL: define void {{.*}}arr_assign3
+// CHECK: [[Arr3:%.*]] = alloca [2 x [2 x i32]], align 4
+// CHECK: [[Arr4:%.*]] = alloca [2 x [2 x i32]], align 4
+// CHECK: [[Tmp:%.*]] = alloca [2 x [2 x i32]], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
{{@.*}}, i32 16, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr4]], ptr align 4 
{{@.*}}, i32 16, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
[[Arr4]], i32 16, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr3]], i32 16, i1 false)
+// CHECK: ret void
+void arr_assign3() {
+  int Arr2[2][2] = {{0, 0}, {1, 1}};
+  int Arr3[2][2] = {{1, 1}, {0, 0}};
+  Arr2 = Arr3;
+}
diff --git a/clang/test/SemaHLSL/ArrayAssignable_errors.hlsl 
b/clang/test/SemaHLSL/ArrayAssignable_errors.hlsl
new file mode 100644
index 00000000000000..1925032a93d488
--- /dev/null
+++ b/clang/test/SemaHLSL/ArrayAssignable_errors.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -verify
+
+void test_wrong_size1() {
+  int Arr[2] = {0, 1};
+  int Arr2[3] = {1, 2, 0};
+  Arr = Arr2;
+  // expected-error@-1 {{assigning to 'int[2]' from incompatible type 
'int[3]'}}
+}
+
+void test_wrong_size2() {
+  int Arr[2] = {0, 1};
+  int Arr2[3] = {1, 2, 0};
+  Arr2 = Arr;
+  // expected-error@-1 {{assigning to 'int[3]' from incompatible type 
'int[2]'}}
+}
+
+void test_wrong_size3() {
+  int Arr[2][2] = {{0, 1}, {2, 3}};
+  int Arr2[2] = {4, 5};
+  Arr = Arr2;
+  // expected-error@-1 {{assigning to 'int[2][2]' from incompatible type 
'int[2]'}}
+}
+
+void test_wrong_size4() {
+  int Arr[2][2] = {{0, 1}, {2, 3}};
+  int Arr2[2] = {4, 5};
+  Arr2 = Arr;
+  // expected-error@-1 {{assigning to 'int[2]' from incompatible type 
'int[2][2]'}}
+}

>From 49db43d9c55f062aba09b72e3f3a075ee1466d11 Mon Sep 17 00:00:00 2001
From: Sarah Spall <sp...@planetbauer.com>
Date: Fri, 27 Sep 2024 14:49:55 +0000
Subject: [PATCH 3/3] c++ ish

---
 clang/lib/CodeGen/CGExpr.cpp                |  15 +++
 clang/lib/CodeGen/CodeGenFunction.h         |   1 +
 clang/test/AST/HLSL/ArrayAssignable.hlsl    | 139 +++++++++++++++++++-
 clang/test/CodeGenHLSL/ArrayAssignable.hlsl |  75 ++++++++++-
 4 files changed, 223 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index df4994ba9af6e1..aaaa4c7cbf2aec 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5797,11 +5797,26 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
     return EmitComplexAssignmentLValue(E);
 
   case TEK_Aggregate:
+    // If the lang opt is HLSL and the LHS is a constant array
+    // then we are performing a copy assignment and call a special
+    // function because EmitAggExprToLValue emits to a temporary LValue
+    if (getLangOpts().HLSL && E->getLHS()->getType()->isConstantArrayType())
+      return EmitHLSLArrayAssignLValue(E);
+
     return EmitAggExprToLValue(E);
   }
   llvm_unreachable("bad evaluation kind");
 }
 
+// This function implements trivial copy assignment for HLSL's
+// assignable constant arrays.
+LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {
+  LValue TrivialAssignmentRHS = EmitLValue(E->getRHS());
+  LValue LHS = EmitLValue(E->getLHS());
+  EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS()->getType());
+  return LHS;
+}
+
 LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E,
                                            llvm::CallBase **CallOrInvoke) {
   RValue RV = EmitCallExpr(E, ReturnValueSlot(), CallOrInvoke);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 3e2abbd9bc1094..9ba0ed02a564dd 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4296,6 +4296,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   LValue EmitCastLValue(const CastExpr *E);
   LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
   LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
+  LValue EmitHLSLArrayAssignLValue(const BinaryOperator *E);
   void EmitHLSLOutArgExpr(const HLSLOutArgExpr *E, CallArgList &Args,
                           QualType Ty);
 
diff --git a/clang/test/AST/HLSL/ArrayAssignable.hlsl 
b/clang/test/AST/HLSL/ArrayAssignable.hlsl
index 52c9918aa85334..49caa8968c8a6b 100644
--- a/clang/test/AST/HLSL/ArrayAssignable.hlsl
+++ b/clang/test/AST/HLSL/ArrayAssignable.hlsl
@@ -77,4 +77,141 @@ void arr_assign3() {
   int Arr[2][2] = {{0, 1}, {2, 3}};
   int Arr2[2][2] = {{0, 0}, {1, 1}};
   Arr = Arr2;
-}
\ No newline at end of file
+}
+
+// CHECK-LABEL: arr_assign4
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int' lvalue '='
+// CHECK: ArraySubscriptExpr 0x{{[0-9a-f]+}} {{.*}} 'int' lvalue
+// CHECK: ImplicitCastExpr 0x{{[0-9a-f]+}} {{.*}} 'int *' <ArrayToPointerDecay>
+// CHECK: ParenExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[A]] 'Arr' 
'int[2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[B]] 'Arr2' 
'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 6
+void arr_assign4() {
+  int Arr[2] = {0, 1};
+  int Arr2[2] = {0, 0};
+  (Arr = Arr2)[0] = 6;
+}
+
+// CHECK-LABEL: arr_assign5
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[C:0x[0-9a-f]+]] {{.*}} col:7 used Arr3 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 3
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 4
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int' lvalue '='
+// CHECK: ArraySubscriptExpr 0x{{[0-9a-f]+}} {{.*}} 'int' lvalue
+// CHECK: ImplicitCastExpr 0x{{[0-9a-f]+}} {{.*}} 'int *' <ArrayToPointerDecay>
+// CHECK: ParenExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[A]] 'Arr' 
'int[2]'
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[B]] 'Arr2' 
'int[2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[C]] 'Arr3' 
'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 6
+void arr_assign5() {
+  int Arr[2] = {0, 1};
+  int Arr2[2] = {0, 0};
+  int Arr3[2] = {3, 4};
+  (Arr = Arr2 = Arr3)[0] = 6;
+}
+
+// CHECK-LABEL: arr_assign6
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2][2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]'
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 2
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 3
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2][2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]'
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int' lvalue '='
+// CHECK: ArraySubscriptExpr 0x{{[0-9a-f]+}} {{.*}} 'int' lvalue
+// CHECK: ImplicitCastExpr 0x{{[0-9a-f]+}} {{.*}} 'int *' <ArrayToPointerDecay>
+// CHECK: ArraySubscriptExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue
+// CHECK: ImplicitCastExpr 0x{{[0-9a-f]+}} {{.*}} 'int (*)[2]' 
<ArrayToPointerDecay>
+// CHECK: ParenExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue Var [[A]] 
'Arr' 'int[2][2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue Var [[B]] 
'Arr2' 'int[2][2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 6
+void arr_assign6() {
+  int Arr[2][2] = {{0, 1}, {2, 3}};
+  int Arr2[2][2] = {{0, 0}, {1, 1}};
+  (Arr = Arr2)[0][0] = 6;
+}
+
+// CHECK-LABEL: arr_assign7
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2][2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]'
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 2
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 3
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2][2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]'
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: ArraySubscriptExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue
+// CHECK: ImplicitCastExpr 0x{{[0-9a-f]+}} {{.*}} 'int (*)[2]' 
<ArrayToPointerDecay>
+// CHECK: ParenExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue Var [[A]] 
'Arr' 'int[2][2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2][2]' lvalue Var [[B]] 
'Arr2' 'int[2][2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 6
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 6
+void arr_assign7() {
+  int Arr[2][2] = {{0, 1}, {2, 3}};
+  int Arr2[2][2] = {{0, 0}, {1, 1}};
+  (Arr = Arr2)[0] = {6, 6};
+}
diff --git a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl 
b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl
index 769154df2bfb43..53ac378608cc78 100644
--- a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl
+++ b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl
@@ -3,11 +3,9 @@
 // CHECK-LABEL: define void {{.*}}arr_assign1
 // CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
 // CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
-// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
 // CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
-// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr]], i32 8, i1 false)
 // CHECK: ret void
 void arr_assign1() {
   int Arr[2] = {0, 1};
@@ -19,13 +17,11 @@ void arr_assign1() {
 // CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
 // CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
 // CHECK: [[Arr3:%.*]] = alloca [2 x i32], align 4
-// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
 // CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
{{@.*}}, i32 8, i1 false)
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr2]], ptr align 4 
[[Arr3]], i32 8, i1 false)
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
-// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr]], i32 8, i1 false)
 // CHECK: ret void
 void arr_assign2() {
   int Arr[2] = {0, 1};
@@ -37,14 +33,81 @@ void arr_assign2() {
 // CHECK-LABEL: define void {{.*}}arr_assign3
 // CHECK: [[Arr3:%.*]] = alloca [2 x [2 x i32]], align 4
 // CHECK: [[Arr4:%.*]] = alloca [2 x [2 x i32]], align 4
-// CHECK: [[Tmp:%.*]] = alloca [2 x [2 x i32]], align 4
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
{{@.*}}, i32 16, i1 false)
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr4]], ptr align 4 
{{@.*}}, i32 16, i1 false)
 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
[[Arr4]], i32 16, i1 false)
-// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr3]], i32 16, i1 false)
 // CHECK: ret void
 void arr_assign3() {
   int Arr2[2][2] = {{0, 0}, {1, 1}};
   int Arr3[2][2] = {{1, 1}, {0, 0}};
   Arr2 = Arr3;
 }
+
+// CHECK-LABEL: define void {{.*}}arr_assign4
+// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
+// CHECK: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[Arr]], i32 0, 
i32 0
+// CHECK: store i32 6, ptr [[Idx]], align 4
+// CHECK: ret void
+void arr_assign4() {
+  int Arr[2] = {0, 1};
+  int Arr2[2] = {0, 0};
+  (Arr = Arr2)[0] = 6;
+}
+
+// CHECK-LABEL: define void {{.*}}arr_assign5
+// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr3:%.*]] = alloca [2 x i32], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr2]], ptr align 4 
[[Arr3]], i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
+// CHECK: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[Arr]], i32 0, 
i32 0
+// CHECK: store i32 6, ptr [[Idx]], align 4
+// CHECK: ret void
+void arr_assign5() {
+  int Arr[2] = {0, 1};
+  int Arr2[2] = {0, 0};
+  int Arr3[2] = {3, 4};
+  (Arr = Arr2 = Arr3)[0] = 6;
+}
+
+// CHECK-LABEL: define void {{.*}}arr_assign6
+// CHECK: [[Arr3:%.*]] = alloca [2 x [2 x i32]], align 4
+// CHECK: [[Arr4:%.*]] = alloca [2 x [2 x i32]], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
{{@.*}}, i32 16, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr4]], ptr align 4 
{{@.*}}, i32 16, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
[[Arr4]], i32 16, i1 false)
+// CHECK: [[Idx:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[Arr3]], 
i32 0, i32 0
+// CHECK: [[Idx2:%.*]] = getelementptr inbounds [2 x i32], ptr [[Idx]], i32 0, 
i32 0
+// CHECK: store i32 6, ptr [[Idx2]], align 4
+// CHECK: ret void
+void arr_assign6() {
+  int Arr[2][2] = {{0, 0}, {1, 1}};
+  int Arr2[2][2] = {{1, 1}, {0, 0}};
+  (Arr = Arr2)[0][0] = 6;
+}
+
+// CHECK-LABEL: define void {{.*}}arr_assign7
+// CHECK: [[Arr3:%.*]] = alloca [2 x [2 x i32]], align 4
+// CHECK: [[Arr4:%.*]] = alloca [2 x [2 x i32]], align 4
+// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
{{@.*}}, i32 16, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr4]], ptr align 4 
{{@.*}}, i32 16, i1 false)
+// CHECK: store i32 6, ptr [[Tmp]], align 4
+// CHECK: [[AIE:%.*]] = getelementptr inbounds i32, ptr [[Tmp]], i32 1
+// CHECK: store i32 6, ptr [[AIE]], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr3]], ptr align 4 
[[Arr4]], i32 16, i1 false)
+// CHECK: [[Idx:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[Arr3]], 
i32 0, i32 0
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Idx]], ptr align 4 
[[Tmp]], i32 8, i1 false)
+// CHECK: ret void
+void arr_assign7() {
+  int Arr[2][2] = {{0, 1}, {2, 3}};
+  int Arr2[2][2] = {{0, 0}, {1, 1}};
+  (Arr = Arr2)[0] = {6, 6};
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to