[llvm-dev] Instruction is selected, but it shouldn't (?)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] Instruction is selected, but it shouldn't (?)

Alex L via llvm-dev
In MyTargetRegisterInfo.td file, I defined separated register classes for general purpose registers and for the SP register:

def GR16 : RegisterClass<"CPU74", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>;
def SSP : RegisterClass<"CPU74", [i16], 16, (add SP)>;

The SP can not be used in general purpose arithmetic instructions, therefore I defined the following classes in MyTargetInstrInfo.td:

class T5rr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<4> opcode>: Type5
                <opcode,
                (outs GR16:$rd), (ins GR16:$rn, GR16:$rs),
                AsmStr< opcStr, altOpcStr, "\t$rn, $rs, $rd">.n,
                [(set GR16:$rd, (opNode GR16:$rn, GR16:$rs)), (implicit SR)]>;

I also have specific instructions that can only use the SP, so I defined this as well

class T11sr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<3> opcode, bits<2> mode>: Type11
                <opcode, mode,
                (outs GR16:$rd), (ins SSP:$sp, GR16:$rd0),
                AsmStr< opcStr, altOpcStr, "\t$sp, $rd0, $rd">.n,
                [(set GR16:$rd, (opNode SSP:$sp, GR16:$rd0)), (implicit SR)]>
                {let Constraints = "$rd = $rd0";}


According to my understanding, instructions belonging to the T5rr16alu class above, should never be selected with the SP as register. However, instructions of that class get selected anyway with the SP, instead of the class T11sr16alu.

However, if I place class T11sr16alu, before class T5rr16alu, then the right instruction is selected

Why is that?. 
What I am missing?

Joan


_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Instruction is selected, but it shouldn't (?)

Alex L via llvm-dev

SelectionDAG isel is only driven by types and operations; it doesn’t care about specific registers.  So you have to pick one version of “add” you want isel to use by default (in this case, probably the general-register version), and only specify a pattern for that one.

 

For computing the addresses of stack slots in particular, you might want to look at how the ARM backend generates Thumb1 code.  Thumb1 has special instructions for SP-relative accesses (tADDframe, tADDrSP, tADDrSPi, tLDRspi, tSTRspi). Explicit copies from “sp” don’t really come up during isel, except for call arguments; most of the interesting code is part of frame lowering.

 

-Eli

 

From: llvm-dev <[hidden email]> On Behalf Of Joan Lluch via llvm-dev
Sent: Tuesday, May 28, 2019 11:31 AM
To: via llvm-dev <[hidden email]>
Subject: [EXT] [llvm-dev] Instruction is selected, but it shouldn't (?)

 

In MyTargetRegisterInfo.td file, I defined separated register classes for general purpose registers and for the SP register:

 

def GR16 : RegisterClass<"CPU74", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>;

def SSP : RegisterClass<"CPU74", [i16], 16, (add SP)>;

 

The SP can not be used in general purpose arithmetic instructions, therefore I defined the following classes in MyTargetInstrInfo.td:

 

class T5rr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<4> opcode>: Type5

                <opcode,

                (outs GR16:$rd), (ins GR16:$rn, GR16:$rs),

                AsmStr< opcStr, altOpcStr, "\t$rn, $rs, $rd">.n,

                [(set GR16:$rd, (opNode GR16:$rn, GR16:$rs)), (implicit SR)]>;

 

I also have specific instructions that can only use the SP, so I defined this as well

 

class T11sr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<3> opcode, bits<2> mode>: Type11

                <opcode, mode,

                (outs GR16:$rd), (ins SSP:$sp, GR16:$rd0),

                AsmStr< opcStr, altOpcStr, "\t$sp, $rd0, $rd">.n,

                [(set GR16:$rd, (opNode SSP:$sp, GR16:$rd0)), (implicit SR)]>

                {let Constraints = "$rd = $rd0";}

 

 

According to my understanding, instructions belonging to the T5rr16alu class above, should never be selected with the SP as register. However, instructions of that class get selected anyway with the SP, instead of the class T11sr16alu.

 

