فهرست منبع

Fix loss of buffer type info with libraries and linker (#5197)

* Fix loss of buffer type info with libraries and linker

## Fix loss of buffer type info.

When undef, there was no global symbol, thus type-preserving cast was lost,
and undef type for resource would be dx.types.Handle instead.  This would
particularly impact path through higher lib target then linked to a lower
final shader target.

The fix is to use the HLSL type for undef when the GlobalSymbol is undef.

## Copy resource type annotation in linker.

Linker was dropping the resource type annotation for the target module.
Fixed by copying the type annotation to the target after AddResource.

## Check resource type annotation with libs and linking and various targets

These tests check both module metadata and reflection dump.
While IR may be unnecessary given reflection check, it does reveal some
format inconsistencies that should be addressed.

TODO: investigate https://github.com/microsoft/DirectXShaderCompiler/issues/5202
Xiang Li 2 سال پیش
والد
کامیت
bf015d2e1a

+ 7 - 3
lib/DXIL/DxilMetadataHelper.cpp

@@ -617,9 +617,13 @@ void DxilMDHelper::EmitDxilResourceBase(const DxilResourceBase &R, Metadata *ppM
   Constant *GlobalSymbol = R.GetGlobalSymbol();
   // For sm66+, global symbol will be mutated into handle type.
   // Save hlsl type by generate bitcast on global symbol.
-  if (m_pSM->IsSM66Plus()) {
-    Type *HLSLTy = R.GetHLSLType();
-    if (HLSLTy && HLSLTy != GlobalSymbol->getType())
+  // For sm65-, global symbol will be undef value which saves the HLSLTy
+  // directly.
+  Type *HLSLTy = R.GetHLSLType();
+  if (HLSLTy && HLSLTy != GlobalSymbol->getType()) {
+    if (isa<UndefValue>(GlobalSymbol))
+      GlobalSymbol = UndefValue::get(HLSLTy);
+    else if (m_pSM->IsSM66Plus())
       GlobalSymbol = cast<Constant>(
           ConstantExpr::getCast(Instruction::BitCast, GlobalSymbol, HLSLTy));
   }

+ 1 - 0
lib/HLSL/DxilLinker.cpp

@@ -664,6 +664,7 @@ bool DxilLinkJob::AddGlobals(DxilModule &DM, ValueToValueMapTy &vmap) {
 
       if (DxilResourceBase *res = pLib->GetResource(GV)) {
         bSuccess &= AddResource(res, NewGV);
+        typeSys.CopyTypeAnnotation(res->GetHLSLType(), tmpTypeSys);
       }
     }
   }

+ 6 - 2
tools/clang/test/DXC/lib_entry4.hlsl

@@ -7,9 +7,13 @@
 // CHECK:; cbuffer A
 // CHECK-NEXT:; {
 // CHECK-NEXT:;
-// CHECK-NEXT:[8 x i8] (type annotation not present)
+// CHECK-NEXT:;   struct A
+// CHECK-NEXT:;   {
 // CHECK-NEXT:;
-// CHECK-NEXT:; }
+// CHECK-NEXT:float a;                                      ; Offset:    0
+// CHECK-NEXT:float v;                                      ; Offset:    4
+// CHECK-NEXT:;
+// CHECK-NEXT:;   } A;
 
 // Make sure same cbuffer decalred in different lib works.
 

+ 164 - 0
tools/clang/test/HLSLFileCheck/hlsl/linker/resources/preserve_cb_types.hlsl

@@ -0,0 +1,164 @@
+// RUN: %dxilver 1.7 | %dxc -T lib_6_5 -Fo dxl_6_5 %s | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// Why is GV not mutated to handle for lib_6_6+?
+// RUN: %dxilver 1.7 | %dxc -T lib_6_6 -Fo dxl_6_6 %s | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -Fo dxl_6_7 %s | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// RUN: %dxilver 1.7 | %dxc -T lib_6_x -Fo dxl_6_x %s | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+
+// Target vs_6_5
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+
+// Target vs_6_6
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+
+// Target vs_6_7
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+
+// Target lib_6_5
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_5 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_5 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_5 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_5 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// Target lib_6_6
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_6 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_6 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_6 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+
+// TBD: Why isn't resource GV type mutated to handle when going through lib_6_x?
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_6 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// Target lib_6_7
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_7 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_7 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_7 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+
+// TBD: Why isn't resource GV type mutated to handle when going through lib_6_x?
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_7 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// Target lib_6_x
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_x dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_x dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_x dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_x dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+
+
+
+// RUN: %dxilver 1.7 | %dxc -T lib_6_5 -Fo dxl_6_5 %s | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxc -T lib_6_6 -Fo dxl_6_6 %s | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -Fo dxl_6_7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxc -T lib_6_x -Fo dxl_6_x %s | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// Target vs_6_5
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+
+// Target vs_6_6
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+
+// Target vs_6_7
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+
+// Target lib_6_5
+// RUN: %dxilver 1.7 | %dxl -T lib_6_5 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_5 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_5 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_5 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// Target lib_6_6
+// RUN: %dxilver 1.7 | %dxl -T lib_6_6 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_6 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_6 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_6 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// Target lib_6_7
+// RUN: %dxilver 1.7 | %dxl -T lib_6_7 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_7 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_7 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_7 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// Target lib_6_x
+// RUN: %dxilver 1.7 | %dxl -T lib_6_x dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_x dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_x dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_x dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// REFLECTLIB: D3D12_FUNCTION_DESC: Name: main
+// REFLECTLIB: Shader Version: Vertex
+// REFLECT:     Constant Buffers:
+// REFLECT:       ID3D12ShaderReflectionConstantBuffer:
+// REFLECT:         D3D12_SHADER_BUFFER_DESC: Name: CB0
+// REFLECT:           Type: D3D_CT_CBUFFER
+// REFLECT:           Size: 80
+// REFLECT:           Num Variables: 2
+// REFLECT:           ID3D12ShaderReflectionVariable:
+// REFLECT:             D3D12_SHADER_VARIABLE_DESC: Name: m
+// REFLECT:               uFlags: (D3D_SVF_USED)
+// REFLECT:             ID3D12ShaderReflectionType:
+// REFLECT:               D3D12_SHADER_TYPE_DESC: Name: float4x4
+// REFLECT:                 Class: D3D_SVC_MATRIX_ROWS
+// REFLECT:                 Type: D3D_SVT_FLOAT
+// REFLECT:           ID3D12ShaderReflectionVariable:
+// REFLECT:             D3D12_SHADER_VARIABLE_DESC: Name: f
+// REFLECT:               Size: 16
+// REFLECT:               StartOffset: 64
+// REFLECT:             ID3D12ShaderReflectionType:
+// REFLECT:               D3D12_SHADER_TYPE_DESC: Name: float4
+// REFLECT:                 Class: D3D_SVC_VECTOR
+// REFLECT:                 Type: D3D_SVT_FLOAT
+// REFLECT:     Bound Resources:
+// REFLECT:       D3D12_SHADER_INPUT_BIND_DESC: Name: CB0
+// REFLECT:         Type: D3D_SIT_CBUFFER
+
+
+// GVHLSL: %[[ResTy:[^ ]]] = type { {{\[4 x \<4 x float\>\]|\%class\.matrix\.float\.4\.4}}, <4 x float> }
+
+// GVHLSL: @[[GV:[^ ]]] = external global %[[ResTy]]
+// GVHDL: @[[GV:[^ ]]] = external constant dx.types.Handle
+
+// CHECK: !dx.resources = !{![[AllRes:[0-9]+]]}
+// CHECK: !dx.typeAnnotations = !{![[TypeAnn:[0-9]+]],
+// CHECK: ![[AllRes]] = !{null, null, ![[AllCBs:[0-9]+]], null}
+// CHECK: ![[AllCBs]] = !{![[Res_CB0:[0-9]+]]}
+
+// LIBGV_ORIG: ![[Res_CB0]] = !{i32 0, %[[ResTy:[^*]+]]* @[[GV:[^,]+]], !"CB0", i32 -1, i32 -1, i32 1, i32 80, null}
+// LIBGV_HDL: ![[Res_CB0]] = !{i32 0, %[[ResTy:[^*]+]]* bitcast (%dx.types.Handle* @[[GV:[^ ]+]] to %[[ResTy]]*), !"CB0", i32 -1, i32 -1, i32 1, i32 80, null}
+// CHKSHAD: ![[Res_CB0]] = !{i32 0, %[[ResTy:[^*]+]]* undef, !"CB0", i32 0, i32 0, i32 1, i32 80, null}
+
+// CHECK: ![[TypeAnn]] =
+// CHECK-SAME: %[[ResTy]] undef, ![[TypeAnn_CB0:[0-9]+]]
+
+// CHECK: ![[TypeAnn_CB0]] = !{i32 80, ![[FieldAnn_m:[0-9]+]]
+// CHECK: ![[FieldAnn_m]] = !{i32 6, !"m", i32 2, !{{[0-9]+}}, i32 3, i32 0, i32 7, i32 9, i32 9, i1 true}
+
+cbuffer CB0 {
+  row_major float4x4 m;
+  float4 f;
+}
+
+export float4 xform(float4 v) {
+  return mul(v, m);
+}
+
+[shader("vertex")]
+float4 main(float3 pos : Position) : SV_Position {
+  return xform(float4(pos, 1)) * f;
+}

+ 159 - 0
tools/clang/test/HLSLFileCheck/hlsl/linker/resources/preserve_sb_types.hlsl

@@ -0,0 +1,159 @@
+// RUN: %dxilver 1.7 | %dxc -T lib_6_5 -Fo dxl_6_5 %s | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// Why is GV not mutated to handle for lib_6_6+?
+// RUN: %dxilver 1.7 | %dxc -T lib_6_6 -Fo dxl_6_6 %s | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -Fo dxl_6_7 %s | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// RUN: %dxilver 1.7 | %dxc -T lib_6_x -Fo dxl_6_x %s | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+
+// Target vs_6_5
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+
+// Target vs_6_6
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+
+// Target vs_6_7
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,CHKSHAD
+
+// Target lib_6_5
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_5 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_5 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_5 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_5 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// Target lib_6_6
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_6 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_6 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_6 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+
+// TBD: Why isn't resource GV type mutated to handle when going through lib_6_x?
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_6 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// Target lib_6_7
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_7 dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_7 dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_7 dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+
+// TBD: Why isn't resource GV type mutated to handle when going through lib_6_x?
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_7 dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_ORIG
+
+// Target lib_6_x
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_x dxl_6_5 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_x dxl_6_6 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_x dxl_6_7 %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+// RUN: %dxilver 1.7 | %dxl -E main -T lib_6_x dxl_6_x %s  | FileCheck %s -check-prefixes=CHECK,LIBGV_HDL
+
+
+
+// RUN: %dxilver 1.7 | %dxc -T lib_6_5 -Fo dxl_6_5 %s | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxc -T lib_6_6 -Fo dxl_6_6 %s | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -Fo dxl_6_7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxc -T lib_6_x -Fo dxl_6_x %s | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// Target vs_6_5
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_5 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+
+// Target vs_6_6
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_6 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+
+// Target vs_6_7
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+// RUN: %dxilver 1.7 | %dxl -E main -T vs_6_7 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECT
+
+// Target lib_6_5
+// RUN: %dxilver 1.7 | %dxl -T lib_6_5 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_5 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_5 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_5 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// Target lib_6_6
+// RUN: %dxilver 1.7 | %dxl -T lib_6_6 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_6 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_6 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_6 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// Target lib_6_7
+// RUN: %dxilver 1.7 | %dxl -T lib_6_7 dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_7 dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_7 dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_7 dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// Target lib_6_x
+// RUN: %dxilver 1.7 | %dxl -T lib_6_x dxl_6_5 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_x dxl_6_6 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_x dxl_6_7 %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+// RUN: %dxilver 1.7 | %dxl -T lib_6_x dxl_6_x %s  | %D3DReflect %s | FileCheck %s -check-prefixes=REFLECTLIB,REFLECT
+
+// REFLECTLIB: D3D12_FUNCTION_DESC: Name: main
+// REFLECTLIB: Shader Version: Vertex
+// REFLECT:     Constant Buffers:
+// REFLECT:       ID3D12ShaderReflectionConstantBuffer:
+// REFLECT:         D3D12_SHADER_BUFFER_DESC: Name: StructBuf
+// REFLECT:           Type: D3D_CT_RESOURCE_BIND_INFO
+// REFLECT:           Size: 80
+// REFLECT:               D3D12_SHADER_TYPE_DESC: Name: Element
+// REFLECT:                 Class: D3D_SVC_STRUCT
+// REFLECT:                   D3D12_SHADER_TYPE_DESC: Name: float4x4
+// REFLECT:                   D3D12_SHADER_TYPE_DESC: Name: float4
+// REFLECT:     Bound Resources:
+// REFLECT:       D3D12_SHADER_INPUT_BIND_DESC: Name: StructBuf
+// REFLECT:         Type: D3D_SIT_STRUCTURED
+
+
+// CHECK: %[[ResTy:[^ ]+]] = type { %[[ElTy:.*struct.Element]] }
+// CHECK: %[[ElTy]] = type { {{\[4 x \<4 x float\>\]|\%class\.matrix\.float\.4\.4}}, <4 x float> }
+
+// TBD: Why is resource global sometimes `global` and sometimes `constant`?
+// LIBGV_ORIG: @[[GV:[^ ]+]] = external {{global|constant}} %[[ResTy]]
+// LIBGV_HDL: @[[GV:[^ ]+]] = external {{global|constant}} %dx.types.Handle
+
+// CHECK: !dx.resources = !{![[AllRes:[0-9]+]]}
+// CHECK: !dx.typeAnnotations = !{![[TypeAnn:[0-9]+]],
+// CHECK: ![[AllRes]] = !{![[AllSRVs:[0-9]+]], null, null, null}
+// CHECK: ![[AllSRVs]] = !{![[Res_StructBuf:[0-9]+]]}
+
+// LIBGV_ORIG: ![[Res_StructBuf]] = !{i32 0, %[[ResTy:[^*]+]]* @[[GV:[^,]+]], !"StructBuf", i32 -1, i32 -1, i32 1, i32 12, i32 0, ![[ExtraProps:[0-9]+]]}
+// LIBGV_HDL: ![[Res_StructBuf]] = !{i32 0, %[[ResTy:[^*]+]]* bitcast (%dx.types.Handle* @[[GV:[^ ]+]] to %[[ResTy]]*), !"StructBuf", i32 -1, i32 -1, i32 1, i32 12, i32 0, ![[ExtraProps:[0-9]+]]}
+// CHKSHAD: ![[Res_StructBuf]] = !{i32 0, %[[ResTy:[^*]+]]* undef, !"StructBuf", i32 0, i32 0, i32 1, i32 12, i32 0, ![[ExtraProps:[0-9]+]]}
+
+// Struct stride:
+// CHECK: ![[ExtraProps]] = !{i32 1, i32 80}
+
+// CHECK: ![[TypeAnn]] =
+// CHECK-SAME: %[[ElTy]] undef, ![[TypeAnn_ElTy:[0-9]+]]
+
+// CHECK: ![[TypeAnn_ElTy]] = !{i32 80, ![[FieldAnn_m:[0-9]+]]
+// CHECK: ![[FieldAnn_m]] = !{i32 6, !"m"
+
+struct Element {
+  row_major float4x4 m;
+  float4 f;
+};
+
+StructuredBuffer<Element> StructBuf;
+
+export float4 xform(float4 v) {
+  return mul(v, StructBuf[0].m);
+}
+
+[shader("vertex")]
+float4 main(float3 pos : Position) : SV_Position {
+  return xform(float4(pos, 1)) * StructBuf[0].f;
+}