[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc-bugs
Subject:    [Bug target/89146] New: arm: "nor" constraint prefers memory reference over constant
From:       "fw at gcc dot gnu.org" <gcc-bugzilla () gcc ! gnu ! org>
Date:       2019-01-31 22:23:03
Message-ID: bug-89146-4 () http ! gcc ! gnu ! org/bugzilla/
[Download RAW message or body]

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.
"=
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic