https://github.com/hekota created 
https://github.com/llvm/llvm-project/pull/191605

When aggregate types appear as _prvalues_ in HLSL initializer lists, convert 
them to _xvalues_ and wrap them in `OpaqueValueExpr` so their temporaries can 
be reused across all element accesses. This allows code generation to avoid 
emitting redundant copies of the same aggregate temporary.

This should be especially helpful once support for constructors on user-defined 
structs is removed, and initializer lists will be the primary mechanism for 
struct initialization.

A similar optimization may also be applicable to vector and matrix types. 
However, their current code generation path does not yet support handling 
`OpaqueValueExpr` in initializer lists.

>From 9a9249637f54ad5c1d3aad538c30e13bc8a0e0e3 Mon Sep 17 00:00:00 2001
From: Helena Kotas <[email protected]>
Date: Fri, 10 Apr 2026 22:31:00 -0700
Subject: [PATCH] [HLSL] Reuse temporaries of aggregate types in list
 initialization

When aggregate types appear as prvalues in HLSL initializer lists, convert them 
to xvalues and wrap them in OpaqueExpr so their temporaries can be reused 
across all element accesses. This allows code generation to avoid emitting 
redundant copies of the same aggregate temporary.
---
 clang/lib/Sema/SemaHLSL.cpp                   | 17 ++++--
 .../CodeGenHLSL/BasicFeatures/InitLists.hlsl  | 53 ++-----------------
 clang/test/SemaHLSL/Language/InitListAST.hlsl | 10 ++++
 3 files changed, 27 insertions(+), 53 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index a943303149931..d56bf1cfc43d7 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -5728,6 +5728,18 @@ class InitListTransformer {
         Ty->isHLSLAttributedResourceType())
       return castInitializer(E);
 
