This is an archive of the discontinued LLVM Phabricator instance.

[FPEnv][AArch64] Implement lowering of llvm.set.rounding
ClosedPublic

Authored by sepavloff on Feb 16 2021, 9:37 PM.

Diff Detail

Event Timeline

sepavloff created this revision.Feb 16 2021, 9:37 PM
sepavloff requested review of this revision.Feb 16 2021, 9:37 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 16 2021, 9:37 PM
simon_tatham added inline comments.Feb 17 2021, 5:22 AM
llvm/test/CodeGen/AArch64/fpenv.ll
13

This may be outside the scope of your patch, but do you have any idea why this hasn't come out as BIC x8, x8, #0xC00000, but instead, has carefully materialized ~0xC00000 in a register so that it can use AND instead of BIC?

sepavloff added inline comments.Feb 17 2021, 8:00 AM
llvm/test/CodeGen/AArch64/fpenv.ll
13

Looking at A64 instruction documentation, I see that BIC has only register, register variant.

simon_tatham added inline comments.Feb 17 2021, 8:10 AM
llvm/test/CodeGen/AArch64/fpenv.ll
13

Yes, sorry – I misremembered what the official name of the instruction was. (I'm more of an AArch32 expert than AArch64.)

But there is an immediate instruction that does what you want. This C source

unsigned long foo(unsigned long x) { return x & ~0xC00000L; }

compiles to this instruction:

and     x0, x0, #0xffffffffff3fffff
kpn added a subscriber: kpn.Feb 17 2021, 11:13 AM
david-arm added inline comments.
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
3493

Should RMMask be uint64_t here since you're creating a MVT::i64 constant?

sepavloff updated this revision to Diff 324571.Feb 18 2021, 2:05 AM

Changed variable type from unsigned to int

sepavloff added inline comments.Feb 18 2021, 2:15 AM
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
3493

Yes, it caused inefficient code generation, as noted by @simon_tatham. How it has type int because it is converted to 64-bit value using sign extension, so produces convenient constant.

llvm/test/CodeGen/AArch64/fpenv.ll
13

This is result of using unsigned for RMMask. When it is converted to 64-bit value, upper 32 bits were zero, this constant cannot be represented as a logical constant in AND instruction, so more complex construct was used for this constant. Using int as the variable type results in sign-extended value, in which upper half is all ones and it can be encoded as immediate in AND.

The generated code becomes better. Thank you!

simon_tatham accepted this revision.Feb 18 2021, 3:54 AM

Looks nicer now, thanks!

This revision is now accepted and ready to land.Feb 18 2021, 3:54 AM
This revision was landed with ongoing or failed builds.Feb 18 2021, 10:17 PM
This revision was automatically updated to reflect the committed changes.