https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120801

            Bug ID: 120801
           Summary: Using const variables as immediate values in extended
                    assembly constraints with -O0 (x86)
           Product: gcc
           Version: 15.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: oskari.alaranta at bananymous dot com
  Target Milestone: ---

Passing immediate values to instructions from const(/constexpr in c++)
variables does not seem to be working correctly on gcc 15.1.0/15.1.1. I have
tested with custom gcc and gcc from Arch linux's repositories. With gcc 12.2.0
I had no issues and I could not find anything regarding this from
https://gcc.gnu.org/bugs/#upgrading. This issue seems to only happen with -O0.

For example x86 instruction int takes 8 bit immediate, but inline assembly
constraint 'i' does not work with uint8_t/char/unsigned char (with 8 bit char).
The following code reports "impossible constraint in `asm`" with -O0 but not
with other optimization levels. Using larger variables short/int/long/long long
work fine even with -O0 though.

void foo(void) {
    const uint8_t value = 0x80;
    asm("int %0" :: "i"(value));
}

I also tested other instructions (add, test, ret) that should accept immediates
but the same problem occurs. Passing the value as an integer literal works in
the failing cases.

Preprocessed output and compiler configuration for `int` instruction with imm8
passed from const unsigned char variable.
// Target: x86_64-pc-linux-gnu
// Configured with: /build/gcc/src/gcc/configure
--enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++,rust,cobol
--enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib
--mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues
--with-build-config=bootstrap-lto --with-linker-hash-style=gnu
--with-system-zlib --enable-__cxa_atexit --enable-cet=auto
--enable-checking=release --enable-clocale=gnu --enable-default-pie
--enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object
--enable-libstdcxx-backtrace --enable-link-serialization=1
--enable-linker-build-id --enable-lto --enable-multilib --enable-plugin
--enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-werror
// Thread model: posix
// Supported LTO compression algorithms: zlib zstd
// gcc version 15.1.1 20250425 (GCC) 
// 
//gcc-int.c: In function ‘foo’:
//gcc-int.c:3:5: warning: ‘asm’ operand 0 probably does not match constraints
//    3 |     asm("int %0" :: "i"(irq) : "memory");
//      |     ^~~
//gcc-int.c:3:5: error: impossible constraint in ‘asm’

// gcc gcc-int.c

# 0 "gcc-int.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "gcc-int.c"
void foo(void) {
    const unsigned char irq = 0x80;
    asm("int %0" :: "i"(irq) : "memory");
}

Reply via email to