[LLVMdev] Be Careful with Positionally-Encoded Operands (AArch64, Mips, AMDGPU, etc.)

Hal Finkel hfinkel at anl.gov
Thu Mar 13 08:41:49 PDT 2014


----- Original Message -----
> From: "Tom Stellard" <tom at stellard.net>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
> Sent: Thursday, March 13, 2014 10:39:48 AM
> Subject: Re: [LLVMdev] Be Careful with Positionally-Encoded Operands (AArch64, Mips, AMDGPU, etc.)
> 
> On Thu, Mar 13, 2014 at 10:01:32AM -0500, Hal Finkel wrote:
> > ----- Original Message -----
> > > From: "Tom Stellard" <tom at stellard.net>
> > > To: "Hal Finkel" <hfinkel at anl.gov>
> > > Cc: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
> > > Sent: Thursday, March 13, 2014 9:46:22 AM
> > > Subject: Re: [LLVMdev] Be Careful with Positionally-Encoded
> > > Operands (AArch64, Mips, AMDGPU, etc.)
> > > 
> > > On Thu, Mar 13, 2014 at 03:21:47AM -0500, Hal Finkel wrote:
> > > > Hello,
> > > > 
> > > > Some of the backends seem to be combining positional and named
> > > > operands when defining some instructions such that some of the
> > > > positional operands overlap with some of the named operands. I
> > > > suspect this is not intentional; here's an example:
> > > > 
> > > > AArch64 has the following instruction definition:
> > > > 
> > > > SMULHxxx {
> > > >   field bits<32> Inst = { 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0,
> > > >   Rm{4},
> > > >   Rm{3}, Rm{2}, Rm{1}, Rm{0}, 0, Ra{4}, Ra{3}, Ra{2}, Ra{1},
> > > >   Ra{0}, Rn{4}, Rn{3}, Rn{2}, Rn{1}, Rn{0}, Rd{4}, Rd{3},
> > > >   Rd{2},
> > > >   Rd{1}, Rd{0} };
> > > >   ...
> > > >   dag OutOperandList = (outs GPR64:$Rd);
> > > >   dag InOperandList = (ins GPR64:$Rn, GPR64:$Rm);
> > > >   string AsmString = "smulh	$Rd, $Rn, $Rm";
> > > >   list<dag> Pattern = [(set i64:$Rd, (mulhs i64:$Rn,
> > > >   i64:$Rm))];
> > > >   ...
> > > >   bits<5> Rd = { ?, ?, ?, ?, ? };
> > > >   bits<5> Rn = { ?, ?, ?, ?, ? };
> > > >   bits<5> Rm = { ?, ?, ?, ?, ? };
> > > >   bits<5> Ra = { ?, ?, ?, ?, ? };
> > > > ...
> > > > }
> > > > 
> > > > So how do the operands in OutOperandList and InOperandList get
> > > > mapped to the variables used to encode the instruction
> > > > (Rd,Rn,Rm,Ra)? The first three match by name (as they appear
> > > > explicitly in OutOperandList and InOperandList), but what about
> > > > Ra? Ra contributes to defining the bits in Inst, and because
> > > > there
> > > > is, by default, no overlap checking, it also gets mapped to the
> > > > first operand: GPR64:$Rd. The result, from
> > > > AArch64GenMCCodeEmitter.inc is:
> > > > 
> > > >     case AArch64::SMULHxxx:
> > > >     case AArch64::UMULHxxx: {
> > > >       // op: Rd
> > > >       op = getMachineOpValue(MI, MI.getOperand(0), Fixups,
> > > >       STI);
> > > >       Value |= op & UINT64_C(31);
> > > >       // op: Rn
> > > >       op = getMachineOpValue(MI, MI.getOperand(1), Fixups,
> > > >       STI);
> > > >       Value |= (op & UINT64_C(31)) << 5;
> > > >       // op: Rm
> > > >       op = getMachineOpValue(MI, MI.getOperand(2), Fixups,
> > > >       STI);
> > > >       Value |= (op & UINT64_C(31)) << 16;
> > > >       // op: Ra
> > > >       op = getMachineOpValue(MI, MI.getOperand(0), Fixups,
> > > >       STI);
> > > >       Value |= (op & UINT64_C(31)) << 10;
> > > >       Value = fixMulHigh(MI, Value, STI);
> > > >       break;
> > > >     }
> > > > 
> > > > This may be correct (I have no idea), but even if it is, it
> > > > seems
> > > > like an odd way to get this behavior: depending on the fact
> > > > that,
> > > > after operands are matched by name, the remaining operands are
> > > > matched by position such that they might overlap with those
> > > > operands matched by name.
> > > > 
> > > > In any case, I believe that the only in-tree target that still
> > > > really needs the positional operand support is PowerPC (because
> > > > the named-operand matching scheme still can't deal with the
> > > > complex operands that PPC uses for handling memory operands),
> > > > and
> > > > PowerPC needs the behavior that named and positional operands
> > > > are
> > > > disjoint so that we can start transitioning toward using named
> > > > mapping, so I've added a new TableGen target bit to disable
> > > > this
> > > > problematic overlapping operand behavior
> > > > (noNamedPositionallyEncodedOperands) in r203767.
> > > > 
> > > > This means that in lib/Target/PowerPC/PPC.td, we have:
> > > > 
> > > > def PPCInstrInfo : InstrInfo {
> > > > ...
> > > > 
> > > >   let noNamedPositionallyEncodedOperands = 1;
> > > > 
> > > > ...
> > > > }
> > > > 
> > > > I'd like those maintaining the current backends (especially
> > > > AArch64, Mips, AMDGPU, which I know to be problematic in this
> > > > regard) to try setting this and: a) fix those definitions that
> > > > are
> > > > problematic or b) explain to me that the current behavior is
> > > > useful.
> > > >
> > > 
> > > Hi Hal,
> > > 
> > > Thanks for working on this, I have run into several problems with
> > > the
> > > positional encodings and I would be happy to see it go away.
> > >  However,
> > > I was under the impression that positional encoding was the only
> > > way
> > > to
> > > encode custom operand types that map to multiple machine
> > > operands.
> > > See for example the MEMxi Operand sub-class in
> > > R600/R600Instructions.td.
> > 
> > Yes, this is the remaining use case for the positional scheme. We
> > need to invent something to replace it (maybe this should be
> > something as simple as mapping '.' -> '_'). Thoughts?
> > 
> 
> Do you mean something like this:
> 
> def MEMxi : Operand<iPTR> {
>   let MIOperandInfo = (ops REG:$ptr, i32imm:$index);
> }
> 
> def Instr {
> let InOperandList = (ins MEMxi:$src);
> 
> field bits<32> Inst;
> field bits<8> src_ptr;   //$src.$ptr
> field bits<8> src_index; //$src.$index
> 
> let Inst{7-0} = src_ptr;
> let Inst{15-8} = src_index;
> }
> 
> This seems like a good idea to me.

Yes, this is what I had in mind. I'll try implementing it next week.

 -Hal

> 
> -Tom
> 
> 
> 
> >  -Hal
> > 
> > > 
> > > Thanks,
> > > Tom
> > > 
> > > > Thanks again,
> > > > Hal
> > > > 
> > > > --
> > > > Hal Finkel
> > > > Assistant Computational Scientist
> > > > Leadership Computing Facility
> > > > Argonne National Laboratory
> > > > _______________________________________________
> > > > LLVM Developers mailing list
> > > > LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> > > > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> > > 
> > 
> > --
> > Hal Finkel
> > Assistant Computational Scientist
> > Leadership Computing Facility
> > Argonne National Laboratory
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-dev mailing list