[PATCH] D91704: [llvm-mca] Fix processing thumb instruction set

Dave Green via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 23 02:19:43 PST 2020


dmgreen added inline comments.


================
Comment at: llvm/lib/MCA/InstrBuilder.cpp:251
+bool InstrBuilder::isThumb1Inst(const MCInstrDesc &MCDesc) const {
+  static const unsigned ThumbFrm = 25 << 7; // ARMII::ThumbFrm
+  return STI.getTargetTriple().isThumb() &&
----------------
Please don't rely on ThumbFrm, a lot of those flags are legacy and should be removed.

I was hoping that this wouldn't have to say "if (thumb)" anywhere, even if the instructions are a little odd. Can it check the position of the optional def instead? So it detects instructions like this, without having to be target dependent.


================
Comment at: llvm/lib/MCA/InstrBuilder.cpp:305-306
 
-  unsigned NumVariadicOps = MCI.getNumOperands() - MCDesc.getNumOperands();
+  bool IsThumb = STI.getTargetTriple().isThumb();
+  // Thumb target specifies CPSR (s_cc_out) as an output operand
+  if (IsThumb && MCDesc.hasOptionalDef())
----------------
evgeny777 wrote:
> andreadb wrote:
> > Does it mean that the `OptionalDef` operand for Thumb instructions is always at index `NumExplicitDefs-1` (rather than at index `MCDesc.getNumOperands() - 1`)?
> > Is the OptionalDef already counted as an explicit operand? That's really odd...
> > 
> > This change breaks the assumptions made by the loop at line 348. The assumption is that implicit definitions always follow explicit definitions. By decreasing `NumExplicitDefs` you are also affecting how that loop iterates over the implicit definitions.
> > 
> > About the code comment: it should mention the issue with the optional def being already counted as an explicit definition.
> > Does it mean that the OptionalDef operand for Thumb instructions is always at index NumExplicitDefs-1
> Yes, for Thumb1 only. Thumb2 instructions follow ARM rules
> Just look at any Thumb1 instruction definition, which modifies CPSR:
> ```
> def tADC {  // InstructionEncoding
> //...
>   dag OutOperandList = (outs tGPR:$Rdn, s_cc_out:$s);
> //...
> }
> ```
> Unfortunately moving `s_cc_out` from the end of output operand list to the beginning of input operand list breaks too many things
> > Is the OptionalDef already counted as an explicit operand? That's really odd.
> Yes, because it's in the output operand list
> > This change breaks the assumptions made by the loop at line 348. The assumption is that implicit definitions always follow explicit definitions.
> Thumb1 instructions with optional def do not have implicit operands, however I'll fix this in upcoming update
> 
> 
Yes. Optional Defs are a little unfortunate, but have been around for a long time and I wouldn't recommend the major changes needed to alter how they work.


================
Comment at: llvm/lib/MCA/InstrBuilder.cpp:310-311
+
+  unsigned NumVariadicOps =
+      MCDesc.isVariadic() ? MCI.getNumOperands() - MCDesc.getNumOperands() : 0;
   ID.Writes.resize(TotalDefs + NumVariadicOps);
----------------
evgeny777 wrote:
> andreadb wrote:
> > > Some Thumb instructions (like tMOVSr) have less number of operands in their MCInstrDesc than MCInst.getNumOperands()
> > 
> > Could you elaborate this a bit more? It is a bit concerning that there is a mismatch in the number of operands. What are exactly these extra operands?
> > 
> > I need to understand if the assumptions made by this algorithm are still valid. Specifically, I need to understand if all of the assumptions described in the comment starting at line 256 are still valid. Can we still guarantee that "Uses always start at index #(MCDesc.getNumDefs())"? Is the order of writes still preserved?
> > Could you elaborate this a bit more? It is a bit concerning that there is a mismatch in the number of operands. What are exactly these extra operands?
> 
> If you look at tMOVSr you'll find out that it has 4 operands. For instance `movs r2, r3` is assembled to:
> ```
>  <MCInst #4275 tMOVSr <MCOperand Reg:74> <MCOperand Reg:75> <MCOperand Imm:14> <MCOperand Reg:0>>
> ```
> The last two args are, I beleive, built-in ARMCC::AL predicate
> 
> However tMOVSr definition lists only 2 arguments:
> ```
> def tMOVSr {  // InstructionEncoding
> // ...
>   dag OutOperandList = (outs tGPR:$Rd);
>   dag InOperandList = (ins tGPR:$Rm);
> // ...
> }
> ```
> InstrBuilder incorrectly treats tMOVSr as variadic, because 4 != 2
> 
This one sounds like a bug to me. Maybe in the AsmParsing? MOVS can't be used in IT blocks, so probably shouldn't use predicated. If you look at PR36658.mir, it looks like ` $r1 = tMOVSr $r0, implicit-def dead $cpsr`


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91704/new/

https://reviews.llvm.org/D91704



More information about the llvm-commits mailing list