+    // If this is an aggregate type and a prvalue, create an xvalue temporary
+    // so the member accesses will be xvalues. Wrap it in OpaqueExpr top make
+    // sure codegen will not generate duplicate copies. 
+    if (E->isPRValue() && Ty->isAggregateType()) {
+      ExprResult TmpExpr = S.TemporaryMaterializationConversion(E);
+      if (TmpExpr.isInvalid())
+        return false;
+      E = TmpExpr.get();
+      E = new (Ctx) OpaqueValueExpr(E->getBeginLoc(), Ty, E->getValueKind(),
+                                    E->getObjectKind(), E);
+    }
+
     if (auto *VecTy = Ty->getAs<VectorType>()) {
       uint64_t Size = VecTy->getNumElements();
 
@@ -5793,11 +5805,6 @@ class InitListTransformer {
     if (auto *RD = Ty->getAsCXXRecordDecl()) {
       llvm::SmallVector<CXXRecordDecl *> RecordDecls;
       RecordDecls.push_back(RD);
-      // If this is a prvalue create an xvalue so the member accesses
-      // will be xvalues.
-      if (E->isPRValue())
-        E = new (Ctx)
-            MaterializeTemporaryExpr(Ty, E, /*BoundToLvalueReference=*/false);
       while (RecordDecls.back()->getNumBases()) {
         CXXRecordDecl *D = RecordDecls.back();
         assert(D->getNumBases() == 1 &&
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl 
b/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl
index 9c42da8962c2d..68050ddfe00d4 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl
@@ -1155,9 +1155,6 @@ void case27(CustomResource a) {
 // CHECK-NEXT:    [[TI:%.*]] = alloca [[STRUCT_TWOINTS:%.*]], align 1
 // CHECK-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_TWOINTS]], align 1
 // CHECK-NEXT:    [[AGG_TEMP:%.*]] = alloca [[STRUCT_TWOFLOATS]], align 1
-// CHECK-NEXT:    [[REF_TMP6:%.*]] = alloca [[STRUCT_TWOINTS]], align 1
-// CHECK-NEXT:    [[AGG_TEMP7:%.*]] = alloca [[STRUCT_TWOFLOATS]], align 1
-// CHECK-NEXT:    [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[TI]], i32 0, i32 0
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_TEMP]], 
ptr align 1 [[TF]], i32 8, i1 false)
 // CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_TWOINTS]], ptr 
[[REF_TMP]], i32 0, i32 0
 // CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_TWOINTS]], 
ptr [[REF_TMP]], i32 0, i32 1
@@ -1169,22 +1166,12 @@ void case27(CustomResource a) {
 // CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[GEP3]], align 4
 // CHECK-NEXT:    [[CONV4:%.*]] = fptosi float [[TMP1]] to i32
 // CHECK-NEXT:    store i32 [[CONV4]], ptr [[GEP1]], align 4
+// CHECK-NEXT:    [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[TI]], i32 0, i32 0
 // CHECK-NEXT:    [[Z5:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[REF_TMP]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z5]], align 1
 // CHECK-NEXT:    store i32 [[TMP2]], ptr [[Z]], align 1
 // CHECK-NEXT:    [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[TI]], i32 0, i32 1
-// CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_TEMP7]], 
ptr align 1 [[TF]], i32 8, i1 false)
-// CHECK-NEXT:    [[GEP8:%.*]] = getelementptr inbounds [[STRUCT_TWOINTS]], 
ptr [[REF_TMP6]], i32 0, i32 0
-// CHECK-NEXT:    [[GEP9:%.*]] = getelementptr inbounds [[STRUCT_TWOINTS]], 
ptr [[REF_TMP6]], i32 0, i32 1
-// CHECK-NEXT:    [[GEP10:%.*]] = getelementptr inbounds [[STRUCT_TWOFLOATS]], 
ptr [[AGG_TEMP7]], i32 0, i32 0
-// CHECK-NEXT:    [[GEP11:%.*]] = getelementptr inbounds [[STRUCT_TWOFLOATS]], 
ptr [[AGG_TEMP7]], i32 0, i32 1
-// CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[GEP10]], align 4
-// CHECK-NEXT:    [[CONV12:%.*]] = fptosi float [[TMP3]] to i32
-// CHECK-NEXT:    store i32 [[CONV12]], ptr [[GEP8]], align 4
-// CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[GEP11]], align 4
-// CHECK-NEXT:    [[CONV13:%.*]] = fptosi float [[TMP4]] to i32
-// CHECK-NEXT:    store i32 [[CONV13]], ptr [[GEP9]], align 4
-// CHECK-NEXT:    [[W14:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[REF_TMP6]], i32 0, i32 1
+// CHECK-NEXT:    [[W14:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[REF_TMP]], i32 0, i32 1
 // CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[W14]], align 1
 // CHECK-NEXT:    store i32 [[TMP5]], ptr [[W]], align 1
 // CHECK-NEXT:    ret void
@@ -1199,8 +1186,6 @@ void case28(TwoFloats TF) {
 // CHECK-NEXT:    [[INTS:%.*]] = alloca [2 x i32], align 4
 // CHECK-NEXT:    [[REF_TMP:%.*]] = alloca [2 x i32], align 4
 // CHECK-NEXT:    [[AGG_TEMP:%.*]] = alloca [[STRUCT_FOURFLOATS]], align 1
-// CHECK-NEXT:    [[REF_TMP7:%.*]] = alloca [2 x i32], align 4
-// CHECK-NEXT:    [[AGG_TEMP8:%.*]] = alloca [[STRUCT_FOURFLOATS]], align 1
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_TEMP]], 
ptr align 1 [[FF]], i32 16, i1 false)
 // CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [2 x i32], ptr 
[[REF_TMP]], i32 0, i32 0
 // CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds [2 x i32], ptr 
[[REF_TMP]], i32 0, i32 1
@@ -1218,20 +1203,7 @@ void case28(TwoFloats TF) {
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
 // CHECK-NEXT:    store i32 [[TMP2]], ptr [[INTS]], align 4
 // CHECK-NEXT:    [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr 
[[INTS]], i32 1
-// CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_TEMP8]], 
ptr align 1 [[FF]], i32 16, i1 false)
-// CHECK-NEXT:    [[GEP9:%.*]] = getelementptr inbounds [2 x i32], ptr 
[[REF_TMP7]], i32 0, i32 0
-// CHECK-NEXT:    [[GEP10:%.*]] = getelementptr inbounds [2 x i32], ptr 
[[REF_TMP7]], i32 0, i32 1
-// CHECK-NEXT:    [[GEP11:%.*]] = getelementptr inbounds 
[[STRUCT_FOURFLOATS]], ptr [[AGG_TEMP8]], i32 0, i32 0, i32 0
-// CHECK-NEXT:    [[GEP12:%.*]] = getelementptr inbounds 
[[STRUCT_FOURFLOATS]], ptr [[AGG_TEMP8]], i32 0, i32 0, i32 1
-// CHECK-NEXT:    [[GEP13:%.*]] = getelementptr inbounds 
[[STRUCT_FOURFLOATS]], ptr [[AGG_TEMP8]], i32 0, i32 1
-// CHECK-NEXT:    [[GEP14:%.*]] = getelementptr inbounds 
[[STRUCT_FOURFLOATS]], ptr [[AGG_TEMP8]], i32 0, i32 2
-// CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[GEP11]], align 4
-// CHECK-NEXT:    [[CONV15:%.*]] = fptosi float [[TMP3]] to i32
-// CHECK-NEXT:    store i32 [[CONV15]], ptr [[GEP9]], align 4
-// CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[GEP12]], align 4
-// CHECK-NEXT:    [[CONV16:%.*]] = fptosi float [[TMP4]] to i32
-// CHECK-NEXT:    store i32 [[CONV16]], ptr [[GEP10]], align 4
-// CHECK-NEXT:    [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw [2 x i32], 
ptr [[REF_TMP7]], i32 0, i32 1
+// CHECK-NEXT:    [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw [2 x i32], 
ptr [[REF_TMP]], i32 0, i32 1
 // CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX17]], align 4
 // CHECK-NEXT:    store i32 [[TMP5]], ptr [[ARRAYINIT_ELEMENT]], align 4
 // CHECK-NEXT:    ret void
@@ -1247,10 +1219,7 @@ void case29(FourFloats FF) {
 // CHECK-NEXT:    [[TI:%.*]] = alloca [[STRUCT_TWOINTS:%.*]], align 1
 // CHECK-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_TWOINTS]], align 1
 // CHECK-NEXT:    [[AGG_TEMP:%.*]] = alloca [4 x float], align 4
-// CHECK-NEXT:    [[REF_TMP8:%.*]] = alloca [[STRUCT_TWOINTS]], align 1
-// CHECK-NEXT:    [[AGG_TEMP9:%.*]] = alloca [4 x float], align 4
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[ARR]], ptr 
align 4 @__const._Z6case30v.Arr, i32 16, i1 false)
-// CHECK-NEXT:    [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[TI]], i32 0, i32 0
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TEMP]], 
ptr align 4 [[ARR]], i32 16, i1 false)
 // CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_TWOINTS]], ptr 
[[REF_TMP]], i32 0, i32 0
 // CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_TWOINTS]], 
ptr [[REF_TMP]], i32 0, i32 1
@@ -1264,24 +1233,12 @@ void case29(FourFloats FF) {
 // CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[GEP3]], align 4
 // CHECK-NEXT:    [[CONV6:%.*]] = fptosi float [[TMP1]] to i32
 // CHECK-NEXT:    store i32 [[CONV6]], ptr [[GEP1]], align 4
+// CHECK-NEXT:    [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[TI]], i32 0, i32 0
 // CHECK-NEXT:    [[Z7:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[REF_TMP]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z7]], align 1
 // CHECK-NEXT:    store i32 [[TMP2]], ptr [[Z]], align 1
 // CHECK-NEXT:    [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[TI]], i32 0, i32 1
-// CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TEMP9]], 
ptr align 4 [[ARR]], i32 16, i1 false)
-// CHECK-NEXT:    [[GEP10:%.*]] = getelementptr inbounds [[STRUCT_TWOINTS]], 
ptr [[REF_TMP8]], i32 0, i32 0
-// CHECK-NEXT:    [[GEP11:%.*]] = getelementptr inbounds [[STRUCT_TWOINTS]], 
ptr [[REF_TMP8]], i32 0, i32 1
-// CHECK-NEXT:    [[GEP12:%.*]] = getelementptr inbounds [4 x float], ptr 
[[AGG_TEMP9]], i32 0, i32 0
-// CHECK-NEXT:    [[GEP13:%.*]] = getelementptr inbounds [4 x float], ptr 
[[AGG_TEMP9]], i32 0, i32 1
-// CHECK-NEXT:    [[GEP14:%.*]] = getelementptr inbounds [4 x float], ptr 
[[AGG_TEMP9]], i32 0, i32 2
-// CHECK-NEXT:    [[GEP15:%.*]] = getelementptr inbounds [4 x float], ptr 
[[AGG_TEMP9]], i32 0, i32 3
-// CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[GEP12]], align 4
-// CHECK-NEXT:    [[CONV16:%.*]] = fptosi float [[TMP3]] to i32
-// CHECK-NEXT:    store i32 [[CONV16]], ptr [[GEP10]], align 4
-// CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[GEP13]], align 4
-// CHECK-NEXT:    [[CONV17:%.*]] = fptosi float [[TMP4]] to i32
-// CHECK-NEXT:    store i32 [[CONV17]], ptr [[GEP11]], align 4
-// CHECK-NEXT:    [[W18:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[REF_TMP8]], i32 0, i32 1
+// CHECK-NEXT:    [[W18:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], 
ptr [[REF_TMP]], i32 0, i32 1
 // CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[W18]], align 1
 // CHECK-NEXT:    store i32 [[TMP5]], ptr [[W]], align 1
 // CHECK-NEXT:    ret void
