Showing results for 
Search instead for 
Did you mean: 

OpenGL & Vulkan

Journeyman III

Compiler Bug on a D3D Pixel Shader Program

I found a bug in the D3D compiler when working on a shader program. Then I reduced the program to a minimal bug-triggering one. Could you ask the GPU compiler developer to check what's wrong with the compiler?




The AMD Radeon RX 6400 incorrectly compiles an HLSL pixel shader program and produces wrong rendering effects. The built-in HLSL function frac calculates fractional part of a floating-point number, i.e., frac(x) = x - floor(x). For example, frac(1.6) = 0.6, frac(0.7) = 0.7. However, in an HLSL program, the compiler incorrectly reasons that frac(x) is zero, even though the actual value of frac(x) is 0.4. This bug doesn't exist if all optimizations are disabled.



- Operating System: Windows 10 Pro, version 21H2, OS build: 19044.1826

- Hardware:

  CPU:  12th Gen Intel(R) Core(TM) i5-12400   2.50 GHz

  RAM:  32.0 GB

  System type:  64-bit operating system, x64-based processor
  1. Intel(R) UHD Graphics 730, with driver version
  2. AMD Radeon RX 6400, with driver version 30.0.15021.11005 (used during the experiment)

- Software:

  Direct3D 11 with Shader Model 5

  IDE: Microsoft Visual Studio Community 2022 (64-bit) Version 17.2.6

  Browser: Chrome Version 104.0.5112.81 (Official Build) (64-bit)

Reproduce the bug in the browser


Prerequisite: Windows system, Chrome, AMD Radeon RX 6400 GPU
  1. Open Chrome, and go to the website
  2. Click the "Compile" button to compile the program.
  3. Click "Pause" button to stop the variable iTime from changing.
  4. Click "Reset time" button to reset iTime to 0.
  5. The correct output should be white. However, due to the incorrect compilation, you would see the output to be black.


Chrome browser by default used Direct3D for executing OpenGL ES shader programs on Windows systems. We can utilize Chrome to quickly reproduce the bug in HLSL compiler. The source code of our used OpenGL ES program and the meaning of each line is provided in


Reproduce the bug on desktop


A minimal pixel shader to reproduce the bug



float4 PS(VertexOut pIn): SV_Target {
    float4 fragColor;
    float t;
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++) {
            t = iTime + 0.4;
            fragColor = (frac(t) == 0.0) ? float4(0.0, 0.0, 0.0, 1.0) : float4(1.0, 1.0, 1.0, 1.0);
    return fragColor;



In the above pixel shader program, the variable iTime is a constant buffer (a kind of variable similar to user-input and assigned by the calling CPU program at runtime) that is provided with value 0 at runtime. So the value of varialbe t is 0.4. Since the semantics of the built-in function frac is to retrieve the fractional part of its input, frac(t) should be 0.4. Hence, frac(t) == 0.0 should be false, and fragColor should be assigned with float4(1.0, 1.0, 1.0, 1.0), which means that the output color is white. However, the compiler incorrectly reasons that frac(t) == 0.0 is true, and assigns fragColor with float4(0.0, 0.0, 0.0, 1.0) (color black).


Steps to reproduce the bug


Prerequisite: Windows 10 system installed with Visual Studio 2022
2. Open D3DApp.sln with Visual Studio.
3. Check correct result: change line 3 of d3dUtils.cpp to "#define NO_OPTMIZATION 1" to disable all the optimizations of hlsl compiler. Click "Start Without Debugging". You will see a window with white body popped up. This means that the return value of the pixel shader is float4(1.0, 1.0, 1.0, 1.0) (color white).
4. Check buggy result: change line 3 of d3dUtils.cpp to "#define NO_OPTMIZATION 0" to enable the optimization of hlsl compiler. Click "Start without Debugging". You will see a small window popped up. The display area of the window is black, meaning that the return value of the pixel shader in HLSL/pixel.hlsl is float4(0.0, 0.0, 0.0, 1.0) (color black).


A brief explanation of the code


What the code does is quite basic. In lines 66~74 of GameApp.cpp, the program compiles the vertex shader HLSL/vertex.hlsl and the pixel shader HLSL/pixel.hlsl, and outputs the compiled *.cso file to the folder HLSL/. It prepares a square for displaying the output of the pixel shader. It sets a constant buffer variable iTime (later used in the pixel shader) in line 125 of GameApp.cpp. Then it executes and displays the rendering output in line 22 of Main.cpp.


Debugging with RenderDoc


If you use RenderDoc and follow the steps in to debug the compiled shader program, or use any of the dissembly tools to inspect the compiled shader program, you will see that the compiled shader directly assigns the output value with zero:



mov, l(0, 0, 0, 0)



It means that the compiler reasons that fract(a) == 0.0 is always true and assigns the output variable fragColor with black color.
8 Replies

Hi @Saniajuneor ,

Thank you for reporting it. I have whitelisted you for the Devgurus community and moved the post to the appropriate forum. 

 2. AMD Radeon RX 6400, with driver version 30.0.15021.11005 (used during the experiment)

It looks like a new driver is available here: . Could you please try this driver to see if the issue is reproducible or not?




I have updated the driver to your provided one. The bug still exists.


Thanks for testing with the latest driver and sharing the observation. I will report the issue to DirectX team.




Just FYI, a ticket has been created to investigate the issue. I will let you know once I get any update on this.



I posted another post yesterday reporting a different compiler bug. But somehow I cannot find that post on the forum today. The detailed descriptions, code, and reproduction steps for that bug are provided in this file:


The post was wrongly marked as spam by the auto spam-filter. I have removed it from the spam folder. Please check here:



Thanks! Could you check that bug as well?


I have reported the bug to the DirectX team.