SPIR-V: Return undefined values from implicit returns instead of dummy

Previously if a non-void function implictly returned, a dummy variable
was created as return value. Now instead it returns the result of the
OpUndef instruction. This better conveys the presence of undefined
behavior to SPIR-V consuming tools (and humans).

It also saves one ID per occurrence...
This commit is contained in:
Miro Knejp 2015-08-11 02:45:24 +02:00
parent 65c78a0b62
commit 28f9b1c28d
4 changed files with 77 additions and 74 deletions

View File

@ -791,9 +791,7 @@ void Builder::leaveFunction(bool main)
if (function.getReturnType() == makeVoidType())
makeReturn(true);
else {
Id retStorage = createVariable(StorageClassFunction, function.getReturnType(), "dummyReturn");
Id retValue = createLoad(retStorage);
makeReturn(true, retValue);
makeReturn(true, createUndefined(function.getReturnType()));
}
}
}
@ -844,6 +842,14 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
return inst->getResultId();
}
// Comments in header
Id Builder::createUndefined(Id type)
{
Instruction* inst = new Instruction(getUniqueId(), type, OpUndef);
buildPoint->addInstruction(inst);
return inst->getResultId();
}
// Comments in header
void Builder::createStore(Id rValue, Id lValue)
{

View File

@ -218,6 +218,9 @@ public:
// Create a global or function local or IO variable.
Id createVariable(StorageClass, Id type, const char* name = 0);
// Create an imtermediate with an undefined value.
Id createUndefined(Id type);
// Store into an Id and return the l-value
void createStore(Id rValue, Id lValue);

30
Test/baseResults/spv.forwardFun.frag.out Executable file → Normal file
View File

@ -5,7 +5,7 @@ Linked fragment stage:
// Module Version 99
// Generated by (magic number): 51a00bb
// Id's are bound by 59
// Id's are bound by 58
Source ESSL 100
Capability Shader
@ -24,8 +24,7 @@ Linked fragment stage:
Name 28 "f"
Name 31 "gl_FragColor"
Name 37 "d"
Name 49 "dummyReturn"
Name 58 "bigColor"
Name 57 "bigColor"
Decorate 19(color) RelaxedPrecision
Decorate 21(BaseColor) RelaxedPrecision
Decorate 21(BaseColor) Smooth
@ -33,8 +32,8 @@ Linked fragment stage:
Decorate 31(gl_FragColor) RelaxedPrecision
Decorate 31(gl_FragColor) BuiltIn FragColor
Decorate 37(d) RelaxedPrecision
Decorate 58(bigColor) RelaxedPrecision
Decorate 58(bigColor) NoStaticUse
Decorate 57(bigColor) RelaxedPrecision
Decorate 57(bigColor) NoStaticUse
2: TypeVoid
3: TypeFunction 2
9: TypeFloat 32
@ -53,8 +52,8 @@ Linked fragment stage:
40: TypeBool
44: 9(float) Constant 1067030938
47: 9(float) Constant 1083179008
57: TypePointer UniformConstant 13(fvec4)
58(bigColor): 57(ptr) Variable UniformConstant
56: TypePointer UniformConstant 13(fvec4)
57(bigColor): 56(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
19(color): 14(ptr) Variable Function
@ -82,7 +81,6 @@ Linked fragment stage:
FunctionEnd
11(unreachableReturn(): 9(float) Function None 10
12: Label
49(dummyReturn): 27(ptr) Variable Function
35: 2 FunctionCall 7(bar()
38: 9(float) Load 37(d)
41: 40(bool) FOrdLessThan 38 39
@ -93,16 +91,16 @@ Linked fragment stage:
46: Label
ReturnValue 47
43: Label
50: 9(float) Load 49(dummyReturn)
ReturnValue 50
49: 9(float) Undef
ReturnValue 49
FunctionEnd
17(foo(vf4;): 9(float) Function None 15
16(bar): 14(ptr) FunctionParameter
18: Label
51: 13(fvec4) Load 16(bar)
52: 9(float) CompositeExtract 51 0
53: 13(fvec4) Load 16(bar)
54: 9(float) CompositeExtract 53 1
55: 9(float) FAdd 52 54
ReturnValue 55
50: 13(fvec4) Load 16(bar)
51: 9(float) CompositeExtract 50 0
52: 13(fvec4) Load 16(bar)
53: 9(float) CompositeExtract 52 1
54: 9(float) FAdd 51 53
ReturnValue 54
FunctionEnd

106
Test/baseResults/spv.functionCall.frag.out Executable file → Normal file
View File

@ -7,7 +7,7 @@ Linked fragment stage:
// Module Version 99
// Generated by (magic number): 51a00bb
// Id's are bound by 76
// Id's are bound by 74
Source GLSL 130
Capability Shader
@ -23,18 +23,16 @@ Linked fragment stage:
Name 19 "missingReturn("
Name 22 "h"
Name 31 "d"
Name 44 "dummyReturn"
Name 53 "dummyReturn"
Name 55 "color"
Name 57 "BaseColor"
Name 58 "param"
Name 63 "f"
Name 65 "g"
Name 68 "gl_FragColor"
Name 75 "bigColor"
Decorate 57(BaseColor) Smooth
Decorate 68(gl_FragColor) BuiltIn FragColor
Decorate 75(bigColor) NoStaticUse
Name 52 "color"
Name 54 "BaseColor"
Name 55 "param"
Name 61 "f"
Name 63 "g"
Name 66 "gl_FragColor"
Name 73 "bigColor"
Decorate 54(BaseColor) Smooth
Decorate 66(gl_FragColor) BuiltIn FragColor
Decorate 73(bigColor) NoStaticUse
2: TypeVoid
3: TypeFunction 2
7: TypeFloat 32
@ -51,37 +49,37 @@ Linked fragment stage:
34: TypeBool
38: 7(float) Constant 1067030938
41: 7(float) Constant 1083179008
43: TypePointer Function 7(float)
51: 7(float) Constant 1081711002
56: TypePointer Input 8(fvec4)
57(BaseColor): 56(ptr) Variable Input
67: TypePointer Output 8(fvec4)
68(gl_FragColor): 67(ptr) Variable Output
74: TypePointer UniformConstant 8(fvec4)
75(bigColor): 74(ptr) Variable UniformConstant
49: 7(float) Constant 1081711002
53: TypePointer Input 8(fvec4)
54(BaseColor): 53(ptr) Variable Input
60: TypePointer Function 7(float)
65: TypePointer Output 8(fvec4)
66(gl_FragColor): 65(ptr) Variable Output
72: TypePointer UniformConstant 8(fvec4)
73(bigColor): 72(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
55(color): 9(ptr) Variable Function
58(param): 9(ptr) Variable Function
63(f): 43(ptr) Variable Function
65(g): 43(ptr) Variable Function
52(color): 9(ptr) Variable Function
55(param): 9(ptr) Variable Function
61(f): 60(ptr) Variable Function
63(g): 60(ptr) Variable Function
Store 22(h) 23
59: 8(fvec4) Load 57(BaseColor)
Store 58(param) 59
60: 7(float) FunctionCall 12(foo(vf4;) 58(param)
61: 8(fvec4) CompositeConstruct 60 60 60 60
Store 55(color) 61
62: 2 FunctionCall 14(bar()
64: 7(float) FunctionCall 17(unreachableReturn()
Store 63(f) 64
66: 7(float) FunctionCall 19(missingReturn()
Store 65(g) 66
69: 8(fvec4) Load 55(color)
70: 7(float) Load 63(f)
56: 8(fvec4) Load 54(BaseColor)
Store 55(param) 56
57: 7(float) FunctionCall 12(foo(vf4;) 55(param)
58: 8(fvec4) CompositeConstruct 57 57 57 57
Store 52(color) 58
59: 2 FunctionCall 14(bar()
62: 7(float) FunctionCall 17(unreachableReturn()
Store 61(f) 62
64: 7(float) FunctionCall 19(missingReturn()
Store 63(g) 64
67: 8(fvec4) Load 52(color)
68: 7(float) Load 61(f)
69: 8(fvec4) VectorTimesScalar 67 68
70: 7(float) Load 22(h)
71: 8(fvec4) VectorTimesScalar 69 70
72: 7(float) Load 22(h)
73: 8(fvec4) VectorTimesScalar 71 72
Store 68(gl_FragColor) 73
Store 66(gl_FragColor) 71
Branch 6
6: Label
Return
@ -102,7 +100,6 @@ Linked fragment stage:
FunctionEnd
17(unreachableReturn(): 7(float) Function None 16
18: Label
44(dummyReturn): 43(ptr) Variable Function
32: 7(float) Load 31(d)
35: 34(bool) FOrdLessThan 32 33
SelectionMerge 37 None
@ -112,21 +109,20 @@ Linked fragment stage:
40: Label
ReturnValue 41
37: Label
45: 7(float) Load 44(dummyReturn)
ReturnValue 45
43: 7(float) Undef
ReturnValue 43
FunctionEnd
19(missingReturn(): 7(float) Function None 16
20: Label
53(dummyReturn): 43(ptr) Variable Function
46: 7(float) Load 31(d)
47: 34(bool) FOrdLessThan 46 41
SelectionMerge 49 None
BranchConditional 47 48 49
48: Label
50: 7(float) Load 31(d)
Store 22(h) 50
ReturnValue 51
49: Label
54: 7(float) Load 53(dummyReturn)
ReturnValue 54
44: 7(float) Load 31(d)
45: 34(bool) FOrdLessThan 44 41
SelectionMerge 47 None
BranchConditional 45 46 47
46: Label
48: 7(float) Load 31(d)
Store 22(h) 48
ReturnValue 49
47: Label
51: 7(float) Undef
ReturnValue 51
FunctionEnd