diff --git a/clang/test/SemaHLSL/Language/InitListAST.hlsl 
b/clang/test/SemaHLSL/Language/InitListAST.hlsl
index 63e6af61b124a..62acaf3046548 100644
--- a/clang/test/SemaHLSL/Language/InitListAST.hlsl
+++ b/clang/test/SemaHLSL/Language/InitListAST.hlsl
@@ -1069,14 +1069,17 @@ float case17() {
 // CHECK-NEXT: FloatingLiteral {{.*}} 'float' 2.000000e+00
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl {{.*}} used TI 'TwoInts' cinit
+// CHECK-NEXT: ExprWithCleanups {{.*}} 'TwoInts'
 // CHECK-NEXT: InitListExpr {{.*}} 'TwoInts'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT: MemberExpr {{.*}} 'int' xvalue .Z
+// CHECK-NEXT: OpaqueValueExpr [[OPV0:0x[0-9a-f]+]] {{.*}} 'TwoInts' xvalue
 // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'TwoInts' xvalue
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'TwoInts' <HLSLElementwiseCast>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue Var {{.*}} 'TF' 
'TwoFloats'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT: MemberExpr {{.*}} 'int' xvalue .W
+// CHECK-NEXT: OpaqueValueExpr [[OPV0]] {{.*}} 'TwoInts' xvalue
 // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'TwoInts' xvalue
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'TwoInts' <HLSLElementwiseCast>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue Var {{.*}} 'TF' 
'TwoFloats'
@@ -1101,6 +1104,7 @@ int case18() {
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' xvalue
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <ArrayToPointerDecay>
+// CHECK-NEXT: OpaqueValueExpr [[OPV1:0x[0-9a-f]+]] {{.*}} 'int[4]' xvalue
 // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'int[4]' xvalue
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'int[4]' <HLSLElementwiseCast>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'FourFloats' lvalue Var {{.*}} 'FF' 
'FourFloats'
@@ -1108,6 +1112,7 @@ int case18() {
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' xvalue
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <ArrayToPointerDecay>
+// CHECK-NEXT: OpaqueValueExpr [[OPV1]] {{.*}} 'int[4]' xvalue
 // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'int[4]' xvalue
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'int[4]' <HLSLElementwiseCast>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'FourFloats' lvalue Var {{.*}} 'FF' 
'FourFloats'
@@ -1115,6 +1120,7 @@ int case18() {
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' xvalue
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <ArrayToPointerDecay>
+// CHECK-NEXT: OpaqueValueExpr [[OPV1]] {{.*}} 'int[4]' xvalue
 // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'int[4]' xvalue
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'int[4]' <HLSLElementwiseCast>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'FourFloats' lvalue Var {{.*}} 'FF' 
'FourFloats'
@@ -1122,6 +1128,7 @@ int case18() {
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' xvalue
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <ArrayToPointerDecay>
+// CHECK-NEXT: OpaqueValueExpr [[OPV1]] {{.*}} 'int[4]' xvalue
 // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'int[4]' xvalue
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'int[4]' <HLSLElementwiseCast>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'FourFloats' lvalue Var {{.*}} 'FF' 
'FourFloats'
@@ -1141,15 +1148,18 @@ int case19() {
 // CHECK-NEXT: FloatingLiteral {{.*}} 'float' 4.000000e+00
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl {{.*}} used TI 'TwoInts' cinit
+// CHECK-NEXT: ExprWithCleanups {{.*}} 'TwoInts'
 // CHECK-NEXT: InitListExpr {{.*}} 'TwoInts'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT: MemberExpr {{.*}} 'int' xvalue .Z
+// CHECK-NEXT: OpaqueValueExpr [[OPV2:0x[0-9a-f]+]] {{.*}} 'TwoInts' xvalue
 // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'TwoInts' xvalue
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'TwoInts' <HLSLElementwiseCast>
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'float[4]' <HLSLArrayRValue> 
part_of_explicit_cast
 // CHECK-NEXT: DeclRefExpr {{.*}} 'float[4]' lvalue Var {{.*}} 'Arr' 'float[4]'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT: MemberExpr {{.*}} 'int' xvalue .W
+// CHECK-NEXT: OpaqueValueExpr [[OPV2]] {{.*}} 'TwoInts' xvalue
 // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'TwoInts' xvalue
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'TwoInts' <HLSLElementwiseCast>
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'float[4]' <HLSLArrayRValue> 
part_of_explicit_cast

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

Reply via email to