2
0
Эх сурвалжийг харах

[spirv] Use OpStore instead of OpVariable initializer (#858)

Right now certain optimization passes in SPIRV-Tools ignores
OpVariable initializer:

https://github.com/KhronosGroup/SPIRV-Tools/issues/1017

As a workaround, this commit replaces OpVariable initializer with
OpStore.

This commit should be reverted once OpVariable initializer is
supported.

Fixes https://github.com/Microsoft/DirectXShaderCompiler/issues/853
Lei Zhang 7 жил өмнө
parent
commit
7f6aaf6cc6

+ 38 - 35
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -775,39 +775,31 @@ void SPIRVEmitter::doVarDecl(const VarDecl *decl) {
     // not have local storage, it should be file scope variable.
     const bool isFileScopeVar = !decl->hasLocalStorage();
 
-    // Handle initializer. SPIR-V requires that "initializer must be an <id>
-    // from a constant instruction or a global (module scope) OpVariable
-    // instruction."
-    llvm::Optional<uint32_t> constInit;
-    if (decl->hasInit()) {
-      if (const uint32_t id = tryToEvaluateAsConst(decl->getInit()))
-        constInit = llvm::Optional<uint32_t>(id);
-    } else if (isFileScopeVar) {
-      // For static variables, if no initializers are provided, we should
-      // initialize them to zero values.
-      constInit = llvm::Optional<uint32_t>(theBuilder.getConstantNull(varType));
-    }
-
     if (isFileScopeVar)
-      varId = declIdMapper.createFileVar(varType, decl, constInit);
+      varId = declIdMapper.createFileVar(varType, decl, llvm::None);
     else
-      varId = declIdMapper.createFnVar(varType, decl, constInit);
-
-    // If we cannot evaluate the initializer as a constant expression, we'll
-    // need to use OpStore to write the initializer to the variable.
-    // Also we should only evaluate the initializer once for a static variable.
-    if (decl->hasInit() && !constInit.hasValue()) {
-      if (isFileScopeVar) {
-        if (decl->isStaticLocal()) {
-          initOnce(decl->getName(), varId, decl->getInit());
-        } else {
-          // Defer to initialize these global variables at the beginning of the
-          // entry function.
-          toInitGloalVars.push_back(decl);
-        }
+      varId = declIdMapper.createFnVar(varType, decl, llvm::None);
+
+    // Emit OpStore to initialize the variable
+    // TODO: revert back to use OpVariable initializer
+
+    // We should only evaluate the initializer once for a static variable.
+    if (isFileScopeVar) {
+      if (decl->isStaticLocal()) {
+        initOnce(decl->getType(), decl->getName(), varId, decl->getInit());
       } else {
-        storeValue(varId, loadIfGLValue(decl->getInit()), decl->getType());
+        // Defer to initialize these global variables at the beginning of the
+        // entry function.
+        toInitGloalVars.push_back(decl);
       }
+
+    }
+    // Function local variables. Just emit OpStore at the current insert point.
+    else if (decl->hasInit()) {
+      if (const auto constId = tryToEvaluateAsConst(decl->getInit()))
+        theBuilder.createStore(varId, constId);
+      else
+        storeValue(varId, loadIfGLValue(decl->getInit()), decl->getType());
     }
   } else {
     varId = declIdMapper.createExternVar(decl);
@@ -3500,8 +3492,8 @@ SpirvEvalInfo SPIRVEmitter::processBinaryOp(const Expr *lhs, const Expr *rhs,
   return 0;
 }
 
-void SPIRVEmitter::initOnce(std::string varName, uint32_t varPtr,
-                            const Expr *varInit) {
+void SPIRVEmitter::initOnce(QualType varType, std::string varName,
+                            uint32_t varPtr, const Expr *varInit) {
   const uint32_t boolType = theBuilder.getBoolType();
   varName = "init.done." + varName;
 
@@ -3522,7 +3514,12 @@ void SPIRVEmitter::initOnce(std::string varName, uint32_t varPtr,
 
   theBuilder.setInsertPoint(thenBB);
   // Do initialization and mark done
-  theBuilder.createStore(varPtr, doExpr(varInit));
+  if (varInit) {
+    theBuilder.createStore(varPtr, doExpr(varInit));
+  } else {
+    const auto typeId = typeTranslator.translateType(varType);
+    theBuilder.createStore(varPtr, theBuilder.getConstantNull(typeId));
+  }
   theBuilder.createStore(initDoneVar, theBuilder.getConstantBool(true));
   theBuilder.createBranch(mergeBB);
   theBuilder.addSuccessor(mergeBB);
@@ -6488,9 +6485,15 @@ bool SPIRVEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
   theBuilder.setInsertPoint(entryLabel);
 
   // Initialize all global variables at the beginning of the wrapper
-  for (const VarDecl *varDecl : toInitGloalVars)
-    theBuilder.createStore(declIdMapper.getDeclResultId(varDecl),
-                           doExpr(varDecl->getInit()));
+  for (const VarDecl *varDecl : toInitGloalVars) {
+    const auto id = declIdMapper.getDeclResultId(varDecl);
+    if (const auto *init = varDecl->getInit()) {
+      theBuilder.createStore(id, doExpr(init));
+    } else {
+      const auto typeId = typeTranslator.translateType(varDecl->getType());
+      theBuilder.createStore(id, theBuilder.getConstantNull(typeId));
+    }
+  }
 
   // Create temporary variables for holding function call arguments
   llvm::SmallVector<uint32_t, 4> params;

+ 2 - 1
tools/clang/lib/SPIRV/SPIRVEmitter.h

@@ -137,7 +137,8 @@ private:
                                 spv::Op mandateGenOpcode = spv::Op::Max);
 
   /// Generates SPIR-V instructions to initialize the given variable once.
-  void initOnce(std::string varName, uint32_t varPtr, const Expr *varInit);
+  void initOnce(QualType varType, std::string varName, uint32_t varPtr,
+                const Expr *varInit);
 
   /// Returns true if the given expression will be translated into a vector
   /// shuffle instruction in SPIR-V.

+ 2 - 3
tools/clang/test/CodeGenSPIRV/cast.2bool.implicit.hlsl

@@ -18,8 +18,6 @@ void main() {
     int1 vfrom1;
     uint2 vfrom2;
     float3 vfrom3;
-// CHECK: %vbc2 = OpVariable %_ptr_Function_v2bool Function [[v2bool_1_0]]
-// CHECK: %vbc3 = OpVariable %_ptr_Function_v3bool Function [[v3bool_0_1_1]]
 
     // From constant (implicit)
 // CHECK: OpStore %b %true
@@ -47,7 +45,8 @@ void main() {
 
     // Vector cases
 
-    // See the beginning for generated code
+// CHECK: OpStore %vbc2 [[v2bool_1_0]]
+// CHECK: OpStore %vbc3 [[v3bool_0_1_1]]
     bool2 vbc2 = {1, 15 - 15};
     bool3 vbc3 = {0.0, 1.2 + 1.1, 3}; // Mixed
 

+ 2 - 3
tools/clang/test/CodeGenSPIRV/cast.2fp.implicit.hlsl

@@ -16,8 +16,6 @@ void main() {
     bool1 vfrom1;
     uint2 vfrom2;
     int3 vfrom3;
-// CHECK: %vfc2 = OpVariable %_ptr_Function_v2float Function [[v2float_1_0]]
-// CHECK: %vfc3 = OpVariable %_ptr_Function_v3float Function [[v3float_0_4_n3]]
 
     // From constant (implicit)
 // CHECK: OpStore %f %float_1
@@ -45,7 +43,8 @@ void main() {
 
     // Vector cases
 
-    // See the beginning for generated code
+// CHECK: OpStore %vfc2 [[v2float_1_0]]
+// CHECK: OpStore %vfc3 [[v3float_0_4_n3]]
     float2 vfc2 = {true, false};
     float3 vfc3 = {false, 4u, -3}; // Mixed
 

+ 2 - 3
tools/clang/test/CodeGenSPIRV/cast.2sint.implicit.hlsl

@@ -16,8 +16,6 @@ void main() {
     bool1 vfrom1;
     uint2 vfrom2;
     float3 vfrom3;
-// CHECK: %vic2 = OpVariable %_ptr_Function_v2int Function [[v2int_1_0]]
-// CHECK: %vic3 = OpVariable %_ptr_Function_v3int Function [[v3int_0_2_n3]]
 
     // From constant (implicit)
 // CHECK: OpStore %i %int_1
@@ -45,7 +43,8 @@ void main() {
 
     // Vector cases
 
-    // See the beginning for generated code
+// CHECK: OpStore %vic2 [[v2int_1_0]]
+// CHECK: OpStore %vic3 [[v3int_0_2_n3]]
     int2 vic2 = {true, false};
     int3 vic3 = {false, 1.1 + 1.2, -3}; // Mixed
 

+ 2 - 3
tools/clang/test/CodeGenSPIRV/cast.2uint.implicit.hlsl

@@ -16,8 +16,6 @@ void main() {
     bool1 vfrom1;
     int2 vfrom2;
     float3 vfrom3;
-// CHECK: %vic2 = OpVariable %_ptr_Function_v2uint Function [[v2uint_1_0]]
-// CHECK: %vic3 = OpVariable %_ptr_Function_v3uint Function [[v3uint_0_2_3]]
 
     // From constant (implicit)
 // CHECK: OpStore %i %uint_1
@@ -45,7 +43,8 @@ void main() {
 
     // Vector cases
 
-    // See the beginning for generated code
+// CHECK: OpStore %vic2 [[v2uint_1_0]]
+// CHECK: OpStore %vic3 [[v3uint_0_2_3]]
     uint2 vic2 = {true, false};
     uint3 vic3 = {false, 1.1 + 1.2, 3}; // Mixed
 

+ 1 - 1
tools/clang/test/CodeGenSPIRV/cast.vector.splat.hlsl

@@ -6,7 +6,7 @@ void main() {
 // CHECK-LABEL: %bb_entry = OpLabel
 
     // From constant
-// CHECK: %vf4 = OpVariable %_ptr_Function_v4float Function [[v4f32c]]
+// CHECK: OpStore %vf4 [[v4f32c]]
     float4 vf4 = 1;
 
 // CHECK: [[v3f32c:%\d+]] = OpCompositeConstruct %v3float %float_2 %float_2 %float_2

+ 1 - 0
tools/clang/test/CodeGenSPIRV/cf.break.mixed.hlsl

@@ -39,6 +39,7 @@ void main() {
         a = 6;     // No SPIR-V should be emitted for this statement.
       }
 // CHECK-NEXT: %switch_default = OpLabel
+// CHECK-NEXT: OpStore %i %int_0
 // CHECK-NEXT: OpBranch %for_check
       default:
       // CHECK-NEXT: %for_check = OpLabel

+ 2 - 1
tools/clang/test/CodeGenSPIRV/cf.for.break.hlsl

@@ -2,7 +2,7 @@
 
 void main() {
   int val = 0;
-  
+
 // CHECK:      OpBranch %for_check
 // CHECK-NEXT: %for_check = OpLabel
 // CHECK:      OpLoopMerge %for_merge %for_continue None
@@ -29,6 +29,7 @@ void main() {
   }
 // CHECK-NEXT: %for_merge = OpLabel
 
+// CHECK-NEXT: OpStore %j %int_0
 // CHECK-NEXT: OpBranch %for_check_0
 
   ////////////////////////////////////////////////////////////////////////////////

+ 2 - 1
tools/clang/test/CodeGenSPIRV/cf.for.continue.hlsl

@@ -2,7 +2,7 @@
 
 void main() {
   int val = 0;
-  
+
 // CHECK:      OpBranch %for_check
 // CHECK-NEXT: %for_check = OpLabel
 // CHECK:      OpLoopMerge %for_merge %for_continue None
@@ -29,6 +29,7 @@ void main() {
   }
 // CHECK-NEXT: %for_merge = OpLabel
 
+// CHECK-NEXT: OpStore %j %int_0
 // CHECK-NEXT: OpBranch %for_check_0
 
 

+ 4 - 4
tools/clang/test/CodeGenSPIRV/cf.for.nested.hlsl

@@ -2,12 +2,10 @@
 
 void main() {
 // CHECK-LABEL: %bb_entry = OpLabel
-// CHECK-NEXT: %val = OpVariable %_ptr_Function_int Function %int_0
     int val = 0;
 
-// CHECK-NEXT: %i = OpVariable %_ptr_Function_int Function %int_0
-// CHECK-NEXT: %j = OpVariable %_ptr_Function_int Function %int_0
-// CHECK-NEXT: %k = OpVariable %_ptr_Function_int Function %int_0
+// CHECK:      OpStore %val %int_0
+// CHECK-NEXT: OpStore %i %int_0
 // CHECK-NEXT: OpBranch %for_check
 
 // CHECK-LABEL: %for_check = OpLabel
@@ -22,6 +20,7 @@ void main() {
 // CHECK-NEXT: [[add0:%\d+]] = OpIAdd %int [[val0]] [[i1]]
 // CHECK-NEXT: OpStore %val [[add0]]
         val = val + i;
+// CHECK-NEXT: OpStore %j %int_0
 // CHECK-NEXT: OpBranch %for_check_0
 
 // CHECK-LABEL: %for_check_0 = OpLabel
@@ -31,6 +30,7 @@ void main() {
 // CHECK-NEXT: OpBranchConditional [[lt1]] %for_body_0 %for_merge_0
         [loop] for (int j = 0; j < 10; ++j) {
 // CHECK-LABEL: %for_body_0 = OpLabel
+// CHECK-NEXT: OpStore %k %int_0
 // CHECK-NEXT: OpBranch %for_check_1
 
 // CHECK-LABEL: %for_check_1 = OpLabel

+ 4 - 4
tools/clang/test/CodeGenSPIRV/cf.if.for.hlsl

@@ -3,11 +3,8 @@
 float4 main(float color: COLOR) : SV_TARGET {
 // CHECK-LABEL: %bb_entry = OpLabel
 
-// CHECK-NEXT: %val = OpVariable %_ptr_Function_float Function %float_0
+// CHECK: OpStore %val %float_0
     float val = 0.;
-// CHECK-NEXT: %i = OpVariable %_ptr_Function_int Function %int_0
-// CHECK-NEXT: %j = OpVariable %_ptr_Function_int Function %int_0
-// CHECK-NEXT: %k = OpVariable %_ptr_Function_int Function %int_0
 
 // CHECK-NEXT: [[color0:%\d+]] = OpLoad %float %color
 // CHECK-NEXT: [[lt0:%\d+]] = OpFOrdLessThan %bool [[color0]] %float_0_3
@@ -20,6 +17,7 @@ float4 main(float color: COLOR) : SV_TARGET {
 // CHECK-NEXT: OpBranch %if_merge
     }
 // CHECK-LABEL: %if_merge = OpLabel
+// CHECK-NEXT: OpStore %i %int_0
 // CHECK-NEXT: OpBranch %for_check
 
     // for-stmt following if-stmt
@@ -38,6 +36,7 @@ float4 main(float color: COLOR) : SV_TARGET {
 // CHECK-LABEL: %if_true_0 = OpLabel
 // CHECK: OpStore %val
             val = val + 1.;
+// CHECK-NEXT: OpStore %j %int_0
 // CHECK-NEXT: OpBranch %for_check_0
 
 // CHECK-LABEL: %for_check_0 = OpLabel
@@ -76,6 +75,7 @@ float4 main(float color: COLOR) : SV_TARGET {
 // CHECK-NEXT: OpBranch %if_merge_2
         } else {
 // CHECK-LABEL: %if_false = OpLabel
+// CHECK-NEXT: OpStore %k %int_0
 // CHECK-NEXT: OpBranch %for_check_1
 
 // CHECK-LABEL: %for_check_1 = OpLabel

+ 2 - 7
tools/clang/test/CodeGenSPIRV/cf.switch.ifstmt.hlsl

@@ -8,11 +8,6 @@ void main() {
 // CHECK-NEXT: %b = OpVariable %_ptr_Function_int Function
 // CHECK-NEXT: %c = OpVariable %_ptr_Function_int Function
 
-// TODO: We should try not to emit OpVariable for constant variables.
-// CHECK-NEXT: %r = OpVariable %_ptr_Function_int Function %int_20
-// CHECK-NEXT: %s = OpVariable %_ptr_Function_int Function %int_40
-// CHECK-NEXT: %t = OpVariable %_ptr_Function_int Function %int_140
-// CHECK-NEXT: %d = OpVariable %_ptr_Function_int Function %int_5
   int a,b,c;
   const int r = 20;
   const int s = 40;
@@ -23,7 +18,7 @@ void main() {
   // DefaultStmt is the first statement //
   ////////////////////////////////////////
 
-// CHECK-NEXT: [[a0:%\d+]] = OpLoad %int %a
+// CHECK:      [[a0:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[is_a_1:%\d+]] = OpIEqual %bool [[a0]] %int_1
 // CHECK-NEXT: OpSelectionMerge %if_merge_0 None
 // CHECK-NEXT: OpBranchConditional [[is_a_1]] %if_true %if_false
@@ -99,7 +94,7 @@ void main() {
   // DefaultStmt is the last statement         //
   ///////////////////////////////////////////////
 
-// CHECK-NEXT: [[d0:%\d+]] = OpLoad %int %d
+// CHECK:      [[d0:%\d+]] = OpLoad %int %d
 // CHECK-NEXT: [[is_d_1:%\d+]] = OpIEqual %bool [[d0]] %int_1
 // CHECK-NEXT: OpSelectionMerge %if_merge_10 None
 // CHECK-NEXT: OpBranchConditional [[is_d_1]] %if_true_3 %if_false_3

+ 5 - 5
tools/clang/test/CodeGenSPIRV/cf.switch.opswitch.hlsl

@@ -12,7 +12,7 @@ void main() {
   // Has a 'default' case   //
   // All cases have 'break' //
   ////////////////////////////
-  
+
   int a = 0;
 // CHECK: [[a:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: OpSelectionMerge %switch_merge None
@@ -57,7 +57,7 @@ void main() {
   ////////////////////////////////////
   // The selector is a statement    //
   // Does not have a 'default' case //
-  // All cases have 'break'         //  
+  // All cases have 'break'         //
   ////////////////////////////////////
 
 // CHECK-NEXT: [[a1:%\d+]] = OpLoad %int %a
@@ -68,7 +68,7 @@ void main() {
   switch(int c = a) {
 // CHECK-NEXT: %switch_n4 = OpLabel
 // CHECK-NEXT: OpStore %result %int_n400
-// CHECK-NEXT: OpBranch %switch_merge_0  
+// CHECK-NEXT: OpBranch %switch_merge_0
     case -4:
       result = -400;
       break;
@@ -253,7 +253,7 @@ void main() {
       }
     }
   }
-// CHECK-NEXT: %switch_merge_5 = OpLabel    
+// CHECK-NEXT: %switch_merge_5 = OpLabel
 
 
 
@@ -322,7 +322,7 @@ void main() {
   const int s = 45;
   const int t = 2*r + s;  // evaluates to 115.
 
-// CHECK-NEXT: [[a8:%\d+]] = OpLoad %int %a
+// CHECK:      [[a8:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: OpSelectionMerge %switch_merge_8 None
 // CHECK-NEXT: OpSwitch [[a8]] %switch_merge_8 35 %switch_35 115 %switch_115
   switch(a) {

+ 5 - 6
tools/clang/test/CodeGenSPIRV/oo.class.static.member.hlsl

@@ -16,22 +16,21 @@ class T {
 
 // CHECK: [[v4fc:%\d+]] = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
 
-// CHECK: %M = OpVariable %_ptr_Private_v4float Private [[v4fc]]
+// CHECK: %M = OpVariable %_ptr_Private_v4float Private
 // CHECK: %N = OpVariable %_ptr_Private_S Private
-// CHECK: %U = OpVariable %_ptr_Private_v4float Private [[v4fc]]
+// CHECK: %U = OpVariable %_ptr_Private_v4float Private
 
 float4 T::M = float4(1., 2., 3., 4.);
 S      T::N = {5.0, 1., 2., 3., 4.};
 
 const float4 T::U = float4(1., 2., 3., 4.);
 
-// T::M is intialized using embeded initializer in the variable declaration.
-// T::N is intialized at the beginning of the main function.
-
 // CHECK-LABEL: %main = OpFunction
-// CHECK:      [[v1to4:%\d+]] = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
+// CHECK:                       OpStore %M [[v4fc]]
+// CHECK-NEXT: [[v1to4:%\d+]] = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
 // CHECK-NEXT: [[v1to5:%\d+]] = OpCompositeConstruct %S %float_5 [[v1to4]]
 // CHECK-NEXT:                  OpStore %N [[v1to5]]
+// CHECK-NEXT:                  OpStore %U [[v4fc]]
 
 // CHECK-LABEL: %src_main = OpFunction
 float4 main(float4 input: A) : SV_Target {

+ 14 - 4
tools/clang/test/CodeGenSPIRV/oo.static.member.init.hlsl

@@ -16,11 +16,21 @@ const int T::SIX = 6;
 
 int foo(int val) { return val; }
 
-// CHECK:   %FIVE = OpVariable %_ptr_Private_int Private %int_5
-// CHECK:    %SIX = OpVariable %_ptr_Private_int Private %int_6
-// CHECK: %FIVE_0 = OpVariable %_ptr_Private_int Private %int_5
-// CHECK:  %SIX_0 = OpVariable %_ptr_Private_int Private %int_6
+// CHECK:   %FIVE = OpVariable %_ptr_Private_int Private
+// CHECK:    %SIX = OpVariable %_ptr_Private_int Private
+// CHECK: %FIVE_0 = OpVariable %_ptr_Private_int Private
+// CHECK:  %SIX_0 = OpVariable %_ptr_Private_int Private
 int main() : A {
+// CHECK-LABEL: %main = OpFunction
+
+// CHECK: OpStore %FIVE %int_5
+// CHECK: OpStore %SIX %int_6
+// CHECK: OpStore %FIVE_0 %int_5
+// CHECK: OpStore %SIX_0 %int_6
+// CHECK: OpFunctionCall %int %src_main
+
+// CHECK-LABEL: %src_main = OpFunction
+
 // CHECK: OpLoad %int %FIVE
 // CHECK: OpLoad %int %SIX
 // CHECK: OpLoad %int %FIVE_0

+ 5 - 6
tools/clang/test/CodeGenSPIRV/oo.struct.static.member.hlsl

@@ -16,22 +16,21 @@ struct T {
 
 // CHECK: [[v4fc:%\d+]] = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
 
-// CHECK: %M = OpVariable %_ptr_Private_v4float Private [[v4fc]]
+// CHECK: %M = OpVariable %_ptr_Private_v4float Private
 // CHECK: %N = OpVariable %_ptr_Private_S Private
-// CHECK: %U = OpVariable %_ptr_Private_v4float Private [[v4fc]]
+// CHECK: %U = OpVariable %_ptr_Private_v4float Private
 
 float4 T::M = float4(1., 2., 3., 4.);
 S      T::N = {5.0, 1., 2., 3., 4.};
 
 const float4 T::U = float4(1., 2., 3., 4.);
 
-// T::M is intialized using embeded initializer in the variable declaration.
-// T::N is intialized at the beginning of the main function.
-
 // CHECK-LABEL: %main = OpFunction
-// CHECK:      [[v1to4:%\d+]] = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
+// CHECK:                       OpStore %M [[v4fc]]
+// CHECK-NEXT: [[v1to4:%\d+]] = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
 // CHECK-NEXT: [[v1to5:%\d+]] = OpCompositeConstruct %S %float_5 [[v1to4]]
 // CHECK-NEXT:                  OpStore %N [[v1to5]]
+// CHECK-NEXT:                  OpStore %U [[v4fc]]
 
 // CHECK-LABEL: %src_main = OpFunction
 float4 main(float4 input: A) : SV_Target {

+ 2 - 0
tools/clang/test/CodeGenSPIRV/op.texture.access.hlsl

@@ -22,6 +22,7 @@ void main() {
 // CHECK-NEXT:                    OpStore %a1 [[result1]]
   float  a1 = t1[5];
 
+// CHECK-NEXT:                    OpStore %pos2 [[cu12]]
 // CHECK-NEXT:    [[pos2:%\d+]] = OpLoad %v2uint %pos2
 // CHECK-NEXT:      [[t2:%\d+]] = OpLoad %type_2d_image %t2
 // CHECK-NEXT:      [[f2:%\d+]] = OpImageFetch %v4int [[t2]] [[pos2]] Lod %uint_0
@@ -30,6 +31,7 @@ void main() {
   uint2 pos2 = uint2(1,2);
   int2    a2 = t2[pos2];
 
+// CHECK-NEXT:                    OpStore %pos3 [[cu123]]
 // CHECK-NEXT:    [[pos3:%\d+]] = OpLoad %v3uint %pos3
 // CHECK-NEXT:      [[t3:%\d+]] = OpLoad %type_3d_image %t3
 // CHECK-NEXT:      [[f3:%\d+]] = OpImageFetch %v4uint [[t3]] [[pos3]] Lod %uint_0

+ 3 - 3
tools/clang/test/CodeGenSPIRV/op.vector.swizzle.const-scalar.hlsl

@@ -6,12 +6,12 @@
 
 void main() {
 
-// CHECK: %a = OpVariable %_ptr_Function_v4float Function [[v4f1]]
+// CHECK: OpStore %a [[v4f1]]
   float4 a = (1).xxxx;
 
-// CHECK: %b = OpVariable %_ptr_Function_v4float Function [[v4f25]]
+// CHECK: OpStore %b [[v4f25]]
   float4 b = (2.5).xxxx;
 
-// CHECK: %c = OpVariable %_ptr_Function_v4float Function [[v4f0]]
+// CHECK: OpStore %c [[v4f0]]
   float4 c = (false).xxxx;
 }

+ 5 - 8
tools/clang/test/CodeGenSPIRV/var.init.hlsl

@@ -7,24 +7,19 @@
 float4 main(float component: COLOR) : SV_TARGET {
 // CHECK-LABEL: %bb_entry = OpLabel
 
-// CHECK: %a = OpVariable %_ptr_Function_int Function %int_0
-// CHECK: %i = OpVariable %_ptr_Function_float Function %float_3
-// CHECK: %m = OpVariable %_ptr_Function_v4float Function [[float4constant]]
-// CHECK: %p = OpVariable %_ptr_Function_v2int Function [[int2constant]]
-// CHECK: %x = OpVariable %_ptr_Function_uint Function %uint_1
-
-// Initializer already attached to the var definition
+// CHECK: OpStore %a %int_0
     int a = 0; // From constant
 // CHECK:      [[a0:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: OpStore %b [[a0]]
     int b = a; // From local variable
 
-// Initializer already attached to the var definition
+// CHECK-NEXT: OpStore %i %float_3
     float i = 1. + 2.;   // From const expr
 // CHECK-NEXT: [[component0:%\d+]] = OpLoad %float %component
 // CHECK-NEXT: OpStore %j [[component0]]
     float j = component; // From stage variable
 
+// CHECK-NEXT: OpStore %m [[float4constant]]
     float4 m = float4(1.0, 2.0, 3.0, 4.0);  // All components are constants
 // CHECK: [[j0:%\d+]] = OpLoad %float %j
 // CHECK-NEXT: [[j1:%\d+]] = OpLoad %float %j
@@ -39,6 +34,7 @@ float4 main(float component: COLOR) : SV_TARGET {
 // CHECK-NEXT: OpStore %o [[oinit]]
     float4 o = float4(1.0, j, 3.0, j);      // Mixed case
 
+// CHECK-NEXT: OpStore %p [[int2constant]]
     int2 p = {1, 2}; // All components are constants
 // CHECK-NEXT: [[b1:%\d+]] = OpLoad %int %b
 // CHECK-NEXT: [[a1:%\d+]] = OpLoad %int %a
@@ -46,6 +42,7 @@ float4 main(float component: COLOR) : SV_TARGET {
 // CHECK-NEXT: OpStore %q [[qinit]]
     int3 q = {4, b, a}; // Mixed cases
 
+// CHECK-NEXT: OpStore %x %uint_1
     uint1 x = uint1(1); // Special case: vector of size 1
 
     float2 y;

+ 32 - 12
tools/clang/test/CodeGenSPIRV/var.static.hlsl

@@ -3,9 +3,9 @@
 // CHECK: [[v3b0:%\d+]] = OpConstantNull %v3bool
 // CHECK: [[v4f0:%\d+]] = OpConstantNull %v4float
 
-// CHECK: %ga = OpVariable %_ptr_Private_int Private %int_6
+// CHECK: %ga = OpVariable %_ptr_Private_int Private
 static int ga = 6;
-// CHECK: %gb = OpVariable %_ptr_Private_v3bool Private [[v3b0]]
+// CHECK: %gb = OpVariable %_ptr_Private_v3bool Private
 static bool3 gb;
 // The front end has no const evaluation support for HLSL specific types.
 // So the following will ends up trying to create an OpStore into gc. We emit
@@ -15,15 +15,18 @@ static bool3 gb;
 // InitListHandler.
 static float2x2 gc = {1, 2, 3, 4};
 
-// CHECK: %a = OpVariable %_ptr_Private_uint Private %uint_5
-// CHECK: %b = OpVariable %_ptr_Private_v4float Private [[v4f0]]
+// CHECK: %a = OpVariable %_ptr_Private_uint Private
+// CHECK: %init_done_a = OpVariable %_ptr_Private_bool Private %false
+// CHECK: %b = OpVariable %_ptr_Private_v4float Private
+// CHECK: %init_done_b = OpVariable %_ptr_Private_bool Private %false
 // CHECK: %c = OpVariable %_ptr_Private_int Private
-
 // CHECK: %init_done_c = OpVariable %_ptr_Private_bool Private %false
 
-    // initialization of gc appears at the beginning of the entry function wrapper
+    // initialization of ga, gb, and gc appears at the beginning of the entry function wrapper
 // CHECK-LABEL: OpLabel
-// CHECK:      [[v2f12:%\d+]] = OpCompositeConstruct %v2float %float_1 %float_2
+// CHECK:      OpStore %ga %int_6
+// CHECK-NEXT: OpStore %gb [[v3b0]]
+// CHECK-NEXT: [[v2f12:%\d+]] = OpCompositeConstruct %v2float %float_1 %float_2
 // CHECK-NEXT: [[v2f34:%\d+]] = OpCompositeConstruct %v2float %float_3 %float_4
 // CHECK-NEXT: [[mat1234:%\d+]] = OpCompositeConstruct %mat2v2float [[v2f12]] [[v2f34]]
 // CHECK-NEXT: OpStore %gc [[mat1234]]
@@ -33,19 +36,36 @@ static float2x2 gc = {1, 2, 3, 4};
 int main(int input: A) : B {
 // CHECK-LABEL: %bb_entry = OpLabel
 
+// CHECK-NEXT: [[initdonea:%\d+]] = OpLoad %bool %init_done_a
+// CHECK-NEXT: OpSelectionMerge %if_merge None
+// CHECK-NEXT: OpBranchConditional [[initdonea]] %if_true %if_merge
+// CHECK-NEXT: %if_true = OpLabel
+// CHECK-NEXT: OpStore %a %uint_5
+// CHECK-NEXT: OpStore %init_done_a %true
+// CHECK-NEXT: OpBranch %if_merge
     static uint a = 5;    // const init
+// CHECK-NEXT: %if_merge = OpLabel
+
+// CHECK-NEXT: [[initdoneb:%\d+]] = OpLoad %bool %init_done_b
+// CHECK-NEXT: OpSelectionMerge %if_merge_0 None
+// CHECK-NEXT: OpBranchConditional [[initdoneb]] %if_true_0 %if_merge_0
+// CHECK-NEXT: %if_true_0 = OpLabel
+// CHECK-NEXT: OpStore %b [[v4f0]]
+// CHECK-NEXT: OpStore %init_done_b %true
+// CHECK-NEXT: OpBranch %if_merge_0
     static float4 b;      // no init
+// CHECK-NEXT: %if_merge_0 = OpLabel
 
 // CHECK-NEXT: [[initdonec:%\d+]] = OpLoad %bool %init_done_c
-// CHECK-NEXT: OpSelectionMerge %if_merge None
-// CHECK-NEXT: OpBranchConditional [[initdonec]] %if_true %if_merge
-// CHECK-NEXT: %if_true = OpLabel
+// CHECK-NEXT: OpSelectionMerge %if_merge_1 None
+// CHECK-NEXT: OpBranchConditional [[initdonec]] %if_true_1 %if_merge_1
+// CHECK-NEXT: %if_true_1 = OpLabel
 // CHECK-NEXT: [[initc:%\d+]] = OpLoad %int %input
 // CHECK-NEXT: OpStore %c [[initc]]
 // CHECK-NEXT: OpStore %init_done_c %true
-// CHECK-NEXT: OpBranch %if_merge
+// CHECK-NEXT: OpBranch %if_merge_1
     static int c = input; // var init
-// CHECK-NEXT: %if_merge = OpLabel
+// CHECK-NEXT: %if_merge_1 = OpLabel
 
     return input;
 }