Subject: gcc: Internal error from ternary cond as inline asm parameter
Date: Wed, 14 Feb 2024 01:10:39 +0000
Package: gcc
Version: 4:12.2.0-3
Severity: normal
X-Debbugs-Cc: [email protected]
Dear Maintainer,
I wanted to dynamically select registers for use in an inline assembly statement, so I tried the questionmark conditional operator, as in this minimal example:
namespace gpr {
volatile register int64_t r12 asm("r12");
volatile register int64_t r13 asm("r13");
...
asm volatile ("mov %0, blah" : "+r"((reg) ? gpr::r13 : gpr::r12));
This generates an internal error:
$ g++ bug.cpp
during RTL pass: expand
bug.cpp: In function ‘void move(uint8_t, int64_t)’:
bug.cpp:11:47: internal compiler error: in expand_expr_addr_expr_1, at expr.cc:8435
11 | asm volatile ("mov %0, blah" : "+r"((reg) ? gpr::r13 : gpr::r12));
| ~~~~~~^~~~~~~~~~~~~~~~~~~~~
g++ -freport-bug did not deem the bug reproducible, but godbolt.org produces the following backtrace
0x264bdbc internal_error(char const*, ...)
???:0
0xa523e3 fancy_abort(char const*, int, char const*)
???:0
0xf62e6e expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool)
???:0
0xf703ae store_expr(tree_node*, rtx_def*, int, bool, bool)
???:0
I expected:
Realistically, a proper compiler error
Optimistically, generation of appropriate branches
I will apply an alternative solution in the meantime, but the latter behaviour would be very nice to have.
Perhaps other builtins also generate improper errors when used with a conditional operator? (I have not tried)
First time Debian/GCC bugreport, please forgive any relevant blunders :)
-- System Information:
Debian Release: 12.5
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386, arm64
Kernel: Linux 6.1.0-17-amd64 (SMP w/12 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), LANGUAGE=en_GB:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages gcc depends on:
ii cpp 4:12.2.0-3
ii gcc-12 12.2.0-14
Versions of packages gcc recommends:
ii libc6-dev [libc-dev] 2.36-9+deb12u4
Versions of packages gcc suggests:
ii autoconf 2.71-3
ii automake 1:1.16.5-1.3
ii bison 2:3.8.2+dfsg-1+b1
ii flex 2.6.4-8.2
pn gcc-doc <none>
pn gcc-multilib <none>
ii gdb-minimal [gdb] 13.1-3
ii libtool 2.4.7-5
ii make 4.3-4.1
ii manpages-dev 6.03-2
-- no debconf information
Acknowledgement sent
to Matthias Klose <[email protected]>:
Extra info received and forwarded to list. Copy sent to Debian GCC Maintainers <[email protected]>.
(Wed, 14 Feb 2024 07:33:03 GMT) (full text, mbox, link).
Subject: Re: Bug#1063882: gcc: Internal error from ternary cond as inline asm
parameter
Date: Wed, 14 Feb 2024 08:26:41 +0100
Control: tags -1 + moreinfo
On 14.02.24 02:10, VictorBW wrote:
> Package: gcc
> Version: 4:12.2.0-3
> Severity: normal
> X-Debbugs-Cc: [email protected]
>
> Dear Maintainer,
>
> I wanted to dynamically select registers for use in an inline assembly statement, so I tried the questionmark conditional operator, as in this minimal example:
>
> namespace gpr {
> volatile register int64_t r12 asm("r12");
> volatile register int64_t r13 asm("r13");
> ...
> asm volatile ("mov %0, blah" : "+r"((reg) ? gpr::r13 : gpr::r12));
>
please post the complete code example.
please also recheck with newer GCC versions (GCC 13, GCC 14) in newer
Debian development versions.
> This generates an internal error:
> $ g++ bug.cpp
> during RTL pass: expand
> bug.cpp: In function ‘void move(uint8_t, int64_t)’:
> bug.cpp:11:47: internal compiler error: in expand_expr_addr_expr_1, at expr.cc:8435
> 11 | asm volatile ("mov %0, blah" : "+r"((reg) ? gpr::r13 : gpr::r12));
> | ~~~~~~^~~~~~~~~~~~~~~~~~~~~
>
> g++ -freport-bug did not deem the bug reproducible, but godbolt.org produces the following backtrace
> 0x264bdbc internal_error(char const*, ...)
> ???:0
> 0xa523e3 fancy_abort(char const*, int, char const*)
> ???:0
> 0xf62e6e expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool)
> ???:0
> 0xf703ae store_expr(tree_node*, rtx_def*, int, bool, bool)
> ???:0
>
> I expected:
> Realistically, a proper compiler error
> Optimistically, generation of appropriate branches
>
> I will apply an alternative solution in the meantime, but the latter behaviour would be very nice to have.
>
> Perhaps other builtins also generate improper errors when used with a conditional operator? (I have not tried)
>
> First time Debian/GCC bugreport, please forgive any relevant blunders :)
>
> -- System Information:
> Debian Release: 12.5
> APT prefers stable-updates
> APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
> Architecture: amd64 (x86_64)
> Foreign Architectures: i386, arm64
Acknowledgement sent
to some body <[email protected]>:
Extra info received and forwarded to list. Copy sent to Debian GCC Maintainers <[email protected]>.
(Thu, 15 Feb 2024 01:57:04 GMT) (full text, mbox, link).
On Wed, 14 Feb 2024 08:26:41 +0100 Matthias Klose <[email protected]> wrote:
> Control: tags -1 + moreinfo
>
> On 14.02.24 02:10, VictorBW wrote:
> > Package: gcc
> > Version: 4:12.2.0-3
> > Severity: normal
> > X-Debbugs-Cc: [email protected]
> >
> > Dear Maintainer,
> >
> > I wanted to dynamically select registers for use in an inline assembly
statement, so I tried the questionmark conditional operator, as in this
minimal example:
> >
> > namespace gpr {
> > volatile register int64_t r12 asm("r12");
> > volatile register int64_t r13 asm("r13");
> > ...
> > asm volatile ("mov %0, blah" : "+r"((reg) ? gpr::r13 : gpr::r12));
> >
>
> please post the complete code example.
>
> please also recheck with newer GCC versions (GCC 13, GCC 14) in newer
> Debian development versions.
>
I do not have GCC 13/14 installed, but godbolt.org's copy of GCC 13 and
trunk will not compile the following complete example
int main(int argc, char** argv) {
register long reg_1 asm("r12");
register long reg_2 asm("r13");
asm volatile ("mov %0, %%r11" : "+r"((argc) ? reg_2 : reg_1));
}
I note that in C mode (gcc minbug.c) a different error is produced (error:
lvalue required in ‘asm’ statement), but in C++ mode (g++ minbug.c) we get
the internal compiler error, and that selecting an input parameter the same
way (rather than an output parameter) seems to work correctly.
Debbugs is free software and licensed under the terms of the GNU General
Public License version 2. The current version can be obtained
from https://bugs.debian.org/debbugs-source/.