This is an archive of the discontinued LLVM Phabricator instance.

[InlineAsm, SystemZ] Handle inline assembly address operands.
ClosedPublic

Authored by jonpa on Sep 22 2021, 9:56 AM.

Details

Summary

Handle ZQ, ZR, ZS, ZT and p inline assembly operand constraints. These represent address operands on SystemZ as used by the Load Address instruction.

These have most things in common with memory operands in the way they need to be handled, except that the instruction using the address does not actually touch memory.

Just like with memory operands, the address can be folded into the using instruction to various degrees. For example, ZT and p allow Base + Index + 20-bit displacement, while ZS does not allow the index register.

In order to handle address operands I made them a subclass of the possible memory operands. They are recognized by their memory constraint codes and a new method isAddress() returns true for these. That way a memory operand can be recognized to actually touch memory or not. I first experimented with a new ConstraintType C_Address (like C_Memory), but it seemed simpler to let them be a type of memory operands instead.

There is still the general/default handling of 'p' which seems to be to treat it as a register. Currently it would be up to each target to handle addresses differently (per this patch).

Todo: CodeGenPrepare could also optimize for address folding for these just like for memory operands, I think.

Feedback most welcome!

Diff Detail

Event Timeline

jonpa created this revision.Sep 22 2021, 9:56 AM
jonpa requested review of this revision.Sep 22 2021, 9:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 22 2021, 9:56 AM

Finally getting back to this patch - sorry for the long delay.

I think it would be worthwhile to explore using a dedicated C_Address constraint type - these constraints are different from memory. In particular, memory constraints usually require the front-end to also use the "indirect" flag since the asm statement requires the address as argument. For actual address operands, these are already addresses at the source level, so they are not indirect.

Using different C_Address and C_Memory types would also force all places that treat constaints to be explicitly updated to handle address constraints, requiring deliberate choices. This seems preferable since the constraint types frequently do require different treatment.

As an aside, in addition to SelectionDAGBuilder, which this patch updates, there is also inline asm constraint handling in GlobalISel/InlineAsmLowering which needs similar changes.

Finally, I tried to play with address constraints on Intel, and the "p" constraint as currently implemented on Intel seems to be actually incorrect. For example, compiling the following code:

void *test (void *ptr)
{
        void *ret;
        asm ("lea %1, %0" : "=r" (ret) : "p" (ptr));
        return ret;
}

with GCC results in:

lea %rdi, %rax
ret

while with clang we get instead:

movq    %rdi, -8(%rsp)
leaq    -8(%rsp), %rax
retq

(i.e. we get the address of a stack slot where ptr was stored, rather than the value of ptr)

So it might make sense to have two patches instead, a first patch that introduces the C_Address mechanism, and uses it to implement the "p" constraint in a platform-independent manner, fixing in particular this bug on Intel. And then in a second patch add the SystemZ-specific address constraints.

jonpa updated this revision to Diff 417238.Mar 22 2022, 3:53 AM
jonpa removed reviewers: rnk, Amanieu, cynecx, lewis-revill, dsanders.

Patch updated per review...

Using different C_Address and C_Memory types would also force all places that treat constaints to be explicitly updated to handle address constraints, requiring deliberate choices. This seems preferable since the constraint types frequently do require different treatment.

Ok - I tried this at https://reviews.llvm.org/D122220.

So it might make sense to have two patches instead, a first patch that introduces the C_Address mechanism, and uses it to implement the "p" constraint in a platform-independent manner, fixing in particular this bug on Intel. And then in a second patch add the SystemZ-specific address constraints.

This patch here is now the SystemZ specific address constraints, on top of the patch for "p" (see above).

Herald added a project: Restricted Project. · View Herald TranscriptMar 22 2022, 3:53 AM
jonpa updated this revision to Diff 420428.Apr 5 2022, 2:54 AM

Formatting.

uweigand accepted this revision.Apr 19 2022, 7:25 AM

LGTM, thanks!

This revision is now accepted and ready to land.Apr 19 2022, 7:25 AM
This revision was landed with ongoing or failed builds.Apr 19 2022, 7:56 AM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptApr 19 2022, 7:56 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript