Possible miscompilation of an empty switch

Test settings

System:    Host: - Kernel: 5.11.0-25-generic x86_64 bits: 64 compiler: gcc v: 10.2.1 Desktop: GNOME 3.38.4 
           tk: GTK 3.24.25 wm: gnome-shell dm: GDM3 Distro: Ubuntu 21.04 (Hirsute Hippo) 
CPU:       Info: 6-Core model: Intel Core i7-8750H bits: 64 type: MT MCP arch: Kaby Lake note: check rev: A L2 cache: 9 MiB 
           flags: avx avx2 lm nx pae sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx bogomips: 52799 
           Speed: 2800 MHz min/max: 800/4100 MHz Core speeds (MHz): 1: 2800 2: 2800 3: 2800 4: 2130 5: 2800 6: 2642 7: 2742 
           8: 2761 9: 2782 10: 2628 11: 2691 12: 2710 
Graphics:  Device-1: Intel CoffeeLake-H GT2 [UHD Graphics 630] vendor: ASUSTeK driver: i915 v: kernel bus ID: 00:02.0 
           chip ID: 8086:3e9b 
           Device-2: NVIDIA GP107M [GeForce GTX 1050 Ti Mobile] vendor: ASUSTeK driver: nvidia v: 470.57.02 bus ID: 01:00.0 
           chip ID: 10de:1c8c 
           Device-3: IMC Networks USB2.0 HD UVC WebCam type: USB driver: uvcvideo bus ID: 1-7:3 chip ID: 13d3:5666 
           Display: x11 server: X.Org 1.20.11 compositor: gnome-shell driver: loaded: modesetting,nvidia 
           unloaded: fbdev,nouveau,vesa resolution: 1: 1920x1080~120Hz 2: 1920x1080~60Hz s-dpi: 96 
           OpenGL: renderer: NVIDIA GeForce GTX 1050 Ti/PCIe/SSE2 v: 4.6.0 NVIDIA 470.57.02 direct render: Yes 

Description

The following code containing an empty switch body does not seem to execute the side-effecting operation in the switch statement.

#version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(std430, binding = 0) buffer buffer_0 {
 uint ext_0; // 0
 uint ext_1; // 5
} ;
void main()
{
  ext_0 += ext_1; // ext_0 = 5
  switch(ext_1 ^= ext_0) // ext_0 = 5 ^ 5 = 0
  {
  }
}

NVIDIA output:

buffer_0 5 5

Expected output:

buffer_0 5 0

Thinking process:

  • The first line affects the value ext_0 = 5
  • The second line affects the ext_1 with xor ext_0 so ext_1 = 0

Code link

For the related code in the shadertrap test format, see: shader03.shadertrap (655 Bytes)
Shadertrap is a testing framework. To use the shadetrap code,

  1. Get or build Shadertrap:
    1. A build version of Shadertrap for linux can be found on Shadertrap release repository.
    2. To build from source, please refer to Shadertrap repository
  2. Ge the shader file
  3. Execute the Shadertrap command
bin/shadertrap shader03.shadertrap
  1. Collect the results, one file per buffer

I am able to duplicate issue and filed a bug 200764746 internally for the tracking purpose.
Shall update with our findings.

1 Like

Issue has been fixed and will be incorporated in future released driver.