https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89146
Bug ID: 89146 Summary: arm: "nor" constraint prefers memory reference over constant Product: gcc Version: 8.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: fw at gcc dot gnu.org Target Milestone: --- Target: armv7l-unknown-linux-gnueabihf This example: #define C "nor" void f (int *x) { asm volatile ("MARK %0, %1, %2, %3" :: C(0), C(x), C("string"), C(*x)); } expands to: MARK .L3, r0, r3, [r0] The .L3 is entirely unexpected. This probably does not matter to real Arm instructions because they do not have a "no" alternative in their constraints. But it also occurs with Systemtap probes. We could use "nr" instead, but that regresses slightly in case of indirect memory references. In the downstream bug, Jakub identified the source of the behavior: “ The pushing of the constants into minipool happens in arm_reorg -> note_invalid_constants /* Things we need to fix can only occur in inputs. */ if (recog_data.operand_type[opno] != OP_IN) continue; /* If this alternative is a memory reference, then any mention of constants in this alternative is really to fool reload into allowing us to accept one there. We need to fix them up now so that we output the right code. */ if (op_alt[opno].memory_ok) { rtx op = recog_data.operand[opno]; if (CONSTANT_P (op)) { if (do_pushes) push_minipool_fix (insn, address, recog_data.operand_loc[opno], recog_data.operand_mode[opno], op); } and the rule it uses is simple, if the constraint allows a memory, then it pushes it into memory, no matter whether it is also allowed to be a constant or not. ”