However, if I place class T11sr16alu, before class T5rr16alu, then the right instruction is selected

 

Why is that?. 

What I am missing?

 

Joan

 


_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Instruction is selected, but it shouldn't (?)

Alex L via llvm-dev
Hi Eli,

Thanks for your response. Actually, I look a lot at the ARM and THUMB1 backend implementations, and this certainly help. My architecture also have specific instructions for SP-relative accesses in a similar way than the Thumb1.

During frame lowering, specific machine instructions are emitted so there’s no issue there. Also during ISelDagToDag I am able to select the right instructions. The issue appears when trying to use the SP in iSelLowering, in particular, I attempt to create a LowerDYNAMIC_STACKALLOC function similar to the Thumb1. However, since my SP register is not part of the set of General Purpose registers, and the SP only has special instructions for it, I can NOT use the Thumb1 code implementation below:

SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
Chain = SP.getValue(1);
SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);

I must use this instead:

SDValue SP = DAG.getRegister(CPU74::SP, VT);
SP = DAG.getNode(ISD::SUB, dl, MVT::i16, SP, Size);

The ‘getCopyFromReg’ code in the first excerpt produces suboptimal code because LLVM can not figure out a way to place the SP directly in the SUB instruction without using an intermediate register. 

However, the code on the second excerpt produces optimal code, except that the wrong instruction is selected…

So, what do you suggest for me to do?. Maybe creating a Target Specific ISD instruction for that SUB that gets correctly selected during iSelDagToDag?

Thanks.

Joan Lluch

On 28 May 2019, at 20:55, Eli Friedman <[hidden email]> wrote:

SelectionDAG isel is only driven by types and operations; it doesn’t care about specific registers.  So you have to pick one version of “add” you want isel to use by default (in this case, probably the general-register version), and only specify a pattern for that one.
 
For computing the addresses of stack slots in particular, you might want to look at how the ARM backend generates Thumb1 code.  Thumb1 has special instructions for SP-relative accesses (tADDframe, tADDrSP, tADDrSPi, tLDRspi, tSTRspi). Explicit copies from “sp” don’t really come up during isel, except for call arguments; most of the interesting code is part of frame lowering.
 
-Eli 
 
From: llvm-dev <[hidden email]> On Behalf Of Joan Lluch via llvm-dev
Sent: Tuesday, May 28, 2019 11:31 AM
To: via llvm-dev <[hidden email]>
Subject: [EXT] [llvm-dev] Instruction is selected, but it shouldn't (?)
 
In MyTargetRegisterInfo.td file, I defined separated register classes for general purpose registers and for the SP register:
 
def GR16 : RegisterClass<"CPU74", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>;
def SSP : RegisterClass<"CPU74", [i16], 16, (add SP)>;
 
The SP can not be used in general purpose arithmetic instructions, therefore I defined the following classes in MyTargetInstrInfo.td:
 
class T5rr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<4> opcode>: Type5
                <opcode,
                (outs GR16:$rd), (ins GR16:$rn, GR16:$rs),
                AsmStr< opcStr, altOpcStr, "\t$rn, $rs, $rd">.n,
                [(set GR16:$rd, (opNode GR16:$rn, GR16:$rs)), (implicit SR)]>;
 
I also have specific instructions that can only use the SP, so I defined this as well
 
class T11sr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<3> opcode, bits<2> mode>: Type11
                <opcode, mode,
                (outs GR16:$rd), (ins SSP:$sp, GR16:$rd0),
                AsmStr< opcStr, altOpcStr, "\t$sp, $rd0, $rd">.n,
                [(set GR16:$rd, (opNode SSP:$sp, GR16:$rd0)), (implicit SR)]>
                {let Constraints = "$rd = $rd0";}
 
 
According to my understanding, instructions belonging to the T5rr16alu class above, should never be selected with the SP as register. However, instructions of that class get selected anyway with the SP, instead of the class T11sr16alu.
 
However, if I place class T11sr16alu, before class T5rr16alu, then the right instruction is selected
 
