[llvm-dev] Correct modelling of instructions with types smaller than the register class

Amara Emerson via llvm-dev llvm-dev at lists.llvm.org
Mon Mar 23 16:56:10 PDT 2020

Hi Dominik,

> On Mar 12, 2020, at 9:46 AM, Dominik Montada <dominik.montada at hightec-rt.com> wrote:
> Hi Quentin,
> thank you for the reply! I have a couple more questions that came up when I tried to implement this today. I hope you can help me out with this again!
> Am 09.03.20 um 23:31 schrieb Quentin Colombet:
>> I would expect that you could create a register class and register bank for the special register. That way you have something to map to when you do register bank select.
>> The register class could be "not allocatable” (see CCR in AArch64 for instance).
>> Note, that if that class is unallocable, you’ll have to manage manually any overlapping that could arise.
>> E.g.,
>> s32 ..., s1 carry1 = G_UADDO
>> s32 ..., s1 carry2 = G_UADDO
>> s32 extended_carry1 = zext s1 carry1 <— carry1 will be destroyed by the second G_UADDO, you’ll have to fix the schedule or copy the value manually.
>> s32 extended_carry2 = zext s1 carry2
>> icmp s32 extended_carry1, extended_carry2
> So before instruction selection we would need to check if there are any overlaps and if so try to fix them if possible or abort compilation if that is not possible?
>> Then when you do instruction selection, just map the register to the physical register. (You may want to do the fix-ups I mentioned here.)
> What exactly do you mean by "map the register to the physical register"? Do you mean that I should just emit a COPY from/to this physical register and constrain the virtual register to the non-allocatable register class? Because this actually gives me an assertion that the register class must be allocatable. Or do you mean to use the physical register in the target instruction instead of the virtual one (i.e. drop the usage of the virtual register and replace it with the physical register)? The target instruction uses the physical register implicitly by the way.
> I also tried to take a look at how AArch64 implements G_UADDO/G_UADDE but it doesn't seem to fully implement selection for those? Maybe I just didn't read the code properly…
AArch64 doesn’t use the condition register bank, it was added before I joined the project so I’m not entirely sure what the intent was. However, the condition register side effect is something that we explicitly capture in SSA variables by copying every definition into a GPR, for which we do have regbanks for. We do this by using CSET/CSINC instructions on AArch64 which allow us to set a GPR register using the value of the condition register. We do this in every selection of an instruction like G_ICMP or G_UADDO which may write write a flag output.

%c1(s1) = G_ICMP eq, %foo, %bar

…can be selected into
cmp x0, x1
csinc x8, xzr, xzr, eq

Which results in the %c1 value being written to the register x8. Because we select in this way, we don’t have any extra side effects to model before selection time. It’s all in SSA. We then have selection patterns that try to optimize sequences like this if we can depending on the context.

For G_UADDO, you can see in the selector code that we emit an ADDS flag setting instruction, and then extract the carry flag using a CSET into the carry destination virtual register.

>> I would expect that you could create a register class and register bank for the special register. That way you have something to map to when you do register bank select.
> I looked at the CC regbank of AArch64, however I didn't see any mappings using it in RegBankInfo. Is that something that AArch64 simply hasn't implemented or is there something going on that I'm not seeing. I mean, what is the point to have a register bank when it is not used during regbankselect? I would at least expect that for example G_UADDO would use this register bank for the s1 carry out.
>> Generally speaking, I think you would need a copy (or zext/sext) to move the value in general purpose land (like in my example with zext). If you don’t have such use, the copy wouldn’t be emitted and there is nothing to do.
>> To be honest, I think the situation is complicated today because GISel lack the fix-up that I mentioned. I am actually surprised that didn’t come up as an issue yet (x86 is full of these flags). Going forward, I think it should just come with the framework: you assign a physreg selection time, GISel copies it around/reschedule appropriately to preserve the value. There’s a lot of wishful thinking here x).
>> Cheers,
>> -Quentin
> Best regards,
> Dominik
> -- 
> ----------------------------------------------------------------------
> Dominik Montada                   Email: dominik.montada at hightec-rt.com
> HighTec EDV-Systeme GmbH          Phone: +49 681 92613 19
> Europaallee 19                    Fax:   +49-681-92613-26
> D-66113 Saarbrücken               WWW: http://www.hightec-rt.com
> Managing Director: Vera Strothmann
> Register Court: Saarbrücken, HRB 10445, VAT ID: DE 138344222
> This e-mail may contain confidential and/or privileged information. If
> you are not the intended recipient please notify the sender immediately
> and destroy this e-mail. Any unauthorised copying, disclosure or
> distribution of the material in this e-mail is strictly forbidden.
> ---

More information about the llvm-dev mailing list