HLSL: Fix unary and binary operator type conversion issues

This fixes defects as follows:

1. handleLvalue could be called on a non-L-value, and it shouldn't be.

2. HLSL allows unary negation on non-bool values.  TUnaryOperator::promote
   can now promote other types (e.g, int, float) to bool for this op.

3. HLSL allows binary logical operations (&&, ||) on arbitrary types, similar
   (2).

4. HLSL allows mod operation on arbitrary types, which will be promoted.
   E.g, int % float -> float % float.
diff --git a/Test/baseResults/hlsl.logical.binary.frag.out b/Test/baseResults/hlsl.logical.binary.frag.out
new file mode 100644
index 0000000..9e6593e
--- /dev/null
+++ b/Test/baseResults/hlsl.logical.binary.frag.out
@@ -0,0 +1,220 @@
+hlsl.logical.binary.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: main( (temp structure{temp 4-component vector of float Color})
+0:12    Function Parameters: 
+0:?     Sequence
+0:13      Test condition and select (temp void)
+0:13        Condition
+0:13        logical-and (temp bool)
+0:13          Convert int to bool (temp bool)
+0:13            ival: direct index for structure (layout(offset=0 ) uniform int)
+0:13              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:13              Constant:
+0:13                0 (const uint)
+0:13          Convert int to bool (temp bool)
+0:13            Convert float to int (temp int)
+0:13              fval: direct index for structure (layout(offset=32 ) uniform float)
+0:13                'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:13                Constant:
+0:13                  2 (const uint)
+0:13        true case is null
+0:14      Test condition and select (temp void)
+0:14        Condition
+0:14        logical-or (temp bool)
+0:14          Convert int to bool (temp bool)
+0:14            ival: direct index for structure (layout(offset=0 ) uniform int)
+0:14              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:14              Constant:
+0:14                0 (const uint)
+0:14          Convert int to bool (temp bool)
+0:14            Convert float to int (temp int)
+0:14              fval: direct index for structure (layout(offset=32 ) uniform float)
+0:14                'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:14                Constant:
+0:14                  2 (const uint)
+0:14        true case is null
+0:17      move second child to first child (temp 4-component vector of float)
+0:17        Color: direct index for structure (temp 4-component vector of float)
+0:17          'psout' (temp structure{temp 4-component vector of float Color})
+0:17          Constant:
+0:17            0 (const int)
+0:17        Constant:
+0:17          1.000000
+0:17          1.000000
+0:17          1.000000
+0:17          1.000000
+0:18      Sequence
+0:18        Sequence
+0:18          move second child to first child (temp 4-component vector of float)
+0:?             'Color' (layout(location=0 ) out 4-component vector of float)
+0:18            Color: direct index for structure (temp 4-component vector of float)
+0:18              'psout' (temp structure{temp 4-component vector of float Color})
+0:18              Constant:
+0:18                0 (const int)
+0:18        Branch: Return
+0:?   Linker Objects
+0:?     'Color' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: main( (temp structure{temp 4-component vector of float Color})
+0:12    Function Parameters: 
+0:?     Sequence
+0:13      Test condition and select (temp void)
+0:13        Condition
+0:13        logical-and (temp bool)
+0:13          Convert int to bool (temp bool)
+0:13            ival: direct index for structure (layout(offset=0 ) uniform int)
+0:13              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:13              Constant:
+0:13                0 (const uint)
+0:13          Convert int to bool (temp bool)
+0:13            Convert float to int (temp int)
+0:13              fval: direct index for structure (layout(offset=32 ) uniform float)
+0:13                'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:13                Constant:
+0:13                  2 (const uint)
+0:13        true case is null
+0:14      Test condition and select (temp void)
+0:14        Condition
+0:14        logical-or (temp bool)
+0:14          Convert int to bool (temp bool)
+0:14            ival: direct index for structure (layout(offset=0 ) uniform int)
+0:14              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:14              Constant:
+0:14                0 (const uint)
+0:14          Convert int to bool (temp bool)
+0:14            Convert float to int (temp int)
+0:14              fval: direct index for structure (layout(offset=32 ) uniform float)
+0:14                'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:14                Constant:
+0:14                  2 (const uint)
+0:14        true case is null
+0:17      move second child to first child (temp 4-component vector of float)
+0:17        Color: direct index for structure (temp 4-component vector of float)
+0:17          'psout' (temp structure{temp 4-component vector of float Color})
+0:17          Constant:
+0:17            0 (const int)
+0:17        Constant:
+0:17          1.000000
+0:17          1.000000
+0:17          1.000000
+0:17          1.000000
+0:18      Sequence
+0:18        Sequence
+0:18          move second child to first child (temp 4-component vector of float)
+0:?             'Color' (layout(location=0 ) out 4-component vector of float)
+0:18            Color: direct index for structure (temp 4-component vector of float)
+0:18              'psout' (temp structure{temp 4-component vector of float Color})
+0:18              Constant:
+0:18                0 (const int)
+0:18        Branch: Return
+0:?   Linker Objects
+0:?     'Color' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 57
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 53
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 11  "$Global"
+                              MemberName 11($Global) 0  "ival"
+                              MemberName 11($Global) 1  "ival4"
+                              MemberName 11($Global) 2  "fval"
+                              MemberName 11($Global) 3  "fval4"
+                              Name 13  ""
+                              Name 45  "PS_OUTPUT"
+                              MemberName 45(PS_OUTPUT) 0  "Color"
+                              Name 47  "psout"
+                              Name 53  "Color"
+                              MemberDecorate 11($Global) 0 Offset 0
+                              MemberDecorate 11($Global) 1 Offset 16
+                              MemberDecorate 11($Global) 2 Offset 32
+                              MemberDecorate 11($Global) 3 Offset 48
+                              Decorate 11($Global) Block
+                              Decorate 13 DescriptorSet 0
+                              Decorate 53(Color) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeBool
+               7:             TypeInt 32 1
+               8:             TypeVector 7(int) 4
+               9:             TypeFloat 32
+              10:             TypeVector 9(float) 4
+     11($Global):             TypeStruct 7(int) 8(ivec4) 9(float) 10(fvec4)
+              12:             TypePointer Uniform 11($Global)
+              13:     12(ptr) Variable Uniform
+              14:      7(int) Constant 0
+              15:             TypePointer Uniform 7(int)
+              18:             TypeInt 32 0
+              19:     18(int) Constant 0
+              23:      7(int) Constant 2
+              24:             TypePointer Uniform 9(float)
+   45(PS_OUTPUT):             TypeStruct 10(fvec4)
+              46:             TypePointer Function 45(PS_OUTPUT)
+              48:    9(float) Constant 1065353216
+              49:   10(fvec4) ConstantComposite 48 48 48 48
+              50:             TypePointer Function 10(fvec4)
+              52:             TypePointer Output 10(fvec4)
+       53(Color):     52(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+       47(psout):     46(ptr) Variable Function
+              16:     15(ptr) AccessChain 13 14
+              17:      7(int) Load 16
+              20:     6(bool) INotEqual 17 19
+                              SelectionMerge 22 None
+                              BranchConditional 20 21 22
+              21:               Label
+              25:     24(ptr)   AccessChain 13 23
+              26:    9(float)   Load 25
+              27:      7(int)   ConvertFToS 26
+              28:     6(bool)   INotEqual 27 19
+                                Branch 22
+              22:             Label
+              29:     6(bool) Phi 20 5 28 21
+                              SelectionMerge 31 None
+                              BranchConditional 29 30 31
+              30:               Label
+                                Branch 31
+              31:             Label
+              32:     15(ptr) AccessChain 13 14
+              33:      7(int) Load 32
+              34:     6(bool) INotEqual 33 19
+              35:     6(bool) LogicalNot 34
+                              SelectionMerge 37 None
+                              BranchConditional 35 36 37
+              36:               Label
+              38:     24(ptr)   AccessChain 13 23
+              39:    9(float)   Load 38
+              40:      7(int)   ConvertFToS 39
+              41:     6(bool)   INotEqual 40 19
+                                Branch 37
+              37:             Label
+              42:     6(bool) Phi 34 31 41 36
+                              SelectionMerge 44 None
+                              BranchConditional 42 43 44
+              43:               Label
+                                Branch 44
+              44:             Label
+              51:     50(ptr) AccessChain 47(psout) 14
+                              Store 51 49
+              54:     50(ptr) AccessChain 47(psout) 14
+              55:   10(fvec4) Load 54
+                              Store 53(Color) 55
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.logical.unary.frag.out b/Test/baseResults/hlsl.logical.unary.frag.out
new file mode 100644
index 0000000..e3def3c
--- /dev/null
+++ b/Test/baseResults/hlsl.logical.unary.frag.out
@@ -0,0 +1,292 @@
+hlsl.logical.unary.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: main( (temp structure{temp 4-component vector of float Color})
+0:12    Function Parameters: 
+0:?     Sequence
+0:13      Negate conditional (temp bool)
+0:13        Convert int to bool (temp bool)
+0:13          ival: direct index for structure (layout(offset=0 ) uniform int)
+0:13            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:13            Constant:
+0:13              0 (const uint)
+0:14      Negate conditional (temp 4-component vector of bool)
+0:14        Convert int to bool (temp 4-component vector of bool)
+0:14          ival4: direct index for structure (layout(offset=16 ) uniform 4-component vector of int)
+0:14            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:14            Constant:
+0:14              1 (const uint)
+0:16      Negate conditional (temp bool)
+0:16        Convert float to bool (temp bool)
+0:16          fval: direct index for structure (layout(offset=32 ) uniform float)
+0:16            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:16            Constant:
+0:16              2 (const uint)
+0:17      Negate conditional (temp 4-component vector of bool)
+0:17        Convert float to bool (temp 4-component vector of bool)
+0:17          fval4: direct index for structure (layout(offset=48 ) uniform 4-component vector of float)
+0:17            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:17            Constant:
+0:17              3 (const uint)
+0:19      Test condition and select (temp void)
+0:19        Condition
+0:19        ival: direct index for structure (layout(offset=0 ) uniform int)
+0:19          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:19          Constant:
+0:19            0 (const uint)
+0:19        true case is null
+0:20      Test condition and select (temp void)
+0:20        Condition
+0:20        fval: direct index for structure (layout(offset=32 ) uniform float)
+0:20          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:20          Constant:
+0:20            2 (const uint)
+0:20        true case is null
+0:21      Test condition and select (temp void)
+0:21        Condition
+0:21        Negate conditional (temp bool)
+0:21          Convert int to bool (temp bool)
+0:21            ival: direct index for structure (layout(offset=0 ) uniform int)
+0:21              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:21              Constant:
+0:21                0 (const uint)
+0:21        true case is null
+0:22      Test condition and select (temp void)
+0:22        Condition
+0:22        Negate conditional (temp bool)
+0:22          Convert float to bool (temp bool)
+0:22            fval: direct index for structure (layout(offset=32 ) uniform float)
+0:22              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:22              Constant:
+0:22                2 (const uint)
+0:22        true case is null
+0:25      move second child to first child (temp 4-component vector of float)
+0:25        Color: direct index for structure (temp 4-component vector of float)
+0:25          'psout' (temp structure{temp 4-component vector of float Color})
+0:25          Constant:
+0:25            0 (const int)
+0:25        Constant:
+0:25          1.000000
+0:25          1.000000
+0:25          1.000000
+0:25          1.000000
+0:26      Sequence
+0:26        Sequence
+0:26          move second child to first child (temp 4-component vector of float)
+0:?             'Color' (layout(location=0 ) out 4-component vector of float)
+0:26            Color: direct index for structure (temp 4-component vector of float)
+0:26              'psout' (temp structure{temp 4-component vector of float Color})
+0:26              Constant:
+0:26                0 (const int)
+0:26        Branch: Return
+0:?   Linker Objects
+0:?     'Color' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: main( (temp structure{temp 4-component vector of float Color})
+0:12    Function Parameters: 
+0:?     Sequence
+0:13      Negate conditional (temp bool)
+0:13        Convert int to bool (temp bool)
+0:13          ival: direct index for structure (layout(offset=0 ) uniform int)
+0:13            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:13            Constant:
+0:13              0 (const uint)
+0:14      Negate conditional (temp 4-component vector of bool)
+0:14        Convert int to bool (temp 4-component vector of bool)
+0:14          ival4: direct index for structure (layout(offset=16 ) uniform 4-component vector of int)
+0:14            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:14            Constant:
+0:14              1 (const uint)
+0:16      Negate conditional (temp bool)
+0:16        Convert float to bool (temp bool)
+0:16          fval: direct index for structure (layout(offset=32 ) uniform float)
+0:16            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:16            Constant:
+0:16              2 (const uint)
+0:17      Negate conditional (temp 4-component vector of bool)
+0:17        Convert float to bool (temp 4-component vector of bool)
+0:17          fval4: direct index for structure (layout(offset=48 ) uniform 4-component vector of float)
+0:17            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:17            Constant:
+0:17              3 (const uint)
+0:19      Test condition and select (temp void)
+0:19        Condition
+0:19        ival: direct index for structure (layout(offset=0 ) uniform int)
+0:19          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:19          Constant:
+0:19            0 (const uint)
+0:19        true case is null
+0:20      Test condition and select (temp void)
+0:20        Condition
+0:20        fval: direct index for structure (layout(offset=32 ) uniform float)
+0:20          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:20          Constant:
+0:20            2 (const uint)
+0:20        true case is null
+0:21      Test condition and select (temp void)
+0:21        Condition
+0:21        Negate conditional (temp bool)
+0:21          Convert int to bool (temp bool)
+0:21            ival: direct index for structure (layout(offset=0 ) uniform int)
+0:21              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:21              Constant:
+0:21                0 (const uint)
+0:21        true case is null
+0:22      Test condition and select (temp void)
+0:22        Condition
+0:22        Negate conditional (temp bool)
+0:22          Convert float to bool (temp bool)
+0:22            fval: direct index for structure (layout(offset=32 ) uniform float)
+0:22              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+0:22              Constant:
+0:22                2 (const uint)
+0:22        true case is null
+0:25      move second child to first child (temp 4-component vector of float)
+0:25        Color: direct index for structure (temp 4-component vector of float)
+0:25          'psout' (temp structure{temp 4-component vector of float Color})
+0:25          Constant:
+0:25            0 (const int)
+0:25        Constant:
+0:25          1.000000
+0:25          1.000000
+0:25          1.000000
+0:25          1.000000
+0:26      Sequence
+0:26        Sequence
+0:26          move second child to first child (temp 4-component vector of float)
+0:?             'Color' (layout(location=0 ) out 4-component vector of float)
+0:26            Color: direct index for structure (temp 4-component vector of float)
+0:26              'psout' (temp structure{temp 4-component vector of float Color})
+0:26              Constant:
+0:26                0 (const int)
+0:26        Branch: Return
+0:?   Linker Objects
+0:?     'Color' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (uniform block{layout(offset=0 ) uniform int ival, layout(offset=16 ) uniform 4-component vector of int ival4, layout(offset=32 ) uniform float fval, layout(offset=48 ) uniform 4-component vector of float fval4})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 77
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 73
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 10  "$Global"
+                              MemberName 10($Global) 0  "ival"
+                              MemberName 10($Global) 1  "ival4"
+                              MemberName 10($Global) 2  "fval"
+                              MemberName 10($Global) 3  "fval4"
+                              Name 12  ""
+                              Name 65  "PS_OUTPUT"
+                              MemberName 65(PS_OUTPUT) 0  "Color"
+                              Name 67  "psout"
+                              Name 73  "Color"
+                              MemberDecorate 10($Global) 0 Offset 0
+                              MemberDecorate 10($Global) 1 Offset 16
+                              MemberDecorate 10($Global) 2 Offset 32
+                              MemberDecorate 10($Global) 3 Offset 48
+                              Decorate 10($Global) Block
+                              Decorate 12 DescriptorSet 0
+                              Decorate 73(Color) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+               7:             TypeVector 6(int) 4
+               8:             TypeFloat 32
+               9:             TypeVector 8(float) 4
+     10($Global):             TypeStruct 6(int) 7(ivec4) 8(float) 9(fvec4)
+              11:             TypePointer Uniform 10($Global)
+              12:     11(ptr) Variable Uniform
+              13:      6(int) Constant 0
+              14:             TypePointer Uniform 6(int)
+              17:             TypeBool
+              18:             TypeInt 32 0
+              19:     18(int) Constant 0
+              22:      6(int) Constant 1
+              23:             TypePointer Uniform 7(ivec4)
+              26:             TypeVector 17(bool) 4
+              27:             TypeVector 18(int) 4
+              28:   27(ivec4) ConstantComposite 19 19 19 19
+              31:      6(int) Constant 2
+              32:             TypePointer Uniform 8(float)
+              35:    8(float) Constant 0
+              38:      6(int) Constant 3
+              39:             TypePointer Uniform 9(fvec4)
+              42:    9(fvec4) ConstantComposite 35 35 35 35
+   65(PS_OUTPUT):             TypeStruct 9(fvec4)
+              66:             TypePointer Function 65(PS_OUTPUT)
+              68:    8(float) Constant 1065353216
+              69:    9(fvec4) ConstantComposite 68 68 68 68
+              70:             TypePointer Function 9(fvec4)
+              72:             TypePointer Output 9(fvec4)
+       73(Color):     72(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+       67(psout):     66(ptr) Variable Function
+              15:     14(ptr) AccessChain 12 13
+              16:      6(int) Load 15
+              20:    17(bool) INotEqual 16 19
+              21:    17(bool) LogicalNot 20
+              24:     23(ptr) AccessChain 12 22
+              25:    7(ivec4) Load 24
+              29:   26(bvec4) INotEqual 25 28
+              30:   26(bvec4) LogicalNot 29
+              33:     32(ptr) AccessChain 12 31
+              34:    8(float) Load 33
+              36:    17(bool) FOrdNotEqual 34 35
+              37:    17(bool) LogicalNot 36
+              40:     39(ptr) AccessChain 12 38
+              41:    9(fvec4) Load 40
+              43:   26(bvec4) FOrdNotEqual 41 42
+              44:   26(bvec4) LogicalNot 43
+              45:     14(ptr) AccessChain 12 13
+              46:      6(int) Load 45
+                              SelectionMerge 48 None
+                              BranchConditional 46 47 48
+              47:               Label
+                                Branch 48
+              48:             Label
+              49:     32(ptr) AccessChain 12 31
+              50:    8(float) Load 49
+                              SelectionMerge 52 None
+                              BranchConditional 50 51 52
+              51:               Label
+                                Branch 52
+              52:             Label
+              53:     14(ptr) AccessChain 12 13
+              54:      6(int) Load 53
+              55:    17(bool) INotEqual 54 19
+              56:    17(bool) LogicalNot 55
+                              SelectionMerge 58 None
+                              BranchConditional 56 57 58
+              57:               Label
+                                Branch 58
+              58:             Label
+              59:     32(ptr) AccessChain 12 31
+              60:    8(float) Load 59
+              61:    17(bool) FOrdNotEqual 60 35
+              62:    17(bool) LogicalNot 61
+                              SelectionMerge 64 None
+                              BranchConditional 62 63 64
+              63:               Label
+                                Branch 64
+              64:             Label
+              71:     70(ptr) AccessChain 67(psout) 13
+                              Store 71 69
+              74:     70(ptr) AccessChain 67(psout) 13
+              75:    9(fvec4) Load 74
+                              Store 73(Color) 75
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.promote.binary.frag.out b/Test/baseResults/hlsl.promote.binary.frag.out
new file mode 100644
index 0000000..a2e7176
--- /dev/null
+++ b/Test/baseResults/hlsl.promote.binary.frag.out
@@ -0,0 +1,280 @@
+hlsl.promote.binary.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:14  Function Definition: main( (temp structure{temp 4-component vector of float Color})
+0:14    Function Parameters: 
+0:?     Sequence
+0:15      mod (temp float)
+0:15        Convert int to float (temp float)
+0:15          ival: direct index for structure (layout(offset=32 ) uniform int)
+0:15            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:15            Constant:
+0:15              2 (const uint)
+0:15        fval: direct index for structure (layout(offset=64 ) uniform float)
+0:15          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:15          Constant:
+0:15            4 (const uint)
+0:16      mod (temp 4-component vector of float)
+0:16        Convert int to float (temp 4-component vector of float)
+0:16          ival4: direct index for structure (layout(offset=48 ) uniform 4-component vector of int)
+0:16            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:16            Constant:
+0:16              3 (const uint)
+0:16        fval4: direct index for structure (layout(offset=80 ) uniform 4-component vector of float)
+0:16          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:16          Constant:
+0:16            5 (const uint)
+0:18      mod (temp float)
+0:18        Convert bool to float (temp float)
+0:18          bval: direct index for structure (layout(offset=0 ) uniform bool)
+0:18            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:18            Constant:
+0:18              0 (const uint)
+0:18        fval: direct index for structure (layout(offset=64 ) uniform float)
+0:18          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:18          Constant:
+0:18            4 (const uint)
+0:19      mod (temp 4-component vector of float)
+0:19        Convert bool to float (temp 4-component vector of float)
+0:19          bval4: direct index for structure (layout(offset=16 ) uniform 4-component vector of bool)
+0:19            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:19            Constant:
+0:19              1 (const uint)
+0:19        fval4: direct index for structure (layout(offset=80 ) uniform 4-component vector of float)
+0:19          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:19          Constant:
+0:19            5 (const uint)
+0:21      Sequence
+0:21        move second child to first child (temp int)
+0:21          'l_int' (temp int)
+0:21          Constant:
+0:21            1 (const int)
+0:22      mod second child into first child (temp int)
+0:22        'l_int' (temp int)
+0:22        Convert float to int (temp int)
+0:22          fval: direct index for structure (layout(offset=64 ) uniform float)
+0:22            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:22            Constant:
+0:22              4 (const uint)
+0:25      move second child to first child (temp 4-component vector of float)
+0:25        Color: direct index for structure (temp 4-component vector of float)
+0:25          'psout' (temp structure{temp 4-component vector of float Color})
+0:25          Constant:
+0:25            0 (const int)
+0:25        Constant:
+0:25          0.000000
+0:25          0.000000
+0:25          0.000000
+0:25          0.000000
+0:26      Sequence
+0:26        Sequence
+0:26          move second child to first child (temp 4-component vector of float)
+0:?             'Color' (layout(location=0 ) out 4-component vector of float)
+0:26            Color: direct index for structure (temp 4-component vector of float)
+0:26              'psout' (temp structure{temp 4-component vector of float Color})
+0:26              Constant:
+0:26                0 (const int)
+0:26        Branch: Return
+0:?   Linker Objects
+0:?     'Color' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:14  Function Definition: main( (temp structure{temp 4-component vector of float Color})
+0:14    Function Parameters: 
+0:?     Sequence
+0:15      mod (temp float)
+0:15        Convert int to float (temp float)
+0:15          ival: direct index for structure (layout(offset=32 ) uniform int)
+0:15            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:15            Constant:
+0:15              2 (const uint)
+0:15        fval: direct index for structure (layout(offset=64 ) uniform float)
+0:15          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:15          Constant:
+0:15            4 (const uint)
+0:16      mod (temp 4-component vector of float)
+0:16        Convert int to float (temp 4-component vector of float)
+0:16          ival4: direct index for structure (layout(offset=48 ) uniform 4-component vector of int)
+0:16            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:16            Constant:
+0:16              3 (const uint)
+0:16        fval4: direct index for structure (layout(offset=80 ) uniform 4-component vector of float)
+0:16          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:16          Constant:
+0:16            5 (const uint)
+0:18      mod (temp float)
+0:18        Convert bool to float (temp float)
+0:18          bval: direct index for structure (layout(offset=0 ) uniform bool)
+0:18            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:18            Constant:
+0:18              0 (const uint)
+0:18        fval: direct index for structure (layout(offset=64 ) uniform float)
+0:18          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:18          Constant:
+0:18            4 (const uint)
+0:19      mod (temp 4-component vector of float)
+0:19        Convert bool to float (temp 4-component vector of float)
+0:19          bval4: direct index for structure (layout(offset=16 ) uniform 4-component vector of bool)
+0:19            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:19            Constant:
+0:19              1 (const uint)
+0:19        fval4: direct index for structure (layout(offset=80 ) uniform 4-component vector of float)
+0:19          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:19          Constant:
+0:19            5 (const uint)
+0:21      Sequence
+0:21        move second child to first child (temp int)
+0:21          'l_int' (temp int)
+0:21          Constant:
+0:21            1 (const int)
+0:22      mod second child into first child (temp int)
+0:22        'l_int' (temp int)
+0:22        Convert float to int (temp int)
+0:22          fval: direct index for structure (layout(offset=64 ) uniform float)
+0:22            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+0:22            Constant:
+0:22              4 (const uint)
+0:25      move second child to first child (temp 4-component vector of float)
+0:25        Color: direct index for structure (temp 4-component vector of float)
+0:25          'psout' (temp structure{temp 4-component vector of float Color})
+0:25          Constant:
+0:25            0 (const int)
+0:25        Constant:
+0:25          0.000000
+0:25          0.000000
+0:25          0.000000
+0:25          0.000000
+0:26      Sequence
+0:26        Sequence
+0:26          move second child to first child (temp 4-component vector of float)
+0:?             'Color' (layout(location=0 ) out 4-component vector of float)
+0:26            Color: direct index for structure (temp 4-component vector of float)
+0:26              'psout' (temp structure{temp 4-component vector of float Color})
+0:26              Constant:
+0:26                0 (const int)
+0:26        Branch: Return
+0:?   Linker Objects
+0:?     'Color' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (uniform block{layout(offset=0 ) uniform bool bval, layout(offset=16 ) uniform 4-component vector of bool bval4, layout(offset=32 ) uniform int ival, layout(offset=48 ) uniform 4-component vector of int ival4, layout(offset=64 ) uniform float fval, layout(offset=80 ) uniform 4-component vector of float fval4})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 78
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 74
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 12  "$Global"
+                              MemberName 12($Global) 0  "bval"
+                              MemberName 12($Global) 1  "bval4"
+                              MemberName 12($Global) 2  "ival"
+                              MemberName 12($Global) 3  "ival4"
+                              MemberName 12($Global) 4  "fval"
+                              MemberName 12($Global) 5  "fval4"
+                              Name 14  ""
+                              Name 62  "l_int"
+                              Name 68  "PS_OUTPUT"
+                              MemberName 68(PS_OUTPUT) 0  "Color"
+                              Name 70  "psout"
+                              Name 74  "Color"
+                              MemberDecorate 12($Global) 0 Offset 0
+                              MemberDecorate 12($Global) 1 Offset 16
+                              MemberDecorate 12($Global) 2 Offset 32
+                              MemberDecorate 12($Global) 3 Offset 48
+                              MemberDecorate 12($Global) 4 Offset 64
+                              MemberDecorate 12($Global) 5 Offset 80
+                              Decorate 12($Global) Block
+                              Decorate 14 DescriptorSet 0
+                              Decorate 74(Color) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 0
+               7:             TypeVector 6(int) 4
+               8:             TypeInt 32 1
+               9:             TypeVector 8(int) 4
+              10:             TypeFloat 32
+              11:             TypeVector 10(float) 4
+     12($Global):             TypeStruct 6(int) 7(ivec4) 8(int) 9(ivec4) 10(float) 11(fvec4)
+              13:             TypePointer Uniform 12($Global)
+              14:     13(ptr) Variable Uniform
+              15:      8(int) Constant 2
+              16:             TypePointer Uniform 8(int)
+              20:      8(int) Constant 4
+              21:             TypePointer Uniform 10(float)
+              25:      8(int) Constant 3
+              26:             TypePointer Uniform 9(ivec4)
+              30:      8(int) Constant 5
+              31:             TypePointer Uniform 11(fvec4)
+              35:      8(int) Constant 0
+              36:             TypePointer Uniform 6(int)
+              39:             TypeBool
+              40:      6(int) Constant 0
+              42:   10(float) Constant 0
+              43:   10(float) Constant 1065353216
+              48:      8(int) Constant 1
+              49:             TypePointer Uniform 7(ivec4)
+              52:             TypeVector 39(bool) 4
+              53:    7(ivec4) ConstantComposite 40 40 40 40
+              55:   11(fvec4) ConstantComposite 42 42 42 42
+              56:   11(fvec4) ConstantComposite 43 43 43 43
+              61:             TypePointer Function 8(int)
+   68(PS_OUTPUT):             TypeStruct 11(fvec4)
+              69:             TypePointer Function 68(PS_OUTPUT)
+              71:             TypePointer Function 11(fvec4)
+              73:             TypePointer Output 11(fvec4)
+       74(Color):     73(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+       62(l_int):     61(ptr) Variable Function
+       70(psout):     69(ptr) Variable Function
+              17:     16(ptr) AccessChain 14 15
+              18:      8(int) Load 17
+              19:   10(float) ConvertSToF 18
+              22:     21(ptr) AccessChain 14 20
+              23:   10(float) Load 22
+              24:   10(float) FMod 19 23
+              27:     26(ptr) AccessChain 14 25
+              28:    9(ivec4) Load 27
+              29:   11(fvec4) ConvertSToF 28
+              32:     31(ptr) AccessChain 14 30
+              33:   11(fvec4) Load 32
+              34:   11(fvec4) FMod 29 33
+              37:     36(ptr) AccessChain 14 35
+              38:      6(int) Load 37
+              41:    39(bool) INotEqual 38 40
+              44:   10(float) Select 41 43 42
+              45:     21(ptr) AccessChain 14 20
+              46:   10(float) Load 45
+              47:   10(float) FMod 44 46
+              50:     49(ptr) AccessChain 14 48
+              51:    7(ivec4) Load 50
+              54:   52(bvec4) INotEqual 51 53
+              57:   11(fvec4) Select 54 56 55
+              58:     31(ptr) AccessChain 14 30
+              59:   11(fvec4) Load 58
+              60:   11(fvec4) FMod 57 59
+                              Store 62(l_int) 48
+              63:     21(ptr) AccessChain 14 20
+              64:   10(float) Load 63
+              65:      8(int) ConvertFToS 64
+              66:      8(int) Load 62(l_int)
+              67:      8(int) SMod 66 65
+                              Store 62(l_int) 67
+              72:     71(ptr) AccessChain 70(psout) 35
+                              Store 72 55
+              75:     71(ptr) AccessChain 70(psout) 35
+              76:   11(fvec4) Load 75
+                              Store 74(Color) 76
+                              Return
+                              FunctionEnd
diff --git a/Test/hlsl.logical.binary.frag b/Test/hlsl.logical.binary.frag
new file mode 100644
index 0000000..06bc9f2
--- /dev/null
+++ b/Test/hlsl.logical.binary.frag
@@ -0,0 +1,21 @@
+struct PS_OUTPUT
+{
+    float4 Color : SV_Target0;
+};
+
+uniform int    ival;
+uniform int4   ival4;
+uniform float  fval;
+uniform float4 fval4;
+
+PS_OUTPUT main()
+{
+    if (ival && fval);
+    if (ival || fval);
+
+    PS_OUTPUT psout;
+    psout.Color = 1.0;
+    return psout;
+}
+
+
diff --git a/Test/hlsl.logical.unary.frag b/Test/hlsl.logical.unary.frag
new file mode 100644
index 0000000..cbcb3bf
--- /dev/null
+++ b/Test/hlsl.logical.unary.frag
@@ -0,0 +1,29 @@
+struct PS_OUTPUT
+{
+    float4 Color : SV_Target0;
+};
+
+uniform int    ival;
+uniform int4   ival4;
+uniform float  fval;
+uniform float4 fval4;
+
+PS_OUTPUT main()
+{
+    !ival;  // scalar int
+    !ival4; // vector int
+
+    !fval;  // scalar float
+    !fval4; // vector float
+    
+    if (ival);
+    if (fval);
+    if (!ival);
+    if (!fval);
+
+    PS_OUTPUT psout;
+    psout.Color = 1.0;
+    return psout;
+}
+
+
diff --git a/Test/hlsl.promote.binary.frag b/Test/hlsl.promote.binary.frag
new file mode 100644
index 0000000..0203bed
--- /dev/null
+++ b/Test/hlsl.promote.binary.frag
@@ -0,0 +1,28 @@
+struct PS_OUTPUT
+{
+    float4 Color : SV_Target0;
+};
+
+uniform bool   bval;
+uniform bool4  bval4;
+uniform int    ival;
+uniform int4   ival4;
+uniform float  fval;
+uniform float4 fval4;
+
+PS_OUTPUT main()
+{
+    ival  % fval;
+    ival4 % fval4;
+
+    bval  % fval;
+    bval4 % fval4;
+
+    int l_int = 1;
+    l_int %= fval;
+
+    PS_OUTPUT psout;
+    psout.Color = 0;
+    return psout;
+}
+
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
index 27c798d..fc26754 100644
--- a/glslang/Include/intermediate.h
+++ b/glslang/Include/intermediate.h
@@ -52,6 +52,8 @@
 
 namespace glslang {
 
+class TIntermediate;
+
 //
 // Operators used by the high-level (parse tree) representation.
 //
@@ -845,7 +847,7 @@
     virtual       TIntermOperator* getAsOperator()       { return this; }
     virtual const TIntermOperator* getAsOperator() const { return this; }
     TOperator getOp() const { return op; }
-    virtual bool promote() { return true; }
+    virtual bool promote(TIntermediate&) { return true; }
     bool modifiesState() const;
     bool isConstructor() const;
     bool isTexture()  const { return op > EOpTextureGuardBegin  && op < EOpTextureGuardEnd; }
@@ -1024,7 +1026,7 @@
     virtual TIntermTyped* getRight() const { return right; }
     virtual       TIntermBinary* getAsBinaryNode()       { return this; }
     virtual const TIntermBinary* getAsBinaryNode() const { return this; }
-    virtual bool promote();
+    virtual bool promote(TIntermediate&);
     virtual void updatePrecision();
 protected:
     TIntermTyped* left;
@@ -1044,7 +1046,7 @@
     virtual const TIntermTyped* getOperand() const { return operand; }
     virtual       TIntermUnary* getAsUnaryNode()       { return this; }
     virtual const TIntermUnary* getAsUnaryNode() const { return this; }
-    virtual bool promote();
+    virtual bool promote(TIntermediate&);
     virtual void updatePrecision();
 protected:
     TIntermTyped* operand;
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index 8e80bbd..1441c55 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -137,7 +137,7 @@
     // one and promote it to the right type.
     //
     TIntermBinary* node = addBinaryNode(op, left, right, loc);
-    if (! node->promote())
+    if (! node->promote(*this))
         return 0;
 
     node->updatePrecision();
@@ -246,7 +246,7 @@
     // build the node
     TIntermBinary* node = addBinaryNode(op, left, right, loc);
 
-    if (! node->promote())
+    if (! node->promote(*this))
         return nullptr;
 
     node->updatePrecision();
@@ -282,6 +282,10 @@
 
     switch (op) {
     case EOpLogicalNot:
+        if (source == EShSourceHlsl) {
+            break; // HLSL can promote logical not
+        }
+ 
         if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
             return 0;
         }
@@ -349,7 +353,7 @@
     //
     TIntermUnary* node = addUnaryNode(op, child, loc);
 
-    if (! node->promote())
+    if (! node->promote(*this))
         return 0;
 
     node->updatePrecision();
@@ -555,6 +559,10 @@
     case EOpAndAssign:
     case EOpInclusiveOrAssign:
     case EOpExclusiveOrAssign:
+    case EOpLogicalNot:
+    case EOpLogicalAnd:
+    case EOpLogicalOr:
+    case EOpLogicalXor:
 
     case EOpFunctionCall:
     case EOpReturn:
@@ -841,6 +849,10 @@
             case EOpModAssign:               // ... 
             case EOpReturn:                  // function returns can also perform arbitrary conversions
             case EOpFunctionCall:            // conversion of a calling parameter
+            case EOpLogicalNot:
+            case EOpLogicalAnd:
+            case EOpLogicalOr:
+            case EOpLogicalXor:
                 return true;
             default:
                 break;
@@ -873,6 +885,8 @@
         case EbtFloat16:
 #endif
             return true;
+        case EbtBool:
+            return (source == EShSourceHlsl);
         default:
             return false;
         }
@@ -1716,13 +1730,20 @@
 //
 // Returns false in nothing makes sense.
 //
-bool TIntermUnary::promote()
+bool TIntermUnary::promote(TIntermediate& intermediate)
 {
     switch (op) {
     case EOpLogicalNot:
-        if (operand->getBasicType() != EbtBool)
+        // Convert operand to a boolean type
+        if (operand->getBasicType() != EbtBool) {
+            // Add constructor to boolean type. If that fails, we can't do it, so return false.
+            TIntermTyped* converted = intermediate.convertToBasicType(op, EbtBool, operand); 
+            if (converted == nullptr)
+                return false;
 
-            return false;
+            // Use the result of converting the node to a bool.
+            operand = converted;
+        }
         break;
     case EOpBitwiseNot:
         if (operand->getBasicType() != EbtInt &&
@@ -1774,13 +1795,31 @@
     }
 }
 
+// If it is not already, convert this node to the given basic type.
+TIntermTyped* TIntermediate::convertToBasicType(TOperator op, TBasicType basicType, TIntermTyped* node) const
+{
+    if (node == nullptr)
+        return nullptr;
+
+    // It's already this basic type: nothing needs to be done, so use the node directly.
+    if (node->getBasicType() == basicType)
+        return node;
+
+    const TType& type = node->getType();
+    const TType newType(basicType, type.getQualifier().storage,
+                        type.getVectorSize(), type.getMatrixCols(), type.getMatrixRows(), type.isVector());
+
+    // Add constructor to the right vectorness of the right type. If that fails, we can't do it, so return nullptr.
+    return addConversion(op, newType, node);
+}
+
 //
 // Establishes the type of the resultant operation, as well as
 // makes the operator the correct one for the operands.
 //
 // Returns false if operator can't work on operands.
 //
-bool TIntermBinary::promote()
+bool TIntermBinary::promote(TIntermediate& intermediate)
 {
     // Arrays and structures have to be exact matches.
     if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct)
@@ -1843,6 +1882,15 @@
     case EOpLogicalAnd:
     case EOpLogicalOr:
     case EOpLogicalXor:
+        if (intermediate.getSource() == EShSourceHlsl) {
+            TIntermTyped* convertedL = intermediate.convertToBasicType(op, EbtBool, left);
+            TIntermTyped* convertedR = intermediate.convertToBasicType(op, EbtBool, right);
+            if (convertedL == nullptr || convertedR == nullptr)
+                return false;
+            left = convertedL;
+            right = convertedR;
+        }
+
         // logical ops operate only on scalar Booleans and will promote to scalar Boolean.
         if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix())
             return false;
@@ -1864,6 +1912,9 @@
     case EOpAndAssign:
     case EOpInclusiveOrAssign:
     case EOpExclusiveOrAssign:
+        if (intermediate.getSource() == EShSourceHlsl)
+            break;
+
         // Check for integer-only operands.
         if ((left->getBasicType() != EbtInt &&  left->getBasicType() != EbtUint &&
              left->getBasicType() != EbtInt64 &&  left->getBasicType() != EbtUint64) ||
@@ -2051,6 +2102,7 @@
     case EOpAndAssign:
     case EOpInclusiveOrAssign:
     case EOpExclusiveOrAssign:
+
         if ((left->isMatrix() && right->isVector()) ||
             (left->isVector() && right->isMatrix()) ||
             left->getBasicType() != right->getBasicType())
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index aae22ec..c8742cb 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -246,6 +246,9 @@
     TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc) const;
     TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc, const TType&) const;
 
+    // Add conversion from node's type to given basic type.
+    TIntermTyped* convertToBasicType(TOperator op, TBasicType basicType, TIntermTyped* node) const;
+
     // Constant folding (in Constant.cpp)
     TIntermTyped* fold(TIntermAggregate* aggrNode);
     TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
@@ -390,7 +393,7 @@
     bool userOutputUsed() const;
     static int getBaseAlignmentScalar(const TType&, int& size);
     bool isSpecializationOperation(const TIntermOperator&) const;
-
+    
     const EShLanguage language;  // stage, known at construction time
     EShSource source;            // source language, known a bit later
     std::string entryPointName;
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index b50816a..9c1a3ee 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -142,6 +142,8 @@
         {"hlsl.load.rwtexture.array.dx10.frag", "main"},
         {"hlsl.load.offset.dx10.frag", "main"},
         {"hlsl.load.offsetarray.dx10.frag", "main"},
+        {"hlsl.logical.unary.frag", "main"},
+        {"hlsl.logical.binary.frag", "main"},
         {"hlsl.multiEntry.vert", "RealEntrypoint"},
         {"hlsl.multiReturn.frag", "main"},
         {"hlsl.matrixindex.frag", "main"},
@@ -149,6 +151,7 @@
         {"hlsl.overload.frag", "PixelShaderFunction"},
         {"hlsl.pp.line.frag", "main"},
         {"hlsl.precise.frag", "main"},
+        {"hlsl.promote.binary.frag", "main"},
         {"hlsl.promotions.frag", "main"},
         {"hlsl.rw.bracket.frag", "main"},
         {"hlsl.rw.scalar.bracket.frag", "main"},
@@ -179,7 +182,7 @@
         {"hlsl.samplelevel.basic.dx10.vert", "main"},
         {"hlsl.samplelevel.offset.dx10.frag", "main"},
         {"hlsl.samplelevel.offsetarray.dx10.frag", "main"},
-        { "hlsl.sample.sub-vec4.dx10.frag", "main"},
+        {"hlsl.sample.sub-vec4.dx10.frag", "main"},
         {"hlsl.semicolons.frag", "main"},
         {"hlsl.shapeConv.frag", "main"},
         {"hlsl.shapeConvRet.frag", "main"},
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index 7766f85..89465bf 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -1935,7 +1935,10 @@
         return true;
 
     node = intermediate.addUnaryMath(unaryOp, node, loc);
-    node = parseContext.handleLvalue(loc, "unary operator", node);
+
+    // These unary ops require lvalues
+    if (unaryOp == EOpPreIncrement || unaryOp == EOpPreDecrement)
+        node = parseContext.handleLvalue(loc, "unary operator", node);
 
     return node != nullptr;
 }
diff --git a/hlsl/hlslParseables.cpp b/hlsl/hlslParseables.cpp
index d33cfb8..7ab159d 100755
--- a/hlsl/hlslParseables.cpp
+++ b/hlsl/hlslParseables.cpp
@@ -245,7 +245,6 @@
     char order = *argOrder;
 
     if (UseHlslTypes) {
-        // TODO: handle sub-vec4 returns
         switch (type) {
         case '-': s += "void";                                            break;
         case 'F': s += "float";                                           break;
@@ -832,8 +831,6 @@
         { "GatherCmpAlpha",  /* O-4 */        "V4",    nullptr,   "%@,S,V,S,V,,,",  "FIU,s,F,,I,,,",  EShLangAll },
         { "GatherCmpAlpha",  /* O-4, status */"V4",    nullptr,   "%@,S,V,S,V,,,,S","FIU,s,F,,I,,,,U",EShLangAll },
 
-        // TODO: Cmp forms
-
         // Mark end of list, since we want to avoid a range-based for, as some compilers don't handle it yet.
         { nullptr,                            nullptr, nullptr,   nullptr,      nullptr,  0 },
     };