Paulo Matos via llvm-dev
2016-Jul-21 15:00 UTC
[llvm-dev] InlineAsm and allocation to wrong register for indirect access
Hi, I am seeing a case, in a private port, of an inline asm with indirect memory references being allocated invalid registers (i.e. registers that cannot be used on loads). For example, the inline asm constraint is correct: call void asm sideeffect "MOV $$r0, $0\0AMOV $$r0, $1\0A", "*m,*m,~{r0}"(i16* @a, i16* %b) #1, !srcloc !1 but then $0 and $1 are allocated to registers that cannot be used as a memory base pointer. I am having trouble finding where this decision is made. Is InlineAsm going through the normal register allocation process or does it have its own specialized algorithm? Any pointers to how registers are allocated in an InlineAsm would be helpful. Kind regards, -- Paulo Matos
Daniel Sanders via llvm-dev
2016-Jul-22 09:30 UTC
[llvm-dev] InlineAsm and allocation to wrong register for indirect access
Hi, I'm not sure where this decision is done but it's possible that there's no constraint-specific selection of register classes for memory operands at the moment in which case it probably uses ${Target}RegisterInfo::getPointerRegClass() without checking the constraint code. I had a similar problem with constraint-specific offset ranges a year or so ago and found that all memory constraints were hardcoded to be 'm' regardless of the constraint in the inline assembly statement. Here's a couple things to look for that might help you find the right code: If you search for getFlagWordForMem() you'll find the code that passes the constraint id (Constraint_m, Constraint_ZC, etc.) into SelectionDAG's ISD::INLINEASM node and https://reviews.llvm.org/rL275786 made the constraint available to the TargetOpcode::INLINEASM instruction. Also, register constraints pick the register class (and sometimes the register too) in ${Target}TargetLowering::getRegForInlineAsmConstraint(). Hope that helps> -----Original Message----- > From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of Paulo > Matos via llvm-dev > Sent: 21 July 2016 16:01 > To: llvm-dev > Subject: [llvm-dev] InlineAsm and allocation to wrong register for indirect > access > > Hi, > > I am seeing a case, in a private port, of an inline asm with indirect > memory references being allocated invalid registers (i.e. registers that > cannot be used on loads). > > For example, the inline asm constraint is correct: > call void asm sideeffect "MOV $$r0, $0\0AMOV $$r0, $1\0A", > "*m,*m,~{r0}"(i16* @a, i16* %b) #1, !srcloc !1 > > but then $0 and $1 are allocated to registers that cannot be used as a > memory base pointer. > > I am having trouble finding where this decision is made. Is InlineAsm > going through the normal register allocation process or does it have its > own specialized algorithm? > > Any pointers to how registers are allocated in an InlineAsm would be > helpful. > > Kind regards, > > -- > Paulo Matos > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Paulo Matos via llvm-dev
2016-Jul-22 18:52 UTC
[llvm-dev] InlineAsm and allocation to wrong register for indirect access
On 22/07/16 11:30, Daniel Sanders wrote:> Hi, > > I'm not sure where this decision is done but it's possible that > there's no constraint-specific selection of register classes for > memory operands at the moment in which case it probably uses > ${Target}RegisterInfo::getPointerRegClass() without checking the > constraint code. I had a similar problem with constraint-specific > offset ranges a year or so ago and found that all memory constraints > were hardcoded to be 'm' regardless of the constraint in the inline > assembly statement. >Thanks Daniel, I found the problem to be on our SelectInlineAsmMemoryOperand which was not returning the correct operand. Now, if I implement it similarly to PPC by returning a COPY_TO_REGCLASS of the operand, I get the correct operand but with the strange offset. So a load from an operand to r0: mov r0, %0, where %0 has 'm' constraint is transformed into mov r0, @r4+12. r4 is the correct choice for a load but I have no idea where `+12` comes from. Do you know how to find where this offset could be added? The IR doesn't show the operand show it's impossible to tell from a straightforward debug dump. -- Paulo Matos