[PATCH vkd3d v3 03/11] vkd3d-shader/hlsl: Test the INT_MIN / -1 constant folding special case.

Giovanni Mascellani gmascellani at codeweavers.com
Sat Apr 23 07:25:15 CDT 2022


Hi,

Il 22/04/22 21:09, Zebediah Figura ha scritto:
> On 4/22/22 05:24, Giovanni Mascellani wrote:
>> Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
>> ---
>>   tests/arithmetic-int.shader_test | 13 +++++++++++++
>>   1 file changed, 13 insertions(+)
>>
>> diff --git a/tests/arithmetic-int.shader_test 
>> b/tests/arithmetic-int.shader_test
>> index c2eee2ba..14bb6a63 100644
>> --- a/tests/arithmetic-int.shader_test
>> +++ b/tests/arithmetic-int.shader_test
>> @@ -24,6 +24,19 @@ float4 main() : SV_TARGET
>>   draw quad
>>   probe all rgba (5.0, 5.0, -5.0, 3.0)
>> +[pixel shader]
>> +float4 main() : SV_TARGET
>> +{
>> +    int x = -2147483648;
>> +    int y = -1;
>> +
>> +    return x / y;
>> +}
>> +
>> +[test]
>> +draw quad
>> +probe all rgba (-2147483648.0, -2147483648.0, -2147483648.0, 
>> -2147483648.0)
>> +
>>   [pixel shader fail]
>>   float4 main() : SV_TARGET
>>   {
> 
> This fails for me with the d3d9 backend, returning positive 2**32 
> instead of negative.

Ouch, yes, you're right. SM1 treats ints as floats, so it gets confused 
when ints that cannot be exactly represented as floats are used, and 
whenever modular arithmetic is assumed, like in this case.

This makes me notice that the problems are more than that; for example, 
this shader returns 2000002:
---
float4 main() : SV_TARGET
{
     int x = 2000001999;
     int y = 1000;

     return x / y;
}
---
but this one returns 2000001:
---
float4 main() : SV_TARGET
{
     return 2000001999 / 1000;
}
---

Notice that 2000001 and 2000002 are different both as ints and as 
floats, and 2000001999 is approximated to 2000002048 when converted to a 
float.

So it seems that the native compiler does two constant folding passes: 
one before copy propagation (in which ints are still treated as ints) 
and one after (and after int operations have been somehow converted to 
float). This also works with INT_MIN / -1, which becomes negative if you 
write it as a simple expression (without storing the operands in 
variables x and y).

This looks pretty braindead and I am not sure we want to replicate it, 
until we find something that really depends on it. And I hope we don't.

In practice, for the moment I would suggest to only do constant folding 
in SM4, and enable it for SM1 once int operations are rewritten correctly.

Giovanni.



More information about the wine-devel mailing list