From c043aadd252f60e14028f12e7823286378ea037f Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 8 Jan 2018 11:48:50 -0700 Subject: [PATCH] Scanner: Many int64 fixes, including performance. - partially addresses #1209 and #1187 - only query 64-bit extension on seeing use of a 64-bit literal (was doing it for every single token) - correct HLSL acceptance of 64-bit literal syntax (still an int though) - error on overflow of 32-bit literal type --- Test/baseResults/numeral.frag.out | 12 +-- Test/baseResults/preprocessor.simple.vert.out | 2 +- Test/baseResults/spv.atomicInt64.comp.out | 2 +- Test/baseResults/tokenLength.vert.out | 8 +- Test/spv.atomicInt64.comp | 2 +- .../preprocessor/PpScanner.cpp | 82 +++++++++++-------- 6 files changed, 61 insertions(+), 47 deletions(-) diff --git a/Test/baseResults/numeral.frag.out b/Test/baseResults/numeral.frag.out index c1e313478..a7343f9c0 100644 --- a/Test/baseResults/numeral.frag.out +++ b/Test/baseResults/numeral.frag.out @@ -85,12 +85,12 @@ ERROR: node is still EOpNull! 0:17 move second child to first child ( temp int) 0:17 'obig' ( temp int) 0:17 Constant: -0:17 995208915 (const int) +0:17 -1662398820 (const int) 0:18 Sequence 0:18 move second child to first child ( temp int) 0:18 'omax1' ( temp int) 0:18 Constant: -0:18 536870912 (const int) +0:18 0 (const int) 0:20 Sequence 0:20 move second child to first child ( temp uint) 0:20 'uo5' ( temp uint) @@ -225,7 +225,7 @@ ERROR: node is still EOpNull! 0:50 move second child to first child ( temp int) 0:50 'hbig' ( temp int) 0:50 Constant: -0:50 -1 (const int) +0:50 -15 (const int) 0:52 Sequence 0:52 move second child to first child ( temp float) 0:52 'f1' ( temp float) @@ -494,12 +494,12 @@ ERROR: node is still EOpNull! 0:17 move second child to first child ( temp int) 0:17 'obig' ( temp int) 0:17 Constant: -0:17 995208915 (const int) +0:17 -1662398820 (const int) 0:18 Sequence 0:18 move second child to first child ( temp int) 0:18 'omax1' ( temp int) 0:18 Constant: -0:18 536870912 (const int) +0:18 0 (const int) 0:20 Sequence 0:20 move second child to first child ( temp uint) 0:20 'uo5' ( temp uint) @@ -634,7 +634,7 @@ ERROR: node is still EOpNull! 0:50 move second child to first child ( temp int) 0:50 'hbig' ( temp int) 0:50 Constant: -0:50 -1 (const int) +0:50 -15 (const int) 0:52 Sequence 0:52 move second child to first child ( temp float) 0:52 'f1' ( temp float) diff --git a/Test/baseResults/preprocessor.simple.vert.out b/Test/baseResults/preprocessor.simple.vert.out index 8cbabdad8..56bfe010f 100644 --- a/Test/baseResults/preprocessor.simple.vert.out +++ b/Test/baseResults/preprocessor.simple.vert.out @@ -25,6 +25,6 @@ int main(){ == != & ^ | && ^^ || ? : += -= *= /= %= <<= >>= &= |= ^= - 1.2 2E10 5u - 5 lf + 1.2 2E10 5u - 5l f } diff --git a/Test/baseResults/spv.atomicInt64.comp.out b/Test/baseResults/spv.atomicInt64.comp.out index c9481558a..8daee95ce 100644 --- a/Test/baseResults/spv.atomicInt64.comp.out +++ b/Test/baseResults/spv.atomicInt64.comp.out @@ -50,7 +50,7 @@ spv.atomicInt64.comp 24: 22(int) Constant 0 28: 17(int) Constant 1 29: TypePointer Uniform 10(int) - 31: 10(int) Constant 15 0 + 31: 10(int) Constant 15 240 84(Struct): TypeStruct 6(int) 10(int) 85: TypePointer Workgroup 84(Struct) 86(s): 85(ptr) Variable Workgroup diff --git a/Test/baseResults/tokenLength.vert.out b/Test/baseResults/tokenLength.vert.out index c4738585c..8c31da921 100644 --- a/Test/baseResults/tokenLength.vert.out +++ b/Test/baseResults/tokenLength.vert.out @@ -51,7 +51,7 @@ ERROR: node is still EOpNull! 0:13 move second child to first child ( temp highp int) 0:13 'OE' ( global highp int) 0:13 Constant: -0:13 1073741823 (const int) +0:13 -1 (const int) 0:14 Sequence 0:14 move second child to first child ( temp highp int) 0:14 'HE' ( global highp int) @@ -92,7 +92,7 @@ ERROR: node is still EOpNull! 0:34 move second child to first child ( temp highp int) 0:34 'superO' ( global highp int) 0:34 Constant: -0:34 1073741823 (const int) +0:34 -1 (const int) 0:35 Sequence 0:35 move second child to first child ( temp highp int) 0:35 'superI' ( global highp int) @@ -147,7 +147,7 @@ ERROR: node is still EOpNull! 0:13 move second child to first child ( temp highp int) 0:13 'OE' ( global highp int) 0:13 Constant: -0:13 1073741823 (const int) +0:13 -1 (const int) 0:14 Sequence 0:14 move second child to first child ( temp highp int) 0:14 'HE' ( global highp int) @@ -188,7 +188,7 @@ ERROR: node is still EOpNull! 0:34 move second child to first child ( temp highp int) 0:34 'superO' ( global highp int) 0:34 Constant: -0:34 1073741823 (const int) +0:34 -1 (const int) 0:35 Sequence 0:35 move second child to first child ( temp highp int) 0:35 'superI' ( global highp int) diff --git a/Test/spv.atomicInt64.comp b/Test/spv.atomicInt64.comp index a56c7ec03..baca4cefe 100644 --- a/Test/spv.atomicInt64.comp +++ b/Test/spv.atomicInt64.comp @@ -22,7 +22,7 @@ shared Struct s; void main() { const int64_t i64c = -24; - const uint64_t u64c = 0xF00000000F; + const uint64_t u64c = 0xF00000000Ful; // Test shader storage block int64_t i64 = 0; diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp index b58bbeeab..9fed80b6a 100644 --- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -333,7 +333,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) int ch = 0; int ii = 0; unsigned long long ival = 0; - bool enableInt64 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64); #ifdef AMD_EXTENSIONS bool enableInt16 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16); #endif @@ -420,7 +419,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ival = 0; do { - if (len < MaxTokenLength && (ival <= 0x0fffffffu || (enableInt64 && ival <= 0x0fffffffffffffffull))) { + if (len < MaxTokenLength && ival <= 0x0fffffffffffffffull) { ppToken->name[len++] = (char)ch; if (ch >= '0' && ch <= '9') { ii = ch - '0'; @@ -453,15 +452,13 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; - if (enableInt64) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt64 = true; - } else - ungetch(); - } + int nextCh = getch(); + if (nextCh == 'l' || nextCh == 'L') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); #ifdef AMD_EXTENSIONS if (enableInt16) { @@ -474,7 +471,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ungetch(); } #endif - } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; @@ -489,6 +486,12 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len] = '\0'; if (isInt64) { + if (pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "64-bit hexadecimal literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, E_GL_ARB_gpu_shader_int64, + "64-bit hexadecimal literal"); + } ppToken->i64val = ival; return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; #ifdef AMD_EXTENSIONS @@ -497,6 +500,8 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16; #endif } else { + if (ival > 0xffffffffu && !AlreadyComplained) + pp->parseContext.ppError(ppToken->loc, "hexadecimal literal too big", "", ""); ppToken->ival = (int)ival; return isUnsigned ? PpAtomConstUint : PpAtomConstInt; } @@ -520,7 +525,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", ""); AlreadyComplained = 1; } - if (ival <= 0x1fffffffu || (enableInt64 && ival <= 0x1fffffffffffffffull)) { + if (ival <= 0x1fffffffffffffffull) { ii = ch - '0'; ival = (ival << 3) | ii; } else @@ -553,15 +558,13 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; - if (enableInt64) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt64 = true; - } else - ungetch(); - } + int nextCh = getch(); + if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); #ifdef AMD_EXTENSIONS if (enableInt16) { @@ -574,7 +577,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ungetch(); } #endif - } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; @@ -588,10 +591,19 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ungetch(); ppToken->name[len] = '\0'; + if (!isInt64 && ival > 0xffffffffu) + octalOverflow = true; + if (octalOverflow) pp->parseContext.ppError(ppToken->loc, "octal literal too big", "", ""); if (isInt64) { + if (pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "64-bit octal literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, E_GL_ARB_gpu_shader_int64, + "64-bit octal literal"); + } ppToken->i64val = ival; return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; #ifdef AMD_EXTENSIONS @@ -633,15 +645,13 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; - if (enableInt64) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt64 = true; - } else - ungetch(); - } + int nextCh = getch(); + if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); #ifdef AMD_EXTENSIONS if (enableInt16) { @@ -654,7 +664,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ungetch(); } #endif - } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; @@ -696,7 +706,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ival = ival * 10 + ch; } - if (isInt64) { + if (isInt64 && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "64-bit literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, E_GL_ARB_gpu_shader_int64, + "64-bit literal"); ppToken->i64val = ival; return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; #ifdef AMD_EXTENSIONS