Why is that?. 
What I am missing?
 
Joan


_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Instruction is selected, but it shouldn't (?)

Alex L via llvm-dev

You could create a target-specific instruction, or you could pattern-match the copy+sub or copy+sub+copy combination in your Select() implementation in ISelDAGToDAG.  Or you could just ignore the potential optimization, like we do on Thumb1; dynamic stack allocation is generally rare.

-Eli

 

From: Joan Lluch <[hidden email]>
Sent: Tuesday, May 28, 2019 12:36 PM
To: Eli Friedman <[hidden email]>
Cc: llvm-dev <[hidden email]>
Subject: [EXT] Re: [llvm-dev] Instruction is selected, but it shouldn't (?)

 

Hi Eli,

 

Thanks for your response. Actually, I look a lot at the ARM and THUMB1 backend implementations, and this certainly help. My architecture also have specific instructions for SP-relative accesses in a similar way than the Thumb1.

 

During frame lowering, specific machine instructions are emitted so there’s no issue there. Also during ISelDagToDag I am able to select the right instructions. The issue appears when trying to use the SP in iSelLowering, in particular, I attempt to create a LowerDYNAMIC_STACKALLOC function similar to the Thumb1. However, since my SP register is not part of the set of General Purpose registers, and the SP only has special instructions for it, I can NOT use the Thumb1 code implementation below:

 

SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);

Chain = SP.getValue(1);

SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);

 

I must use this instead:

 

SDValue SP = DAG.getRegister(CPU74::SP, VT);

SP = DAG.getNode(ISD::SUB, dl, MVT::i16, SP, Size);

 

The ‘getCopyFromReg’ code in the first excerpt produces suboptimal code because LLVM can not figure out a way to place the SP directly in the SUB instruction without using an intermediate register. 

 

However, the code on the second excerpt produces optimal code, except that the wrong instruction is selected…

 

So, what do you suggest for me to do?. Maybe creating a Target Specific ISD instruction for that SUB that gets correctly selected during iSelDagToDag?

 

Thanks.

 

Joan Lluch

 

On 28 May 2019, at 20:55, Eli Friedman <[hidden email]> wrote:

 

SelectionDAG isel is only driven by types and operations; it doesn’t care about specific registers.  So you have to pick one version of “add” you want isel to use by default (in this case, probably the general-register version), and only specify a pattern for that one.

 

For computing the addresses of stack slots in particular, you might want to look at how the ARM backend generates Thumb1 code.  Thumb1 has special instructions for SP-relative accesses (tADDframe, tADDrSP, tADDrSPi, tLDRspi, tSTRspi). Explicit copies from “sp” don’t really come up during isel, except for call arguments; most of the interesting code is part of frame lowering.

 

-Eli 

 

From: llvm-dev <[hidden email]> On Behalf Of Joan Lluch via llvm-dev
Sent: Tuesday, May 28, 2019 11:31 AM
To: via llvm-dev <[hidden email]>
Subject: [EXT] [llvm-dev] Instruction is selected, but it shouldn't (?)

 

In MyTargetRegisterInfo.td file, I defined separated register classes for general purpose registers and for the SP register:

 

def GR16 : RegisterClass<"CPU74", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>;

def SSP : RegisterClass<"CPU74", [i16], 16, (add SP)>;

 

The SP can not be used in general purpose arithmetic instructions, therefore I defined the following classes in MyTargetInstrInfo.td:

 

class T5rr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<4> opcode>: Type5

                <opcode,

                (outs GR16:$rd), (ins GR16:$rn, GR16:$rs),

                AsmStr< opcStr, altOpcStr, "\t$rn, $rs, $rd">.n,

                [(set GR16:$rd, (opNode GR16:$rn, GR16:$rs)), (implicit SR)]>;

 

I also have specific instructions that can only use the SP, so I defined this as well

 

