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 },
};