diff --git a/Test/baseResults/hlsl.forLoop.frag.out b/Test/baseResults/hlsl.forLoop.frag.out index e9908db3..eaca9fde 100755 --- a/Test/baseResults/hlsl.forLoop.frag.out +++ b/Test/baseResults/hlsl.forLoop.frag.out @@ -110,6 +110,80 @@ gl_FragCoord origin is upper left 0:11 'ii' ( temp int) 0:12 Pre-Decrement ( temp float) 0:12 'ii' ( temp float) +0:13 Sequence +0:13 move second child to first child ( temp int) +0:13 'first' ( temp int) +0:13 Constant: +0:13 0 (const int) +0:13 move second child to first child ( temp int) +0:13 'second' ( temp int) +0:13 Constant: +0:13 1 (const int) +0:13 Loop with condition tested first +0:13 No loop condition +0:13 Loop Body +0:13 add ( temp int) +0:13 'first' ( temp int) +0:13 'second' ( temp int) +0:14 Sequence +0:14 move second child to first child ( temp int) +0:14 'i' ( temp int) +0:14 Constant: +0:14 0 (const int) +0:14 move second child to first child ( temp int) +0:14 'count' ( temp int) +0:14 Convert float to int ( temp int) +0:14 'ii' ( temp float) +0:14 Loop with condition tested first +0:14 Loop Condition +0:14 Compare Less Than ( temp bool) +0:14 'i' ( temp int) +0:14 'count' ( temp int) +0:14 No loop body +0:14 Loop Terminal Expression +0:14 Post-Increment ( temp int) +0:14 'i' ( temp int) +0:15 Sequence +0:15 move second child to first child ( temp float) +0:15 'first' ( temp float) +0:15 Constant: +0:15 0.000000 +0:15 Loop with condition tested first +0:15 Loop Condition +0:15 Compare Less Than ( temp bool) +0:15 'first' ( temp float) +0:15 direct index ( temp float) +0:15 'second' ( temp 2-element array of float) +0:15 Constant: +0:15 0 (const int) +0:15 Loop Body +0:15 add ( temp float) +0:15 add ( temp float) +0:15 'first' ( temp float) +0:15 direct index ( temp float) +0:15 'second' ( temp 2-element array of float) +0:15 Constant: +0:15 1 (const int) +0:15 'third' ( temp float) +0:15 Loop Terminal Expression +0:15 Pre-Increment ( temp float) +0:15 direct index ( temp float) +0:15 'second' ( temp 2-element array of float) +0:15 Constant: +0:15 1 (const int) +0:? Sequence +0:16 Comma ( temp float) +0:16 Comma ( temp float) +0:16 Pre-Decrement ( temp float) +0:16 'ii' ( temp float) +0:16 Pre-Decrement ( temp float) +0:16 'ii' ( temp float) +0:16 Pre-Decrement ( temp float) +0:16 'ii' ( temp float) +0:16 Loop with condition tested first +0:16 No loop condition +0:16 Loop Body +0:16 'ii' ( temp float) 0:2 Function Definition: PixelShaderFunction( ( temp void) 0:2 Function Parameters: 0:? Sequence @@ -239,6 +313,80 @@ gl_FragCoord origin is upper left 0:11 'ii' ( temp int) 0:12 Pre-Decrement ( temp float) 0:12 'ii' ( temp float) +0:13 Sequence +0:13 move second child to first child ( temp int) +0:13 'first' ( temp int) +0:13 Constant: +0:13 0 (const int) +0:13 move second child to first child ( temp int) +0:13 'second' ( temp int) +0:13 Constant: +0:13 1 (const int) +0:13 Loop with condition tested first +0:13 No loop condition +0:13 Loop Body +0:13 add ( temp int) +0:13 'first' ( temp int) +0:13 'second' ( temp int) +0:14 Sequence +0:14 move second child to first child ( temp int) +0:14 'i' ( temp int) +0:14 Constant: +0:14 0 (const int) +0:14 move second child to first child ( temp int) +0:14 'count' ( temp int) +0:14 Convert float to int ( temp int) +0:14 'ii' ( temp float) +0:14 Loop with condition tested first +0:14 Loop Condition +0:14 Compare Less Than ( temp bool) +0:14 'i' ( temp int) +0:14 'count' ( temp int) +0:14 No loop body +0:14 Loop Terminal Expression +0:14 Post-Increment ( temp int) +0:14 'i' ( temp int) +0:15 Sequence +0:15 move second child to first child ( temp float) +0:15 'first' ( temp float) +0:15 Constant: +0:15 0.000000 +0:15 Loop with condition tested first +0:15 Loop Condition +0:15 Compare Less Than ( temp bool) +0:15 'first' ( temp float) +0:15 direct index ( temp float) +0:15 'second' ( temp 2-element array of float) +0:15 Constant: +0:15 0 (const int) +0:15 Loop Body +0:15 add ( temp float) +0:15 add ( temp float) +0:15 'first' ( temp float) +0:15 direct index ( temp float) +0:15 'second' ( temp 2-element array of float) +0:15 Constant: +0:15 1 (const int) +0:15 'third' ( temp float) +0:15 Loop Terminal Expression +0:15 Pre-Increment ( temp float) +0:15 direct index ( temp float) +0:15 'second' ( temp 2-element array of float) +0:15 Constant: +0:15 1 (const int) +0:? Sequence +0:16 Comma ( temp float) +0:16 Comma ( temp float) +0:16 Pre-Decrement ( temp float) +0:16 'ii' ( temp float) +0:16 Pre-Decrement ( temp float) +0:16 'ii' ( temp float) +0:16 Pre-Decrement ( temp float) +0:16 'ii' ( temp float) +0:16 Loop with condition tested first +0:16 No loop condition +0:16 Loop Body +0:16 'ii' ( temp float) 0:2 Function Definition: PixelShaderFunction( ( temp void) 0:2 Function Parameters: 0:? Sequence @@ -255,12 +403,12 @@ gl_FragCoord origin is upper left // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 124 +// Id's are bound by 183 Capability Shader 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Fragment 4 "PixelShaderFunction" 117 120 + EntryPoint Fragment 4 "PixelShaderFunction" 176 179 ExecutionMode 4 OriginUpperLeft Source HLSL 500 Name 4 "PixelShaderFunction" @@ -268,12 +416,19 @@ gl_FragCoord origin is upper left Name 10 "input" Name 92 "ii" Name 111 "ii" - Name 115 "input" - Name 117 "input" - Name 120 "@entryPointOutput" - Name 121 "param" - Decorate 117(input) Location 0 - Decorate 120(@entryPointOutput) Location 0 + Name 114 "first" + Name 116 "second" + Name 124 "i" + Name 125 "count" + Name 138 "first" + Name 149 "second" + Name 157 "third" + Name 174 "input" + Name 176 "input" + Name 179 "@entryPointOutput" + Name 180 "param" + Decorate 176(input) Location 0 + Decorate 179(@entryPointOutput) Location 0 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -293,20 +448,25 @@ gl_FragCoord origin is upper left 100: 90(int) Constant 3 103: 90(int) Constant 2 109: 90(int) Constant 1 - 116: TypePointer Input 7(fvec4) - 117(input): 116(ptr) Variable Input - 119: TypePointer Output 7(fvec4) -120(@entryPointOutput): 119(ptr) Variable Output + 115: 90(int) Constant 0 + 139: 6(float) Constant 0 + 146: 71(int) Constant 2 + 147: TypeArray 6(float) 146 + 148: TypePointer Function 147 + 175: TypePointer Input 7(fvec4) + 176(input): 175(ptr) Variable Input + 178: TypePointer Output 7(fvec4) +179(@entryPointOutput): 178(ptr) Variable Output 4(PixelShaderFunction): 2 Function None 3 5: Label - 115(input): 8(ptr) Variable Function - 121(param): 8(ptr) Variable Function - 118: 7(fvec4) Load 117(input) - Store 115(input) 118 - 122: 7(fvec4) Load 115(input) - Store 121(param) 122 - 123: 7(fvec4) FunctionCall 11(@PixelShaderFunction(vf4;) 121(param) - Store 120(@entryPointOutput) 123 + 174(input): 8(ptr) Variable Function + 180(param): 8(ptr) Variable Function + 177: 7(fvec4) Load 176(input) + Store 174(input) 177 + 181: 7(fvec4) Load 174(input) + Store 180(param) 181 + 182: 7(fvec4) FunctionCall 11(@PixelShaderFunction(vf4;) 180(param) + Store 179(@entryPointOutput) 182 Return FunctionEnd 11(@PixelShaderFunction(vf4;): 7(fvec4) Function None 9 @@ -314,6 +474,13 @@ gl_FragCoord origin is upper left 12: Label 92(ii): 91(ptr) Variable Function 111(ii): 73(ptr) Variable Function + 114(first): 91(ptr) Variable Function + 116(second): 91(ptr) Variable Function + 124(i): 91(ptr) Variable Function + 125(count): 91(ptr) Variable Function + 138(first): 73(ptr) Variable Function + 149(second): 148(ptr) Variable Function + 157(third): 73(ptr) Variable Function Branch 13 13: Label LoopMerge 15 16 None @@ -454,6 +621,85 @@ gl_FragCoord origin is upper left 112: 6(float) Load 111(ii) 113: 6(float) FSub 112 18 Store 111(ii) 113 - 114: 7(fvec4) Undef - ReturnValue 114 + Store 114(first) 115 + Store 116(second) 109 + Branch 117 + 117: Label + LoopMerge 119 120 None + Branch 118 + 118: Label + 121: 90(int) Load 114(first) + 122: 90(int) Load 116(second) + 123: 90(int) IAdd 121 122 + Branch 120 + 120: Label + Branch 117 + 119: Label + Store 124(i) 115 + 126: 6(float) Load 111(ii) + 127: 90(int) ConvertFToS 126 + Store 125(count) 127 + Branch 128 + 128: Label + LoopMerge 130 131 None + Branch 132 + 132: Label + 133: 90(int) Load 124(i) + 134: 90(int) Load 125(count) + 135: 32(bool) SLessThan 133 134 + BranchConditional 135 129 130 + 129: Label + Branch 131 + 131: Label + 136: 90(int) Load 124(i) + 137: 90(int) IAdd 136 109 + Store 124(i) 137 + Branch 128 + 130: Label + Store 138(first) 139 + Branch 140 + 140: Label + LoopMerge 142 143 None + Branch 144 + 144: Label + 145: 6(float) Load 138(first) + 150: 73(ptr) AccessChain 149(second) 115 + 151: 6(float) Load 150 + 152: 32(bool) FOrdLessThan 145 151 + BranchConditional 152 141 142 + 141: Label + 153: 6(float) Load 138(first) + 154: 73(ptr) AccessChain 149(second) 109 + 155: 6(float) Load 154 + 156: 6(float) FAdd 153 155 + 158: 6(float) Load 157(third) + 159: 6(float) FAdd 156 158 + Branch 143 + 143: Label + 160: 73(ptr) AccessChain 149(second) 109 + 161: 6(float) Load 160 + 162: 6(float) FAdd 161 18 + Store 160 162 + Branch 140 + 142: Label + 163: 6(float) Load 111(ii) + 164: 6(float) FSub 163 18 + Store 111(ii) 164 + 165: 6(float) Load 111(ii) + 166: 6(float) FSub 165 18 + Store 111(ii) 166 + 167: 6(float) Load 111(ii) + 168: 6(float) FSub 167 18 + Store 111(ii) 168 + Branch 169 + 169: Label + LoopMerge 171 172 None + Branch 170 + 170: Label + Branch 172 + 172: Label + Branch 169 + 171: Label + 173: 7(fvec4) Undef + ReturnValue 173 FunctionEnd diff --git a/Test/hlsl.forLoop.frag b/Test/hlsl.forLoop.frag index 93789967..9cf60ee4 100644 --- a/Test/hlsl.forLoop.frag +++ b/Test/hlsl.forLoop.frag @@ -5,9 +5,13 @@ float4 PixelShaderFunction(float4 input) : COLOR0 [unroll] for (; any(input != input); ) {} for (; any(input != input); ) { return -input; } for (--input; any(input != input); input += 2) { return -input; } - for (;;) if (input.x > 2.0) break; - for (;;) if (input.x > 2.0) continue; - float ii; - for (int ii = -1; ii < 3; ++ii) if (ii == 2) continue; - --ii; + for (;;) if (input.x > 2.0) break; + for (;;) if (input.x > 2.0) continue; + float ii; + for (int ii = -1; ii < 3; ++ii) if (ii == 2) continue; + --ii; + for (int first = 0, second = 1; ;) first + second; + for ( int i = 0, count = int(ii); i < count; i++ ); + for (float first = 0, second[2], third; first < second[0]; ++second[1]) first + second[1] + third; + for (--ii, --ii, --ii;;) ii; } diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index ad9720c0..29a0e741 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -1735,8 +1735,13 @@ TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* init node->setLoc(loc); node->setLoopControl(control); - // make a sequence of the initializer and statement - TIntermAggregate* loopSequence = makeAggregate(initializer, loc); + // make a sequence of the initializer and statement, but try to reuse the + // aggregate already created for whatever is in the initializer, if there is one + TIntermAggregate* loopSequence = (initializer == nullptr || + initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc) + : initializer->getAsAggregate(); + if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence) + loopSequence->setOp(EOpNull); loopSequence = growAggregate(loopSequence, node); loopSequence->setOperator(EOpSequence); diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 69155850..2329246d 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -3039,6 +3039,37 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node) return true; } +// simple_statement +// : SEMICOLON +// | declaration_statement +// | expression SEMICOLON +// +bool HlslGrammar::acceptSimpleStatement(TIntermNode*& statement) +{ + // SEMICOLON + if (acceptTokenClass(EHTokSemicolon)) + return true; + + // declaration + if (acceptDeclaration(statement)) + return true; + + // expression + TIntermTyped* node; + if (acceptExpression(node)) + statement = node; + else + return false; + + // SEMICOLON (following an expression) + if (acceptTokenClass(EHTokSemicolon)) + return true; + else { + expected(";"); + return false; + } +} + // compound_statement // : LEFT_CURLY statement statement ... RIGHT_CURLY // @@ -3096,12 +3127,11 @@ bool HlslGrammar::acceptScopedCompoundStatement(TIntermNode*& statement) // // attributed_statement // : compound_statement -// | SEMICOLON -// | expression SEMICOLON -// | declaration_statement +// | simple_statement // | selection_statement // | switch_statement // | case_label +// | default_label // | iteration_statement // | jump_statement // @@ -3140,33 +3170,13 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement) case EHTokDefault: return acceptDefaultLabel(statement); - case EHTokSemicolon: - return acceptTokenClass(EHTokSemicolon); - case EHTokRightBrace: // Performance: not strictly necessary, but stops a bunch of hunting early, // and is how sequences of statements end. return false; default: - { - // declaration - if (acceptDeclaration(statement)) - return true; - - // expression - TIntermTyped* node; - if (acceptExpression(node)) - statement = node; - else - return false; - - // SEMICOLON (following an expression) - if (! acceptTokenClass(EHTokSemicolon)) { - expected(";"); - return false; - } - } + return acceptSimpleStatement(statement); } return true; @@ -3420,14 +3430,8 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri // initializer TIntermNode* initNode = nullptr; - if (! acceptControlDeclaration(initNode)) { - TIntermTyped* initExpr = nullptr; - acceptExpression(initExpr); - initNode = initExpr; - } - // SEMI_COLON - if (! acceptTokenClass(EHTokSemicolon)) - expected(";"); + if (! acceptSimpleStatement(initNode)) + expected("for-loop initializer statement"); parseContext.nestLooping(); diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 07c88787..135fd6c3 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -108,10 +108,11 @@ namespace glslang { bool acceptFunctionCall(const TSourceLoc&, TString& name, TIntermTyped*&, TIntermTyped* objectBase); bool acceptArguments(TFunction*, TIntermTyped*&); bool acceptLiteral(TIntermTyped*&); + bool acceptSimpleStatement(TIntermNode*&); bool acceptCompoundStatement(TIntermNode*&); - bool acceptStatement(TIntermNode*&); bool acceptScopedStatement(TIntermNode*&); bool acceptScopedCompoundStatement(TIntermNode*&); + bool acceptStatement(TIntermNode*&); bool acceptNestedStatement(TIntermNode*&); void acceptAttributes(TAttributeMap&); bool acceptSelectionStatement(TIntermNode*&);