class T11sr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<3> opcode, bits<2> mode>: Type11

                <opcode, mode,

                (outs GR16:$rd), (ins SSP:$sp, GR16:$rd0),

                AsmStr< opcStr, altOpcStr, "\t$sp, $rd0, $rd">.n,

                [(set GR16:$rd, (opNode SSP:$sp, GR16:$rd0)), (implicit SR)]>

                {let Constraints = "$rd = $rd0";}

 

 

According to my understanding, instructions belonging to the T5rr16alu class above, should never be selected with the SP as register. However, instructions of that class get selected anyway with the SP, instead of the class T11sr16alu.

 

However, if I place class T11sr16alu, before class T5rr16alu, then the right instruction is selected

 

Why is that?. 

What I am missing?

 

Joan

 


_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Instruction is selected, but it shouldn't (?)

Alex L via llvm-dev
Hi Eli,

Ok, thank you very much. This is helpful.

Joan Lluch

Tel: 620 28 45 13

On 28 May 2019, at 22:31, Eli Friedman <[hidden email]> wrote:

You could create a target-specific instruction, or you could pattern-match the copy+sub or copy+sub+copy combination in your Select() implementation in ISelDAGToDAG.  Or you could just ignore the potential optimization, like we do on Thumb1; dynamic stack allocation is generally rare.
-Eli
 
From: Joan Lluch <[hidden email]> 
Sent: Tuesday, May 28, 2019 12:36 PM
To: Eli Friedman <[hidden email]>
Cc: llvm-dev <[hidden email]>
Subject: [EXT] Re: [llvm-dev] Instruction is selected, but it shouldn't (?)
 
Hi Eli,
 
Thanks for your response. Actually, I look a lot at the ARM and THUMB1 backend implementations, and this certainly help. My architecture also have specific instructions for SP-relative accesses in a similar way than the Thumb1.
 
During frame lowering, specific machine instructions are emitted so there’s no issue there. Also during ISelDagToDag I am able to select the right instructions. The issue appears when trying to use the SP in iSelLowering, in particular, I attempt to create a LowerDYNAMIC_STACKALLOC function similar to the Thumb1. However, since my SP register is not part of the set of General Purpose registers, and the SP only has special instructions for it, I can NOT use the Thumb1 code implementation below:
 
SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
Chain = SP.getValue(1);
SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);
 
I must use this instead:
 
SDValue SP = DAG.getRegister(CPU74::SP, VT);
SP = DAG.getNode(ISD::SUB, dl, MVT::i16, SP, Size);
 
The ‘getCopyFromReg’ code in the first excerpt produces suboptimal code because LLVM can not figure out a way to place the SP directly in the SUB instruction without using an intermediate register. 
 
However, the code on the second excerpt produces optimal code, except that the wrong instruction is selected…
 
So, what do you suggest for me to do?. Maybe creating a Target Specific ISD instruction for that SUB that gets correctly selected during iSelDagToDag?
 
Thanks.
 
Joan Lluch
 
On 28 May 2019, at 20:55, Eli Friedman <[hidden email]> wrote:
 
SelectionDAG isel is only driven by types and operations; it doesn’t care about specific registers.  So you have to pick one version of “add” you want isel to use by default (in this case, probably the general-register version), and only specify a pattern for that one.
 
For computing the addresses of stack slots in particular, you might want to look at how the ARM backend generates Thumb1 code.  Thumb1 has special instructions for SP-relative accesses (tADDframe, tADDrSP, tADDrSPi, tLDRspi, tSTRspi). Explicit copies from “sp” don’t really come up during isel, except for call arguments; most of the interesting code is part of frame lowering.
 
-Eli 
 
From: llvm-dev <[hidden email]> On Behalf Of Joan Lluch via llvm-dev
Sent: Tuesday, May 28, 2019 11:31 AM
To: via llvm-dev <[hidden email]>
Subject: [EXT] [llvm-dev] Instruction is selected, but it shouldn't (?)
 
In MyTargetRegisterInfo.td file, I defined separated register classes for general purpose registers and for the SP register:
 
def GR16 : RegisterClass<"CPU74", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>;
def SSP : RegisterClass<"CPU74", [i16], 16, (add SP)>;
 
