Possible miscompilation in a vector used in a ternary operator

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 array affectation before a ternary operator seems to return a wrong result.

#version 450

layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

layout(std430, binding = 0) buffer buffer_0 {
 int ext_0[2]; // 0 1
};
void main()
{
 bvec2 var_0[2] = bvec2[2](bvec2(true), bvec2(true));
 var_0 = bvec2[2](bvec2(true, false), bvec2(false, true));
 ext_0[0] = var_0[ext_0[1]].r ? 1 : 2;
}

NVIDIA output:

buffer_0 1 1

Expected output:

buffer_0 2 1

Thinking process:

  • ext_0[1]=1 so var_0[1] is examined
  • var_0[1].r = false so 2 is returned

Code link

For the related code in the shadertrap test format, see: shader22.shadertrap (729 Bytes)

Shadertrap is a testing framework. To use the shadetrap code,

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