forked from OSchip/llvm-project
Revert 48125, 48126, and 48130 for now to unbreak some x86-64 tests.
llvm-svn: 48167
This commit is contained in:
parent
514b3ed536
commit
d4e1d9eeb2
|
@ -322,12 +322,9 @@ namespace ISD {
|
|||
// This node takes a superreg and a constant sub-register index as operands.
|
||||
EXTRACT_SUBREG,
|
||||
|
||||
// INSERT_SUBREG - This node is used to insert a sub-register value into
|
||||
// either explicitly into a superreg, or implicitly into a superreg value.
|
||||
// INSERT_SUBREG - This node is used to insert a sub-register value.
|
||||
// This node takes a superreg, a subreg value, and a constant sub-register
|
||||
// index as operands. The superreg may be either a superregister operand or a
|
||||
// target constant indicating that the insert is being done into a target
|
||||
// specific implicit value.
|
||||
// index as operands.
|
||||
INSERT_SUBREG,
|
||||
|
||||
// MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
|
||||
|
|
|
@ -105,21 +105,32 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
|
|||
MachineFunction &MF = *MBB->getParent();
|
||||
const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo();
|
||||
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
||||
assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
|
||||
((MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) ||
|
||||
MI->getOperand(1).isImmediate()) &&
|
||||
(MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
|
||||
MI->getOperand(3).isImmediate() && "Invalid insert_subreg");
|
||||
|
||||
unsigned DstReg = MI->getOperand(0).getReg();
|
||||
unsigned DstReg = 0;
|
||||
unsigned SrcReg = 0;
|
||||
// Check if we're inserting into an implicit value.
|
||||
if (MI->getOperand(1).isImmediate())
|
||||
unsigned InsReg = 0;
|
||||
unsigned SubIdx = 0;
|
||||
|
||||
// If only have 3 operands, then the source superreg is undef
|
||||
// and we can supress the copy from the undef value
|
||||
if (MI->getNumOperands() == 3) {
|
||||
assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
|
||||
(MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
|
||||
MI->getOperand(2).isImmediate() && "Invalid extract_subreg");
|
||||
DstReg = MI->getOperand(0).getReg();
|
||||
SrcReg = DstReg;
|
||||
else
|
||||
InsReg = MI->getOperand(1).getReg();
|
||||
SubIdx = MI->getOperand(2).getImm();
|
||||
} else if (MI->getNumOperands() == 4) {
|
||||
assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
|
||||
(MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
|
||||
(MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
|
||||
MI->getOperand(3).isImmediate() && "Invalid extract_subreg");
|
||||
DstReg = MI->getOperand(0).getReg();
|
||||
SrcReg = MI->getOperand(1).getReg();
|
||||
unsigned InsReg = MI->getOperand(2).getReg();
|
||||
unsigned SubIdx = MI->getOperand(3).getImm();
|
||||
InsReg = MI->getOperand(2).getReg();
|
||||
SubIdx = MI->getOperand(3).getImm();
|
||||
} else
|
||||
assert(0 && "Malformed extract_subreg");
|
||||
|
||||
assert(SubIdx != 0 && "Invalid index for extract_subreg");
|
||||
unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx);
|
||||
|
|
|
@ -693,13 +693,19 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node,
|
|||
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
||||
|
||||
} else if (Opc == TargetInstrInfo::INSERT_SUBREG) {
|
||||
assert((Node->getNumOperands() == 3) &&
|
||||
assert((Node->getNumOperands() == 2 || Node->getNumOperands() == 3) &&
|
||||
"Malformed insert_subreg node");
|
||||
SDOperand N0 = Node->getOperand(0);
|
||||
SDOperand N1 = Node->getOperand(1);
|
||||
SDOperand N2 = Node->getOperand(2);
|
||||
unsigned SubReg = getVR(N1, VRBaseMap);
|
||||
unsigned SubIdx = cast<ConstantSDNode>(N2)->getValue();
|
||||
bool isUndefInput = (Node->getNumOperands() == 2);
|
||||
unsigned SubReg = 0;
|
||||
unsigned SubIdx = 0;
|
||||
|
||||
if (isUndefInput) {
|
||||
SubReg = getVR(Node->getOperand(0), VRBaseMap);
|
||||
SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getValue();
|
||||
} else {
|
||||
SubReg = getVR(Node->getOperand(1), VRBaseMap);
|
||||
SubIdx = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
|
||||
}
|
||||
|
||||
// TODO: Add tracking info to MachineRegisterInfo of which vregs are subregs
|
||||
// to allow coalescing in the allocator
|
||||
|
@ -737,15 +743,9 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node,
|
|||
}
|
||||
|
||||
MI->addOperand(MachineOperand::CreateReg(VRBase, true));
|
||||
|
||||
// If N0 is a constant then it indicates the insert is being done
|
||||
// into a target specific constant value, not a register.
|
||||
if (const ConstantSDNode *SD = dyn_cast<ConstantSDNode>(N0))
|
||||
MI->addOperand(MachineOperand::CreateImm(SD->getValue()));
|
||||
else
|
||||
AddOperand(MI, N0, 0, 0, VRBaseMap);
|
||||
// Add the subregster being inserted
|
||||
AddOperand(MI, N1, 0, 0, VRBaseMap);
|
||||
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
|
||||
if (!isUndefInput)
|
||||
AddOperand(MI, Node->getOperand(1), 0, 0, VRBaseMap);
|
||||
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
||||
} else
|
||||
assert(0 && "Node is not a subreg insert or extract");
|
||||
|
|
|
@ -263,10 +263,6 @@ def variable_ops;
|
|||
/// flags. But currently we have but one flag.
|
||||
def ptr_rc;
|
||||
|
||||
/// unknown definition - Mark this operand as being of unknown type, causing
|
||||
/// it to be resolved by inference in the context it is used.
|
||||
def unknown;
|
||||
|
||||
/// Operand Types - These provide the built-in operand types that may be used
|
||||
/// by a target. Targets can optionally provide their own operand types as
|
||||
/// needed, though this should not be needed for RISC targets.
|
||||
|
@ -355,15 +351,15 @@ def DECLARE : Instruction {
|
|||
let hasCtrlDep = 1;
|
||||
}
|
||||
def EXTRACT_SUBREG : Instruction {
|
||||
let OutOperandList = (ops unknown:$dst);
|
||||
let InOperandList = (ops unknown:$supersrc, i32imm:$subidx);
|
||||
let OutOperandList = (ops variable_ops);
|
||||
let InOperandList = (ops variable_ops);
|
||||
let AsmString = "";
|
||||
let Namespace = "TargetInstrInfo";
|
||||
let neverHasSideEffects = 1;
|
||||
}
|
||||
def INSERT_SUBREG : Instruction {
|
||||
let OutOperandList = (ops unknown:$dst);
|
||||
let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
|
||||
let OutOperandList = (ops variable_ops);
|
||||
let InOperandList = (ops variable_ops);
|
||||
let AsmString = "";
|
||||
let Namespace = "TargetInstrInfo";
|
||||
let neverHasSideEffects = 1;
|
||||
|
|
|
@ -1491,27 +1491,22 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
|
|||
AddToISelQueue(N0);
|
||||
if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
|
||||
SDOperand SRIdx;
|
||||
SDOperand ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_UNDEF,
|
||||
MVT::i32);
|
||||
switch(N0.getValueType()) {
|
||||
case MVT::i32:
|
||||
SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
|
||||
// x86-64 zero extends 32-bit inserts int 64-bit registers
|
||||
if (Subtarget->is64Bit())
|
||||
ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_ZERO, MVT::i32);
|
||||
SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
|
||||
break;
|
||||
case MVT::i16:
|
||||
SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);
|
||||
SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
|
||||
break;
|
||||
case MVT::i8:
|
||||
if (Subtarget->is64Bit())
|
||||
SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32);
|
||||
SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
|
||||
break;
|
||||
default: assert(0 && "Unknown any_extend!");
|
||||
}
|
||||
if (SRIdx.Val) {
|
||||
SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
|
||||
NVT, ImplVal, N0, SRIdx);
|
||||
NVT, N0, SRIdx);
|
||||
|
||||
#ifndef NDEBUG
|
||||
DOUT << std::string(Indent-2, ' ') << "=> ";
|
||||
|
|
|
@ -1098,11 +1098,12 @@ def PsMOVZX64rm32: I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
|
|||
"mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
|
||||
[(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
|
||||
|
||||
// r & (2^32-1)
|
||||
def : Pat<(and GR64:$src, i64immFFFFFFFF),
|
||||
(INSERT_SUBREG x86_impl_val_zero,
|
||||
(MOV32rr (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)),
|
||||
x86_subreg_32bit)>;
|
||||
/// PsAND64rrFFFFFFFF - r = r & (2^32-1)
|
||||
def PsAND64rrFFFFFFFF
|
||||
: I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
|
||||
"mov{l}\t{${src:subreg32}, ${dst:subreg32}|${dst:subreg32}, ${src:subreg32}}",
|
||||
[(set GR64:$dst, (and GR64:$src, i64immFFFFFFFF))]>;
|
||||
|
||||
|
||||
// Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
|
||||
// equivalent due to implicit zero-extending, and it sometimes has a smaller
|
||||
|
|
|
@ -903,20 +903,16 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
|||
? X86::LEA64_32r : X86::LEA32r;
|
||||
unsigned leaInReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
|
||||
unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
|
||||
|
||||
// Build and insert into an implicit UNDEF value. This is OK because
|
||||
// well be shifting and then extracting the lower 16-bits.
|
||||
MachineInstr *Ins =
|
||||
BuildMI(get(X86::INSERT_SUBREG),leaInReg).addImm(X86::IMPL_VAL_UNDEF)
|
||||
.addReg(Src).addImm(X86::SUBREG_16BIT);
|
||||
|
||||
MachineInstr *Ins =
|
||||
BuildMI(get(X86::INSERT_SUBREG), leaInReg).addReg(Src).addImm(2);
|
||||
Ins->copyKillDeadInfo(MI);
|
||||
|
||||
NewMI = BuildMI(get(Opc), leaOutReg)
|
||||
.addReg(0).addImm(1 << ShAmt).addReg(leaInReg).addImm(0);
|
||||
|
||||
MachineInstr *Ext =
|
||||
BuildMI(get(X86::EXTRACT_SUBREG), Dest)
|
||||
.addReg(leaOutReg).addImm(X86::SUBREG_16BIT);
|
||||
BuildMI(get(X86::EXTRACT_SUBREG), Dest).addReg(leaOutReg).addImm(2);
|
||||
Ext->copyKillDeadInfo(MI);
|
||||
|
||||
MFI->insert(MBBI, Ins); // Insert the insert_subreg
|
||||
|
|
|
@ -46,14 +46,6 @@ namespace X86 {
|
|||
COND_INVALID
|
||||
};
|
||||
|
||||
// X86 specific implict values used for subregister inserts.
|
||||
// This can be used to model the fact that x86-64 by default
|
||||
// inserts 32-bit values into 64-bit registers implicitly containing zeros.
|
||||
enum ImplicitVal {
|
||||
IMPL_VAL_UNDEF = 0,
|
||||
IMPL_VAL_ZERO = 1
|
||||
};
|
||||
|
||||
// Turn condition code into conditional branch opcode.
|
||||
unsigned GetCondBranchFromCond(CondCode CC);
|
||||
|
||||
|
|
|
@ -161,10 +161,6 @@ def i32i8imm : Operand<i32>;
|
|||
// Branch targets have OtherVT type.
|
||||
def brtarget : Operand<OtherVT>;
|
||||
|
||||
// These should match the enum X86::ImplicitVal
|
||||
def x86_impl_val_undef : PatLeaf<(i32 0)>;
|
||||
def x86_impl_val_zero : PatLeaf<(i32 1)>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// X86 Complex Pattern Definitions.
|
||||
//
|
||||
|
|
|
@ -32,15 +32,6 @@ namespace N86 {
|
|||
};
|
||||
}
|
||||
|
||||
namespace X86 {
|
||||
/// SubregIndex - The index of various sized subregister classes. Note that
|
||||
/// these indices must be kept in sync with the class indices in the
|
||||
/// X86RegisterInfo.td file.
|
||||
enum SubregIndex {
|
||||
SUBREG_8BIT = 1, SUBREG_16BIT = 2, SUBREG_32BIT = 3
|
||||
};
|
||||
}
|
||||
|
||||
/// DWARFFlavour - Flavour of dwarf regnumbers
|
||||
///
|
||||
namespace DWARFFlavour {
|
||||
|
|
|
@ -176,10 +176,6 @@ let Namespace = "X86" in {
|
|||
// sub registers for each register.
|
||||
//
|
||||
|
||||
def x86_subreg_8bit : PatLeaf<(i32 1)>;
|
||||
def x86_subreg_16bit : PatLeaf<(i32 2)>;
|
||||
def x86_subreg_32bit : PatLeaf<(i32 3)>;
|
||||
|
||||
def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI,
|
||||
R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
|
||||
[AL, CL, DL, BL, SPL, BPL, SIL, DIL,
|
||||
|
|
|
@ -872,10 +872,6 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
|||
std::vector<unsigned char> VT;
|
||||
VT.push_back(MVT::iPTR);
|
||||
MadeChange = UpdateNodeType(VT, TP);
|
||||
} else if (ResultNode->getName() == "unknown") {
|
||||
std::vector<unsigned char> VT;
|
||||
VT.push_back(MVT::isUnknown);
|
||||
MadeChange = UpdateNodeType(VT, TP);
|
||||
} else {
|
||||
assert(ResultNode->isSubClassOf("RegisterClass") &&
|
||||
"Operands should be register classes!");
|
||||
|
@ -914,15 +910,13 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
|||
MadeChange |= Child->UpdateNodeType(VT, TP);
|
||||
} else if (OperandNode->getName() == "ptr_rc") {
|
||||
MadeChange |= Child->UpdateNodeType(MVT::iPTR, TP);
|
||||
} else if (OperandNode->getName() == "unknown") {
|
||||
MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
|
||||
} else {
|
||||
assert(0 && "Unknown operand type!");
|
||||
abort();
|
||||
}
|
||||
MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);
|
||||
}
|
||||
|
||||
|
||||
if (ChildNo != getNumChildren())
|
||||
TP.error("Instruction '" + getOperator()->getName() +
|
||||
"' was provided too many operands!");
|
||||
|
|
|
@ -163,7 +163,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
|
|||
isVariadic = true;
|
||||
continue;
|
||||
} else if (!Rec->isSubClassOf("RegisterClass") &&
|
||||
Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
|
||||
Rec->getName() != "ptr_rc")
|
||||
throw "Unknown operand class '" + Rec->getName() +
|
||||
"' in instruction '" + R->getName() + "' instruction!";
|
||||
|
||||
|
|
Loading…
Reference in New Issue