The SP can not be used in general purpose arithmetic instructions, therefore I defined the following classes in MyTargetInstrInfo.td:
 
class T5rr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<4> opcode>: Type5
                <opcode,
                (outs GR16:$rd), (ins GR16:$rn, GR16:$rs),
                AsmStr< opcStr, altOpcStr, "\t$rn, $rs, $rd">.n,
                [(set GR16:$rd, (opNode GR16:$rn, GR16:$rs)), (implicit SR)]>;
 
I also have specific instructions that can only use the SP, so I defined this as well
 
class T11sr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<3> opcode, bits<2> mode>: Type11
                <opcode, mode,
                (outs GR16:$rd), (ins SSP:$sp, GR16:$rd0),
                AsmStr< opcStr, altOpcStr, "\t$sp, $rd0, $rd">.n,
                [(set GR16:$rd, (opNode SSP:$sp, GR16:$rd0)), (implicit SR)]>
                {let Constraints = "$rd = $rd0";}
 
 
According to my understanding, instructions belonging to the T5rr16alu class above, should never be selected with the SP as register. However, instructions of that class get selected anyway with the SP, instead of the class T11sr16alu.
 
However, if I place class T11sr16alu, before class T5rr16alu, then the right instruction is selected
 
Why is that?. 
What I am missing?
 
Joan


_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Instruction is selected, but it shouldn't (?)

Alex L via llvm-dev
Hi Eli,

Just as a matter of information, this is what I did:

In MyTargetInstrInfo.td I added:

class RegOperand : Operand<i16> {
  let OperandType = "OPERAND_REGISTER";
}

def GPReg : RegOperand, ComplexPattern< i16, 1, "SelectGRRegister"> {
  let MIOperandInfo = (ops GR16);
}

def SPReg : RegOperand, ComplexPattern< i16, 1, "SelectSPRegister"> {
  let MIOperandInfo = (ops SSP);
}

I also replaced all uses of registers in instruction input operands by the above Operand defs


In MyTargetISelDAGtoDAG.cpp I added:

static unsigned selSPRegister( SDValue Node )
{
  SDValue &EntryNode = Node;

  

  if ( EntryNode->getOpcode() == ISD::CopyFromReg  )
    EntryNode = EntryNode.getOperand(1);

  

  if ( RegisterSDNode *RN = dyn_cast<RegisterSDNode>(EntryNode))
    if ( CPU74::SSPRegClass.contains(RN->getReg()) )
      return RN->getReg();

  

  return 0 ;
}

bool CPU74DAGToDAGISel::SelectGRRegister(SDValue Node, SDValue &Base)
{
  if ( !selSPRegister( Node ) ) {
    Base = Node;
    return true ;
  }
  return false;
}

bool CPU74DAGToDAGISel::SelectSPRegister(SDValue Node, SDValue &Base)
{
  if ( unsigned Reg = selSPRegister( Node ) ) {
    Base = CurDAG->getRegister(Reg, Node.getValueType());
    return true;
  }
  return false;
}

This works like a charm

So thank you for your suggestions.

Joan Lluch
Puigsacalm, 7 
17458 - Fornells de la Selva
Girona

Tel: 620 28 45 13

On 28 May 2019, at 22:35, Joan Lluch <[hidden email]> wrote:

Hi Eli,

Ok, thank you very much. This is helpful.

Joan Lluch

Tel: 620 28 45 13

On 28 May 2019, at 22:31, Eli Friedman <[hidden email]> wrote:

You could create a target-specific instruction, or you could pattern-match the copy+sub or copy+sub+copy combination in your Select() implementation in ISelDAGToDAG.  Or you could just ignore the potential optimization, like we do on Thumb1; dynamic stack allocation is generally rare.
-Eli
 
From: Joan Lluch <[hidden email]> 
Sent: Tuesday, May 28, 2019 12:36 PM
To: Eli Friedman <[hidden email]>
Cc: llvm-dev <[hidden email]>
Subject: [EXT] Re: [llvm-dev] Instruction is selected, but it shouldn't (?)
 
