https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70184
Bug ID: 70184 Summary: Exlpicit register variables overwritten by conversion libcall Product: gcc Version: 6.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: inline-asm Assignee: unassigned at gcc dot gnu.org Reporter: ktkachov at gcc dot gnu.org Target Milestone: --- Target: arm Consider the testcase: void foo(unsigned a, float b) { unsigned c = (unsigned) b; register unsigned r0 __asm__("r0") = a; register unsigned r1 __asm__("r1") = c; __asm__ volatile( "str %[r1], [%[r0]]\n" : : [r0] "r" (r0), [r1] "r" (r1)); } Compile for an arm target with (for example) -Os -mfloat-abi=soft -march=armv7-a -marm. This generates: foo: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 push {r4, lr} mov r0, r1 bl __aeabi_f2uiz mov r1, r0 .syntax divided @ 7 "foo.c" 1 str r1, [r0] @ 0 "" 2 .syntax unified pop {r4, pc} The register r0 holding 'a' gets overwritten as part of the setup for the rounding libcall so when it gets tied to the variable 'r0' expecting it to hold 'a' it gets garbage instead. This testcase is warned about in: https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables but the code above explicitly follows the workaround suggested on that page so I'd expect it to work. Is this indeed a supported usecase of local register variables? and if so, is there a workaround for this bug?