Bug with extended asm operand aliases

Documentation link:

The following code is miscompiled:

#include <stdio.h>
int main(void)
{
  int c1, c;

  asm ("mov $1, %[c1]\n"
       "mov $2, %[c]"
       : [c1] "=r" (c1),
         [c] "=r" (c));

  printf("1=%d 2=%d\n", c1, c);
}
$ nvc --version

nvc 22.11-0 64-bit target on x86-64 Linux -tp skylake-avx512 
NVIDIA Compilers and Tools
Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.  All rights reserved.

$ nvc asm.c
$ ./a.out 
1=2 2=2002284504

(or some other random number, expected is 1=1, 2=2, GCC, Clang, Intel all give you that)

the generated code has

  41:   be 01 00 00 00          mov    $0x1,%esi
  46:   be 02 00 00 00          mov    $0x2,%esi

ie. the wrong register is used for c, as it’s the same one as used for c2.

This issue came up trying to compile BLIS (GitHub - flame/blis: BLAS-like Library Instantiation Software Framework); NVHPC 22.7 had issues with the use of the rbp register in inline asm; 22.11 no longer has that issue but instead causes segmentation faults in its tests.

A workaround is to simply replace “c” by “c2”, it only seems to happen if one alias’ first letter(s) are the same as the full name of another one?

Thanks for the report Bart.

it only seems to happen if one alias’ first letter(s) are the same as the full name of another one?

Yes, I think you’re correct. It seems to occur when the second asm symbol name starts with and wholly included in the first. To avoid confusion with the program variable names, I changed the code to use “output” and “out”, and the same issue occurred.

I’ve filed a problem report, TPR#32778, and have asked engineering to investigate.

-Mat

Ho Bart,

FYI, TPR #32778 should be fixed in our 23.5 release.


% nvc asm1.c -Mkeepasm -O0 -V23.3 ; a.out
1=2 2=0
% nvc asm1.c -Mkeepasm -O0 -V23.5 ; a.out
1=1 2=2

-Mat