Hi Eli,
 
Thanks for your response. Actually, I look a lot at the ARM and THUMB1 backend implementations, and this certainly help. My architecture also have specific instructions for SP-relative accesses in a similar way than the Thumb1.
 
During frame lowering, specific machine instructions are emitted so there’s no issue there. Also during ISelDagToDag I am able to select the right instructions. The issue appears when trying to use the SP in iSelLowering, in particular, I attempt to create a LowerDYNAMIC_STACKALLOC function similar to the Thumb1. However, since my SP register is not part of the set of General Purpose registers, and the SP only has special instructions for it, I can NOT use the Thumb1 code implementation below:
 
SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
Chain = SP.getValue(1);
SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);
 
I must use this instead:
 
SDValue SP = DAG.getRegister(CPU74::SP, VT);
SP = DAG.getNode(ISD::SUB, dl, MVT::i16, SP, Size);
 
The ‘getCopyFromReg’ code in the first excerpt produces suboptimal code because LLVM can not figure out a way to place the SP directly in the SUB instruction without using an intermediate register. 
 
However, the code on the second excerpt produces optimal code, except that the wrong instruction is selected…
 
So, what do you suggest for me to do?. Maybe creating a Target Specific ISD instruction for that SUB that gets correctly selected during iSelDagToDag?
 
Thanks.
 
Joan Lluch
 
On 28 May 2019, at 20:55, Eli Friedman <[hidden email]> wrote:
 
SelectionDAG isel is only driven by types and operations; it doesn’t care about specific registers.  So you have to pick one version of “add” you want isel to use by default (in this case, probably the general-register version), and only specify a pattern for that one.
 
For computing the addresses of stack slots in particular, you might want to look at how the ARM backend generates Thumb1 code.  Thumb1 has special instructions for SP-relative accesses (tADDframe, tADDrSP, tADDrSPi, tLDRspi, tSTRspi). Explicit copies from “sp” don’t really come up during isel, except for call arguments; most of the interesting code is part of frame lowering.
 
-Eli 
 
From: llvm-dev <[hidden email]> On Behalf Of Joan Lluch via llvm-dev
Sent: Tuesday, May 28, 2019 11:31 AM
To: via llvm-dev <[hidden email]>
Subject: [EXT] [llvm-dev] Instruction is selected, but it shouldn't (?)
 
In MyTargetRegisterInfo.td file, I defined separated register classes for general purpose registers and for the SP register:
 
def GR16 : RegisterClass<"CPU74", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>;
def SSP : RegisterClass<"CPU74", [i16], 16, (add SP)>;
 
The SP can not be used in general purpose arithmetic instructions, therefore I defined the following classes in MyTargetInstrInfo.td:
 
class T5rr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<4> opcode>: Type5
                <opcode,
                (outs GR16:$rd), (ins GR16:$rn, GR16:$rs),
                AsmStr< opcStr, altOpcStr, "\t$rn, $rs, $rd">.n,
                [(set GR16:$rd, (opNode GR16:$rn, GR16:$rs)), (implicit SR)]>;
 
I also have specific instructions that can only use the SP, so I defined this as well
 
class T11sr16alu<string opcStr, string altOpcStr, SDNode opNode, bits<3> opcode, bits<2> mode>: Type11
                <opcode, mode,
                (outs GR16:$rd), (ins SSP:$sp, GR16:$rd0),
                AsmStr< opcStr, altOpcStr, "\t$sp, $rd0, $rd">.n,
                [(set GR16:$rd, (opNode SSP:$sp, GR16:$rd0)), (implicit SR)]>
                {let Constraints = "$rd = $rd0";}
 
 
According to my understanding, instructions belonging to the T5rr16alu class above, should never be selected with the SP as register. However, instructions of that class get selected anyway with the SP, instead of the class T11sr16alu.
 
However, if I place class T11sr16alu, before class T5rr16alu, then the right instruction is selected
 
Why is that?. 
What I am missing?
 
Joan



_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev