Commit 647fccaf by John Kessenich

AST: Fix shift conversions, which don't require matching types.

The base and shift amount need to be integers, but not of the same type. This fixes #1296 and replaces #1297.
parent 6e899be5
spv.rankShift.comp
// Module Version 10000
// Generated by (magic number): 80006
// Id's are bound by 33
Capability Shader
Capability Int64
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint GLCompute 4 "main"
ExecutionMode 4 LocalSize 54 1 1
Source GLSL 450
SourceExtension "GL_ARB_gpu_shader_int64"
Name 4 "main"
Name 8 "result"
Name 11 "arg0"
Name 15 "arg1"
Decorate 11(arg0) Location 4
Decorate 15(arg1) Location 5
Decorate 32 BuiltIn WorkgroupSize
2: TypeVoid
3: TypeFunction 2
6: TypeInt 64 0
7: TypePointer Function 6(int)
9: TypeInt 64 1
10: TypePointer UniformConstant 9(int)
11(arg0): 10(ptr) Variable UniformConstant
13: TypeInt 32 0
14: TypePointer UniformConstant 13(int)
15(arg1): 14(ptr) Variable UniformConstant
29: TypeVector 13(int) 3
30: 13(int) Constant 54
31: 13(int) Constant 1
32: 29(ivec3) ConstantComposite 30 31 31
4(main): 2 Function None 3
5: Label
8(result): 7(ptr) Variable Function
12: 9(int) Load 11(arg0)
16: 13(int) Load 15(arg1)
17: 9(int) ShiftLeftLogical 12 16
18: 6(int) Bitcast 17
Store 8(result) 18
19: 9(int) Load 11(arg0)
20: 13(int) Load 15(arg1)
21: 9(int) ShiftRightArithmetic 19 20
22: 6(int) Bitcast 21
Store 8(result) 22
23: 13(int) Load 15(arg1)
24: 6(int) Load 8(result)
25: 6(int) ShiftLeftLogical 24 23
Store 8(result) 25
26: 13(int) Load 15(arg1)
27: 6(int) Load 8(result)
28: 6(int) ShiftRightLogical 27 26
Store 8(result) 28
Return
FunctionEnd
...@@ -116,6 +116,8 @@ void operators() ...@@ -116,6 +116,8 @@ void operators()
i64 = i64 % i; i64 = i64 % i;
// Shift // Shift
u64v = u64v << i;
i64 = i64 >> uv.y;
u64v <<= i; u64v <<= i;
i64 >>= uv.y; i64 >>= uv.y;
......
#version 450
#extension GL_ARB_gpu_shader_int64 : require
layout(local_size_x = 54) in;
layout(location=4) uniform int64_t arg0;
layout(location=5) uniform uint arg1;
void main()
{
uint64_t result = arg0 << arg1;
result = arg0 >> arg1;
result <<= arg1;
result >>= arg1;
}
\ No newline at end of file
...@@ -744,9 +744,6 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no ...@@ -744,9 +744,6 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no
auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes); auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes);
TBasicType type0 = node0->getType().getBasicType();
TBasicType type1 = node1->getType().getBasicType();
switch (op) { switch (op) {
// //
// List all the binary ops that can implicitly convert one operand to the other's type; // List all the binary ops that can implicitly convert one operand to the other's type;
...@@ -776,10 +773,10 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no ...@@ -776,10 +773,10 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no
case EOpSequence: // used by ?: case EOpSequence: // used by ?:
if (type0 == type1) if (node0->getBasicType() == node1->getBasicType())
return std::make_tuple(node0, node1); return std::make_tuple(node0, node1);
promoteTo = getConversionDestinatonType(type0, type1, op); promoteTo = getConversionDestinatonType(node0->getBasicType(), node1->getBasicType(), op);
if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes) if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes)
return std::make_tuple(nullptr, nullptr); return std::make_tuple(nullptr, nullptr);
...@@ -794,23 +791,25 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no ...@@ -794,23 +791,25 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no
return std::make_tuple(node0, node1); return std::make_tuple(node0, node1);
break; break;
// Shifts can have mixed types as long as they are integer and of the same rank, // There are no conversions needed for GLSL; the shift amount just needs to be an
// without converting. // integer type, as does the base.
// HLSL can promote bools to ints to make this work.
case EOpLeftShift: case EOpLeftShift:
case EOpRightShift: case EOpRightShift:
if (node0->getType() == node1->getType()) if (source == EShSourceHlsl) {
return std::make_tuple(node0, node1); TBasicType node0BasicType = node0->getBasicType();
if (node0BasicType == EbtBool)
if (isTypeInt(type0) && isTypeInt(type1)) { node0BasicType = EbtInt;
if (getTypeRank(type0) == getTypeRank(type1)) { if (node1->getBasicType() == EbtBool)
promoteTo = std::make_tuple(node0BasicType, EbtInt);
else
promoteTo = std::make_tuple(node0BasicType, node1->getBasicType());
} else {
if (isTypeInt(node0->getBasicType()) && isTypeInt(node1->getBasicType()))
return std::make_tuple(node0, node1); return std::make_tuple(node0, node1);
} else { else
promoteTo = getConversionDestinatonType(type0, type1, op); return std::make_tuple(nullptr, nullptr);
if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes) }
return std::make_tuple(nullptr, nullptr);
}
} else
return std::make_tuple(nullptr, nullptr);
break; break;
default: default:
...@@ -964,35 +963,24 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -964,35 +963,24 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
if (type.getBasicType() == node->getType().getBasicType()) if (type.getBasicType() == node->getType().getBasicType())
return node; return node;
if (canImplicitlyPromote(node->getType().getBasicType(), type.getBasicType(), op)) if (canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op))
promoteTo = type.getBasicType(); promoteTo = type.getBasicType();
else else
return nullptr; return nullptr;
break; break;
// Shifts can have mixed types as long as they are integer and of the same rank, // For GLSL, there are no conversions needed; the shift amount just needs to be an
// without converting. // integer type, as do the base/result.
// It's the left operand's type that determines the resulting type, so no issue // HLSL can convert the shift from a bool to an int.
// with assign shift ops either.
case EOpLeftShiftAssign: case EOpLeftShiftAssign:
case EOpRightShiftAssign: case EOpRightShiftAssign:
{ {
TBasicType type0 = type.getBasicType(); if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool)
TBasicType type1 = node->getType().getBasicType(); promoteTo = type.getBasicType();
else {
if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) { if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType()))
promoteTo = type0; return node;
} else { else
if (isTypeInt(type0) && isTypeInt(type1)) {
if (getTypeRank(type0) == getTypeRank(type1)) {
return node;
} else {
if (canImplicitlyPromote(type1, type0, op))
promoteTo = type0;
else
return nullptr;
}
} else
return nullptr; return nullptr;
} }
break; break;
...@@ -1437,9 +1425,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat ...@@ -1437,9 +1425,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float32) || extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float32) ||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float64); extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float64);
if(explicitTypesEnabled) if(explicitTypesEnabled) {
{
// integral promotions // integral promotions
if (isIntegralPromotion(from, to)) { if (isIntegralPromotion(from, to)) {
return true; return true;
......
...@@ -416,6 +416,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -416,6 +416,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.460.comp", "spv.460.comp",
"spv.atomic.comp", "spv.atomic.comp",
"spv.glFragColor.frag", "spv.glFragColor.frag",
"spv.rankShift.comp",
"spv.specConst.vert", "spv.specConst.vert",
"spv.OVR_multiview.vert", "spv.OVR_multiview.vert",
})), })),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment