#1063882 gcc: Internal error from ternary cond as inline asm parameter

Package:
gcc
Source:
gcc
Description:
GNU C compiler
Submitter:
VictorBW
Date:
2024-02-15 01:57:05 UTC
Severity:
normal
Tags:
#1063882#5
Date:
2024-02-14 01:10:39 UTC
From:
To:
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 :)

#1063882#10
Date:
2024-02-14 07:26:41 UTC
From:
To:
Control: tags -1 + moreinfo

please post the complete code example.

please also recheck with newer GCC versions (GCC 13, GCC 14) in newer
Debian development versions.

#1063882#17
Date:
2024-02-15 01:54:19 UTC
From:
To:
statement, so I tried the questionmark conditional operator, as in this
minimal example:
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.