Dr. ERDI Gergo via llvm-dev
2017-May-28 10:04 UTC
[llvm-dev] Pseudo-instruction that overwrites its input register
On Sun, 28 May 2017, David Chisnall wrote:>> let Constraints = "@earlyclobber $reg" in >> def LDWRdPtr : Pseudo<(outs DREGS:$reg), >> (ins PTRREGS:$ptrreg), >> "ldw\t$reg, $ptrreg", >> [(set i16:$reg, (load i16:$ptrreg))]>, >> Requires<[HasSRAM]>; >> >> The problem, of course, is that with this definition I end up with code which assumes it is equivalent to save P before 'ldw r1:r2,P' or after. I tried adding "@earlyclobber $ptrreg" as a Constraint, but that just leads to an assertion failure during codegen (I assume because @earlyclobber is for output ports) > > You need to express the P as both an input and output operand and add a constraint that both must be the same register.OK, but then the pattern will have to include that extra output operand somehow, right? What would the pattern need to be so that during ISel, this LDWRdPtr instruction with the extra output still matches?
Nemanja Ivanovic via llvm-dev
2017-May-30 03:43 UTC
[llvm-dev] Pseudo-instruction that overwrites its input register
This is typically accomplished with something like PPC's `RegConstraint` and `NoEncode`. You can see examples of it that are very similar to what you're after in PPC's load/store with update forms (i.e. load a value and update the base register with the effective address - these are used for pre-increment loads/stores). For example: the definition of LBZU and friends in lib/Target/PowerPC/PPCInstrInfo.td. For a simpler example of just the `RegConstraint` usage (as it doesn't use a compound node like PPC's address nodes), you can look at all the fused multiply-add such as XSMADDADP in lib/Target/PowerPC/PPCInstrVSX.td. Hope this helps. On Sun, May 28, 2017 at 12:04 PM, Dr. ERDI Gergo via llvm-dev < llvm-dev at lists.llvm.org> wrote:> On Sun, 28 May 2017, David Chisnall wrote: > > let Constraints = "@earlyclobber $reg" in >>> def LDWRdPtr : Pseudo<(outs DREGS:$reg), >>> (ins PTRREGS:$ptrreg), >>> "ldw\t$reg, $ptrreg", >>> [(set i16:$reg, (load i16:$ptrreg))]>, >>> Requires<[HasSRAM]>; >>> >>> The problem, of course, is that with this definition I end up with code >>> which assumes it is equivalent to save P before 'ldw r1:r2,P' or after. I >>> tried adding "@earlyclobber $ptrreg" as a Constraint, but that just leads >>> to an assertion failure during codegen (I assume because @earlyclobber is >>> for output ports) >>> >> >> You need to express the P as both an input and output operand and add a >> constraint that both must be the same register. >> > > OK, but then the pattern will have to include that extra output operand > somehow, right? What would the pattern need to be so that during ISel, this > LDWRdPtr instruction with the extra output still matches? > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170530/e2834478/attachment.html>
Dr. ERDI Gergo via llvm-dev
2017-May-30 13:01 UTC
[llvm-dev] Pseudo-instruction that overwrites its input register
On Tue, 30 May 2017, Nemanja Ivanovic wrote:> This is typically accomplished with something like PPC's `RegConstraint` and > `NoEncode`. You can see examples of it that are very similar to what you're after in > PPC's load/store with update forms (i.e. load a value and update the base register > with the effective address - these are used for pre-increment loads/stores). > For example: the definition of LBZU and friends in lib/Target/PowerPC/PPCInstrInfo.td. > For a simpler example of just the `RegConstraint` usage (as it doesn't use a compound > node like PPC's address nodes), you can look at all the fused multiply-add such as > XSMADDADP in lib/Target/PowerPC/PPCInstrVSX.td. > > Hope this helps.Thanks! However, none of the NoEncode examples in PPCInstrInfo.td seem to have an isel pattern; and the VSX examples, like XSMADDADP, seem to match on setting a single output: let BaseName = "XSMADDADP" in { let isCommutable = 1 in def XSMADDADP : XX3Form<60, 33, (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsmaddadp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; If I'm reading this right, this matches an instruction that updates $XT by taking the current $XT, and two extra args in $XA and $XB. However, my situation would be something akin to (set f64:$XC, (fma f64:$XA, f64:$XB, f64:$XTi)) with the extra constraint that $XTi is overwritten in the process. Is there maybe a way to write a pattern like (set (tuple f64:$XC, f64:$XT), (fma f64:$XA, f64:$XB, f64:$XTi)) that would match (set f64:$XC, (fma f64:$XA, f64:$XB, f64:$XTi)) by automatically lifting it to store $XT as well? (of course, with a RegConstraint that $XT = $XTi)