Hi all, Can someone please explain me how to use REG_SEQUENCE in tablegen? The arch i'm writing backend for has 32-bit regs, and it has a couple of 64-bit load/store instructions which use two neighboring regs at once, which i'm trying to employ using virtual regs with subs. For example, it I want to move one 64-bit virtual reg to another, I'm trying to use the following pattern: def LoReg: OutPatFrag<(ops node:$Rd), (EXTRACT_SUBREG (i64 $Rd), isub_lo)>; def HiReg: OutPatFrag<(ops node:$Rd), (EXTRACT_SUBREG (i64 $Rd), isub_hi)>; def MOVi64rr : Pat<(set GPR64:$Rd, GPR64:$Rn), (REG_SEQUENCE GPR64, (MOVi32rr (HiReg GPR64:$Rn)), isub_hi, (MOVi32rr (LoReg GPR64:$Rn)), isub_lo)>; isub_hi and isub_lo are subregs of a single 64-bit virtual reg. When trying to compile it, im getting the following error: MOVi64rr: (set GPR64:i64:$Rd, GPR64:i64:$Rn) MOVi64rr: (REG_SEQUENCE:<empty> GPR64:i32, (MOVi32rr:i32 (EXTRACT_SUBREG:i32 GPR64:i64:$Rn, isub_hi:i32)), isub_hi:i32, (MOVi32rr:i32 (EXTRACT_SUBREG:i32 GPR64:i64:$Rn, isub_lo:i32)), isub_lo:i32) error: In MOVi64rr: Could not infer all types in pattern result! Assertion `SDNodes.count(R) && "Unknown node!"' failed. If i'll specify the type for REG_SEQUENCE, i.e. (i64 (REG_SEQUENCE ...)), it doesn't say anything about types, but it fails exactly at the same place with Assertion `SDNodes.count(R) && "Unknown node!"' failed. Thanks, Petr -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170322/53725f88/attachment.html>
On 03/22/2017 08:17 AM, Peter Bel via llvm-dev wrote:> Hi all, > > Can someone please explain me how to use REG_SEQUENCE in tablegen? > The arch i'm writing backend for has 32-bit regs, and it has a couple > of 64-bit load/store instructions which use two neighboring regs at > once, which i'm trying to employ using virtual regs with subs. > > For example, it I want to move one 64-bit virtual reg to another, I'm > trying to use the following pattern: > > def LoReg: OutPatFrag<(ops node:$Rd), (EXTRACT_SUBREG (i64 $Rd), > isub_lo)>; > def HiReg: OutPatFrag<(ops node:$Rd), (EXTRACT_SUBREG (i64 $Rd), > isub_hi)>; > def MOVi64rr : Pat<(set GPR64:$Rd, GPR64:$Rn), \'set' isn't something you can have in an input pattern. It is for assigning a result to a register, it isn't a DAG operation you can match against. You might be looking for bitconvert? -Matt
Yes, that will hold for the reg copy. But what about copying an immediate? Or subdividing one wide reg into two standard to run some math? Also, what'd be the best approach - using RegisterTuple like in AMDGPU, or using RegisterClass? On Wed, Mar 22, 2017 at 9:11 PM, Arsenault, Matthew < Matthew.Arsenault at amd.com> wrote:> I think you really just want to be emitting a COPY and handling the wide > registers in copyPhysReg for bitconvert > ------------------------------ > *From:* Peter Bel <upcfrost at gmail.com> > *Sent:* Wednesday, March 22, 2017 10:18:45 AM > *To:* Arsenault, Matthew > *Subject:* Re: [llvm-dev] REG_SEQUENCE use question > > Thanks for mentioning bitconvert, I completely forgot about it, and I > think there's a couple of places where I'll need it to be implemented. > About the REG_SEQUENCE - in fact the only 2 things that i want to be able > to do are to use 64-bit load/store instructions (which use RegisterTuples > similar to AMDGPU), and to handle 64-bit values (i.e. setting and saving > them). > The CPU itself can't handle any 64-bit ops except load/store, but as far > as i understood, having some kind of i64/f64 virtual reg class or tuple > (probably tuple would be better here) is necessary to use 64-bit types like > double. > > That said, I'm just not sure how to proceed with this stuff - should it be > regclass or regtuple, should i write additional patterns to handle all > other ops, etc. > > On Wed, Mar 22, 2017 at 7:32 PM, Matt Arsenault <Matthew.Arsenault at amd.com > > wrote: > >> On 03/22/2017 08:17 AM, Peter Bel via llvm-dev wrote: >> >>> Hi all, >>> >>> Can someone please explain me how to use REG_SEQUENCE in tablegen? >>> The arch i'm writing backend for has 32-bit regs, and it has a couple of >>> 64-bit load/store instructions which use two neighboring regs at once, >>> which i'm trying to employ using virtual regs with subs. >>> >>> For example, it I want to move one 64-bit virtual reg to another, I'm >>> trying to use the following pattern: >>> >>> def LoReg: OutPatFrag<(ops node:$Rd), (EXTRACT_SUBREG (i64 $Rd), >>> isub_lo)>; >>> def HiReg: OutPatFrag<(ops node:$Rd), (EXTRACT_SUBREG (i64 $Rd), >>> isub_hi)>; >>> def MOVi64rr : Pat<(set GPR64:$Rd, GPR64:$Rn), \ >>> >> 'set' isn't something you can have in an input pattern. It is for >> assigning a result to a register, it isn't a DAG operation you can match >> against. You might be looking for bitconvert? >> >> -Matt >> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170322/ea1410b6/attachment.html>
Krzysztof Parzyszek via llvm-dev
2017-Mar-22 21:35 UTC
[llvm-dev] REG_SEQUENCE use question
On 3/22/2017 3:15 PM, Peter Bel via llvm-dev wrote:> Yes, that will hold for the reg copy. But what about copying an > immediate? Or subdividing one wide reg into two standard to run some math?You can have a Pat that will convert an immediate into a value in a register. For example (from HexagonPatterns.td): def: Pat<(s32_0ImmPred:$s16), (A2_tfrsi imm:$s16)>; For dividing regs we use PatFrags LoReg and HiReg. -Krzysztof -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation