Merge pull request #232 from Qining/fix-spec-const-bool-to-int-conversion

SPV: SpecOp bool->uint/int and uint<->int conversion
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 9249574..39f3b8b 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1960,7 +1960,6 @@
     glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim);
     if (specNode != nullptr) {
         builder.clearAccessChain();
-        // SpecConstantOpModeGuard set_to_spec_const_mode(&builder);
         specNode->traverse(this);
         return accessChainLoad(specNode->getAsTyped()->getType());
     }
@@ -3308,6 +3307,15 @@
 
     case glslang::EOpConvUintToInt:
     case glslang::EOpConvIntToUint:
+        if (builder.isInSpecConstCodeGenMode()) {
+            // Build zero scalar or vector for OpIAdd.
+            zero = builder.makeUintConstant(0);
+            zero = makeSmearedConstant(zero, vectorSize);
+            // Use OpIAdd, instead of OpBitcast to do the conversion when
+            // generating for OpSpecConstantOp instruction.
+            return builder.createBinOp(spv::OpIAdd, destType, operand, zero);
+        }
+        // For normal run-time conversion instruction, use OpBitcast.
         convOp = spv::OpBitcast;
         break;
 
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index f69e7fe..7896deb 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1212,6 +1212,16 @@
 
 Id Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3)
 {
+    // Generate code for spec constants if in spec constant operation
+    // generation mode.
+    if (generatingOpCodeForSpecConst) {
+        std::vector<Id> operands(3);
+        operands[0] = op1;
+        operands[1] = op2;
+        operands[2] = op3;
+        return createSpecConstantOp(
+            opCode, typeId, operands, std::vector<Id>());
+    }
     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
     op->addIdOperand(op1);
     op->addIdOperand(op2);
diff --git a/Test/baseResults/spv.specConstantOperations.vert.out b/Test/baseResults/spv.specConstantOperations.vert.out
index 76853d6..eedbea5 100644
--- a/Test/baseResults/spv.specConstantOperations.vert.out
+++ b/Test/baseResults/spv.specConstantOperations.vert.out
@@ -7,7 +7,7 @@
 
 // Module Version 10000
 // Generated by (magic number): 80001
-// Id's are bound by 101
+// Id's are bound by 134
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
@@ -16,109 +16,152 @@
                               Source GLSL 450
                               Name 4  "main"
                               Name 8  "non_const_array_size_from_spec_const("
-                              Name 15  "array"
-                              Decorate 10 SpecId 201
-                              Decorate 24 SpecId 200
-                              Decorate 26 SpecId 202
-                              Decorate 27 SpecId 203
+                              Name 11  "i"
+                              Name 27  "array"
+                              Decorate 19 SpecId 201
+                              Decorate 40 SpecId 200
+                              Decorate 42 SpecId 202
+                              Decorate 43 SpecId 203
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeInt 32 1
                7:             TypeFunction 6(int)
-              10:      6(int) SpecConstant 10
-              11:      6(int) Constant 2
-              12:      6(int) SpecConstantOp 128 10 11
-              13:             TypeArray 6(int) 12
-              14:             TypePointer Function 13
-              16:      6(int) Constant 1
-              17:      6(int) SpecConstantOp 128 10 16
-              18:             TypePointer Function 6(int)
-              23:             TypeFloat 32
-              24:   23(float) SpecConstant 1078530010
-              25:             TypeInt 32 0
-              26:     25(int) SpecConstant 100
-              27:      6(int) SpecConstant 4294967286
-              28:      6(int) SpecConstantOp 126 10
-              29:      6(int) SpecConstantOp 200 10
-              30:      6(int) SpecConstantOp 128 10 11
-              31:      6(int) SpecConstantOp 128 10 11
-              32:      6(int) Constant 3
-              33:      6(int) SpecConstantOp 130 31 32
-              34:      6(int) Constant 4
-              35:      6(int) SpecConstantOp 130 30 34
-              36:      6(int) SpecConstantOp 132 27 11
-              37:     25(int) Constant 2
-              38:     25(int) SpecConstantOp 132 26 37
-              39:      6(int) Constant 5
-              40:      6(int) SpecConstantOp 135 36 39
-              41:     25(int) Constant 5
-              42:     25(int) SpecConstantOp 134 38 41
-              43:      6(int) SpecConstantOp 139 27 34
-              44:     25(int) Constant 4
-              45:     25(int) SpecConstantOp 137 26 44
-              46:      6(int) SpecConstantOp 132 27 32
-              47:      6(int) SpecConstantOp 135 46 39
-              48:      6(int) Constant 10
-              49:      6(int) SpecConstantOp 195 27 48
-              50:      6(int) Constant 20
-              51:     25(int) SpecConstantOp 194 26 50
-              52:      6(int) SpecConstantOp 196 27 16
-              53:     25(int) SpecConstantOp 196 26 11
-              54:      6(int) Constant 256
-              55:      6(int) SpecConstantOp 197 27 54
-              56:     25(int) Constant 512
-              57:     25(int) SpecConstantOp 198 26 56
-              58:             TypeBool
-              59:    58(bool) SpecConstantOp 177 10 27
-              60:    58(bool) SpecConstantOp 170 26 26
-              61:    58(bool) SpecConstantOp 173 10 27
-              62:             TypeVector 6(int) 4
-              63:      6(int) Constant 30
-              64:   62(ivec4) SpecConstantComposite 50 63 10 10
-              65:             TypeVector 25(int) 4
-              66:     25(int) Constant 4294967295
-              67:     25(int) Constant 4294967294
-              68:   65(ivec4) SpecConstantComposite 26 26 66 67
-              69:             TypeVector 23(float) 4
-              70:   23(float) Constant 1067450368
-              71:   69(fvec4) SpecConstantComposite 24 70 24 70
-              72:   62(ivec4) SpecConstantOp 200 64
-              73:   62(ivec4) SpecConstantOp 126 64
-              74:   62(ivec4) ConstantComposite 11 11 11 11
-              75:   62(ivec4) SpecConstantOp 128 64 74
-              76:   62(ivec4) SpecConstantOp 128 64 74
-              77:   62(ivec4) ConstantComposite 32 32 32 32
-              78:   62(ivec4) SpecConstantOp 130 76 77
-              79:   62(ivec4) ConstantComposite 34 34 34 34
-              80:   62(ivec4) SpecConstantOp 130 78 79
-              81:   62(ivec4) SpecConstantOp 132 64 74
-              82:   62(ivec4) ConstantComposite 39 39 39 39
-              83:   62(ivec4) SpecConstantOp 135 81 82
-              84:   62(ivec4) SpecConstantOp 139 64 79
-              85:   62(ivec4) ConstantComposite 48 48 48 48
-              86:   62(ivec4) SpecConstantOp 195 64 85
-              87:   62(ivec4) SpecConstantOp 196 64 74
-              88:      6(int) Constant 1024
-              89:   62(ivec4) ConstantComposite 88 88 88 88
-              90:   62(ivec4) SpecConstantOp 197 64 89
-              91:     25(int) Constant 2048
-              92:   65(ivec4) ConstantComposite 91 91 91 91
-              93:   65(ivec4) SpecConstantOp 198 68 92
-              94:     25(int) Constant 0
-              95:      6(int) SpecConstantOp 81 64 0
-              96:             TypeVector 6(int) 2
-              97:   96(ivec2) SpecConstantOp 79 64 64 1(GLSL.std.450) 0
-              98:             TypeVector 6(int) 3
-              99:   98(ivec3) SpecConstantOp 79 64 64 2 1(GLSL.std.450) 0
-             100:   62(ivec4) SpecConstantOp 79 64 64 1(GLSL.std.450) 2 0 3
+              10:             TypePointer Function 6(int)
+              12:      6(int) Constant 0
+              19:      6(int) SpecConstant 10
+              20:      6(int) Constant 2
+              21:      6(int) SpecConstantOp 128 19 20
+              22:             TypeBool
+              24:      6(int) SpecConstantOp 128 19 20
+              25:             TypeArray 6(int) 24
+              26:             TypePointer Function 25
+              29:      6(int) Constant 1023
+              32:      6(int) Constant 1
+              34:      6(int) SpecConstantOp 128 19 32
+              39:             TypeFloat 32
+              40:   39(float) SpecConstant 1078530010
+              41:             TypeInt 32 0
+              42:     41(int) SpecConstant 100
+              43:      6(int) SpecConstant 4294967286
+              44:     41(int) Constant 0
+              45:    22(bool) SpecConstantOp 171 19 44
+              46:    22(bool) SpecConstantOp 171 42 44
+              47:      6(int) SpecConstantOp 169 45 32 12
+              48:     41(int) Constant 1
+              49:     41(int) SpecConstantOp 169 45 48 44
+              50:     41(int) SpecConstantOp 128 43 44
+              51:      6(int) SpecConstantOp 128 42 44
+              52:      6(int) SpecConstantOp 126 19
+              53:      6(int) SpecConstantOp 200 19
+              54:      6(int) SpecConstantOp 128 19 20
+              55:      6(int) SpecConstantOp 128 19 20
+              56:      6(int) Constant 3
+              57:      6(int) SpecConstantOp 130 55 56
+              58:      6(int) Constant 4
+              59:      6(int) SpecConstantOp 130 54 58
+              60:      6(int) SpecConstantOp 132 43 20
+              61:     41(int) Constant 2
+              62:     41(int) SpecConstantOp 132 42 61
+              63:      6(int) Constant 5
+              64:      6(int) SpecConstantOp 135 60 63
+              65:     41(int) Constant 5
+              66:     41(int) SpecConstantOp 134 62 65
+              67:      6(int) SpecConstantOp 139 43 58
+              68:     41(int) Constant 4
+              69:     41(int) SpecConstantOp 137 42 68
+              70:      6(int) SpecConstantOp 132 43 56
+              71:      6(int) SpecConstantOp 135 70 63
+              72:      6(int) Constant 10
+              73:      6(int) SpecConstantOp 195 43 72
+              74:      6(int) Constant 20
+              75:     41(int) SpecConstantOp 194 42 74
+              76:      6(int) SpecConstantOp 196 43 32
+              77:     41(int) SpecConstantOp 196 42 20
+              78:      6(int) Constant 256
+              79:      6(int) SpecConstantOp 197 43 78
+              80:     41(int) Constant 512
+              81:     41(int) SpecConstantOp 198 42 80
+              82:    22(bool) SpecConstantOp 177 19 43
+              83:    22(bool) SpecConstantOp 170 42 42
+              84:    22(bool) SpecConstantOp 173 19 43
+              85:             TypeVector 6(int) 4
+              86:      6(int) Constant 30
+              87:   85(ivec4) SpecConstantComposite 74 86 19 19
+              88:             TypeVector 41(int) 4
+              89:     41(int) Constant 4294967295
+              90:     41(int) Constant 4294967294
+              91:   88(ivec4) SpecConstantComposite 42 42 89 90
+              92:             TypeVector 39(float) 4
+              93:   39(float) Constant 1067450368
+              94:   92(fvec4) SpecConstantComposite 40 93 40 93
+              95:             TypeVector 22(bool) 4
+              96:   88(ivec4) ConstantComposite 44 44 44 44
+              97:   95(bvec4) SpecConstantOp 171 87 96
+              98:   95(bvec4) SpecConstantOp 171 91 96
+              99:   85(ivec4) ConstantComposite 12 12 12 12
+             100:   85(ivec4) ConstantComposite 32 32 32 32
+             101:   85(ivec4) SpecConstantOp 169 97 100 99
+             102:   88(ivec4) ConstantComposite 48 48 48 48
+             103:   88(ivec4) SpecConstantOp 169 97 102 96
+             104:   88(ivec4) SpecConstantOp 128 87 96
+             105:   85(ivec4) SpecConstantOp 128 91 96
+             106:   85(ivec4) SpecConstantOp 200 87
+             107:   85(ivec4) SpecConstantOp 126 87
+             108:   85(ivec4) ConstantComposite 20 20 20 20
+             109:   85(ivec4) SpecConstantOp 128 87 108
+             110:   85(ivec4) SpecConstantOp 128 87 108
+             111:   85(ivec4) ConstantComposite 56 56 56 56
+             112:   85(ivec4) SpecConstantOp 130 110 111
+             113:   85(ivec4) ConstantComposite 58 58 58 58
+             114:   85(ivec4) SpecConstantOp 130 112 113
+             115:   85(ivec4) SpecConstantOp 132 87 108
+             116:   85(ivec4) ConstantComposite 63 63 63 63
+             117:   85(ivec4) SpecConstantOp 135 115 116
+             118:   85(ivec4) SpecConstantOp 139 87 113
+             119:   85(ivec4) ConstantComposite 72 72 72 72
+             120:   85(ivec4) SpecConstantOp 195 87 119
+             121:   85(ivec4) SpecConstantOp 196 87 108
+             122:      6(int) Constant 1024
+             123:   85(ivec4) ConstantComposite 122 122 122 122
+             124:   85(ivec4) SpecConstantOp 197 87 123
+             125:     41(int) Constant 2048
+             126:   88(ivec4) ConstantComposite 125 125 125 125
+             127:   88(ivec4) SpecConstantOp 198 91 126
+             128:      6(int) SpecConstantOp 81 87 0
+             129:             TypeVector 6(int) 2
+             130:  129(ivec2) SpecConstantOp 79 87 87 1(GLSL.std.450) 0
+             131:             TypeVector 6(int) 3
+             132:  131(ivec3) SpecConstantOp 79 87 87 2 1(GLSL.std.450) 0
+             133:   85(ivec4) SpecConstantOp 79 87 87 1(GLSL.std.450) 2 0 3
          4(main):           2 Function None 3
                5:             Label
                               Return
                               FunctionEnd
 8(non_const_array_size_from_spec_const():      6(int) Function None 7
                9:             Label
-       15(array):     14(ptr) Variable Function
-              19:     18(ptr) AccessChain 15(array) 17
-              20:      6(int) Load 19
-                              ReturnValue 20
+           11(i):     10(ptr) Variable Function
+       27(array):     26(ptr) Variable Function
+                              Store 11(i) 12
+                              Branch 13
+              13:             Label
+                              LoopMerge 15 16 None
+                              Branch 17
+              17:             Label
+              18:      6(int) Load 11(i)
+              23:    22(bool) SLessThan 18 21
+                              BranchConditional 23 14 15
+              14:               Label
+              28:      6(int)   Load 11(i)
+              30:     10(ptr)   AccessChain 27(array) 28
+                                Store 30 29
+                                Branch 16
+              16:               Label
+              31:      6(int)   Load 11(i)
+              33:      6(int)   IAdd 31 32
+                                Store 11(i) 33
+                                Branch 13
+              15:             Label
+              35:     10(ptr) AccessChain 27(array) 34
+              36:      6(int) Load 35
+                              ReturnValue 36
                               FunctionEnd
diff --git a/Test/spv.specConstantOperations.vert b/Test/spv.specConstantOperations.vert
index 91920cf..f2d57bf 100644
--- a/Test/spv.specConstantOperations.vert
+++ b/Test/spv.specConstantOperations.vert
@@ -10,9 +10,15 @@
 // Scalars
 //
 
-// Size convert
-//const double float_to_double = double(sp_float);
-//const float double_to_float = float(float_to_double);
+// uint/int <-> bool conversion
+const bool bool_from_int = bool(sp_int);
+const bool bool_from_uint = bool(sp_uint);
+const int int_from_bool = int(bool_from_int);
+const uint uint_from_bool = uint(bool_from_int);
+
+// uint <-> int
+const uint sp_uint_from_sint = uint(sp_sint);
+const int sp_sint_from_uint = int(sp_uint);
 
 // Negate and Not
 const int negate_int = -sp_int;
@@ -54,9 +60,15 @@
 const uvec4 uv = uvec4(sp_uint, sp_uint, -1, -2);
 const vec4 fv = vec4(sp_float, 1.25, sp_float, 1.25);
 
-// Size convert
-//const dvec4 fv_to_dv = dvec4(fv);
-//const vec4 dv_to_fv = vec4(fv_to_dv);
+// uint/int <-> bool conversion
+const bvec4 bv_from_iv = bvec4(iv);
+const bvec4 bv_from_uv = bvec4(uv);
+const ivec4 iv_from_bv = ivec4(bv_from_iv);
+const uvec4 uv_from_bv = uvec4(bv_from_iv);
+
+// uint <-> int
+const uvec4 uv_from_iv = uvec4(iv);
+const ivec4 iv_from_uv = ivec4(uv);
 
 // Negate and Not
 const ivec4 not_iv = ~iv;
@@ -88,6 +100,9 @@
 
 int non_const_array_size_from_spec_const() {
     int array[sp_int + 2];
+    for (int i = 0; i < sp_int + 2; i++) {
+        array[i] = 1023;
+    }
     return array[sp_int + 1];
 }