mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
X86: Stop LEA64_32r doing unspeakable things to its arguments.
Previously LEA64_32r went through virtually the entire backend thinking it was using 32-bit registers until its blissful illusions were cruelly snatched away by MCInstLower and 64-bit equivalents were substituted at the last minute. This patch makes it behave normally, and take 64-bit registers as sources all the way through. Previous uses (for 32-bit arithmetic) are accommodated via SUBREG_TO_REG instructions which make the types and classes agree properly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183693 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6d315c6cf2
commit
e5609f3732
@ -204,6 +204,9 @@ namespace {
|
||||
bool SelectLEAAddr(SDValue N, SDValue &Base,
|
||||
SDValue &Scale, SDValue &Index, SDValue &Disp,
|
||||
SDValue &Segment);
|
||||
bool SelectLEA64_32Addr(SDValue N, SDValue &Base,
|
||||
SDValue &Scale, SDValue &Index, SDValue &Disp,
|
||||
SDValue &Segment);
|
||||
bool SelectTLSADDRAddr(SDValue N, SDValue &Base,
|
||||
SDValue &Scale, SDValue &Index, SDValue &Disp,
|
||||
SDValue &Segment);
|
||||
@ -1394,7 +1397,8 @@ bool X86DAGToDAGISel::SelectMOV64Imm32(SDValue N, SDValue &Imm) {
|
||||
// In static codegen with small code model, we can get the address of a label
|
||||
// into a register with 'movl'. TableGen has already made sure we're looking
|
||||
// at a label of some kind.
|
||||
assert(N->getOpcode() == X86ISD::Wrapper && "Unexpected node type for MOV32ri64");
|
||||
assert(N->getOpcode() == X86ISD::Wrapper &&
|
||||
"Unexpected node type for MOV32ri64");
|
||||
N = N.getOperand(0);
|
||||
|
||||
if (N->getOpcode() != ISD::TargetConstantPool &&
|
||||
@ -1408,6 +1412,43 @@ bool X86DAGToDAGISel::SelectMOV64Imm32(SDValue N, SDValue &Imm) {
|
||||
return TM.getCodeModel() == CodeModel::Small;
|
||||
}
|
||||
|
||||
bool X86DAGToDAGISel::SelectLEA64_32Addr(SDValue N, SDValue &Base,
|
||||
SDValue &Scale, SDValue &Index,
|
||||
SDValue &Disp, SDValue &Segment) {
|
||||
if (!SelectLEAAddr(N, Base, Scale, Index, Disp, Segment))
|
||||
return false;
|
||||
|
||||
SDLoc DL(N);
|
||||
RegisterSDNode *RN = dyn_cast<RegisterSDNode>(Base);
|
||||
if (RN && RN->getReg() == 0)
|
||||
Base = CurDAG->getRegister(0, MVT::i64);
|
||||
else if (Base.getValueType() == MVT::i32 && !dyn_cast<FrameIndexSDNode>(N)) {
|
||||
// Base could already be %rip, particularly in the x32 ABI.
|
||||
Base = SDValue(CurDAG->getMachineNode(
|
||||
TargetOpcode::SUBREG_TO_REG, DL, MVT::i64,
|
||||
CurDAG->getTargetConstant(0, MVT::i64),
|
||||
Base,
|
||||
CurDAG->getTargetConstant(X86::sub_32bit, MVT::i32)),
|
||||
0);
|
||||
}
|
||||
|
||||
RN = dyn_cast<RegisterSDNode>(Index);
|
||||
if (RN && RN->getReg() == 0)
|
||||
Index = CurDAG->getRegister(0, MVT::i64);
|
||||
else {
|
||||
assert(Index.getValueType() == MVT::i32 &&
|
||||
"Expect to be extending 32-bit registers for use in LEA");
|
||||
Index = SDValue(CurDAG->getMachineNode(
|
||||
TargetOpcode::SUBREG_TO_REG, DL, MVT::i64,
|
||||
CurDAG->getTargetConstant(0, MVT::i64),
|
||||
Index,
|
||||
CurDAG->getTargetConstant(X86::sub_32bit, MVT::i32)),
|
||||
0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing
|
||||
/// mode it matches can be cost effectively emitted as an LEA instruction.
|
||||
bool X86DAGToDAGISel::SelectLEAAddr(SDValue N,
|
||||
|
@ -1763,6 +1763,77 @@ inline static bool isTruncatedShiftCountForLEA(unsigned ShAmt) {
|
||||
return ShAmt < 4 && ShAmt > 0;
|
||||
}
|
||||
|
||||
bool X86InstrInfo::classifyLEAReg(MachineInstr *MI, const MachineOperand &Src,
|
||||
unsigned Opc, bool AllowSP,
|
||||
unsigned &NewSrc, bool &isKill, bool &isUndef,
|
||||
MachineOperand &ImplicitOp) const {
|
||||
MachineFunction &MF = *MI->getParent()->getParent();
|
||||
const TargetRegisterClass *RC;
|
||||
if (AllowSP) {
|
||||
RC = Opc != X86::LEA32r ? &X86::GR64RegClass : &X86::GR32RegClass;
|
||||
} else {
|
||||
RC = Opc != X86::LEA32r ?
|
||||
&X86::GR64_NOSPRegClass : &X86::GR32_NOSPRegClass;
|
||||
}
|
||||
unsigned SrcReg = Src.getReg();
|
||||
|
||||
// For both LEA64 and LEA32 the register already has essentially the right
|
||||
// type (32-bit or 64-bit) we may just need to forbid SP.
|
||||
if (Opc != X86::LEA64_32r) {
|
||||
NewSrc = SrcReg;
|
||||
isKill = Src.isKill();
|
||||
isUndef = Src.isUndef();
|
||||
|
||||
if (TargetRegisterInfo::isVirtualRegister(NewSrc) &&
|
||||
!MF.getRegInfo().constrainRegClass(NewSrc, RC))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is for an LEA64_32r and incoming registers are 32-bit. One way or
|
||||
// another we need to add 64-bit registers to the final MI.
|
||||
if (TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
|
||||
ImplicitOp = Src;
|
||||
ImplicitOp.setImplicit();
|
||||
|
||||
NewSrc = getX86SubSuperRegister(Src.getReg(), MVT::i64);
|
||||
MachineBasicBlock::LivenessQueryResult LQR =
|
||||
MI->getParent()->computeRegisterLiveness(&getRegisterInfo(), NewSrc, MI);
|
||||
|
||||
switch (LQR) {
|
||||
case MachineBasicBlock::LQR_Unknown:
|
||||
// We can't give sane liveness flags to the instruction, abandon LEA
|
||||
// formation.
|
||||
return false;
|
||||
case MachineBasicBlock::LQR_Live:
|
||||
isKill = MI->killsRegister(SrcReg);
|
||||
isUndef = false;
|
||||
break;
|
||||
default:
|
||||
// The physreg itself is dead, so we have to use it as an <undef>.
|
||||
isKill = false;
|
||||
isUndef = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Virtual register of the wrong class, we have to create a temporary 64-bit
|
||||
// vreg to feed into the LEA.
|
||||
NewSrc = MF.getRegInfo().createVirtualRegister(RC);
|
||||
BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
|
||||
get(TargetOpcode::COPY))
|
||||
.addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit)
|
||||
.addOperand(Src);
|
||||
|
||||
// Which is obviously going to be dead after we're done with it.
|
||||
isKill = true;
|
||||
isUndef = false;
|
||||
}
|
||||
|
||||
// We've set all the parameters without issue.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// convertToThreeAddressWithLEA - Helper for convertToThreeAddress when
|
||||
/// 16-bit LEA is disabled, use 32-bit LEA to form 3-address code by promoting
|
||||
/// to a 32-bit superregister and then truncating back down to a 16-bit
|
||||
@ -1778,11 +1849,16 @@ X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc,
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
|
||||
unsigned Opc = TM.getSubtarget<X86Subtarget>().is64Bit()
|
||||
? X86::LEA64_32r : X86::LEA32r;
|
||||
MachineRegisterInfo &RegInfo = MFI->getParent()->getRegInfo();
|
||||
unsigned leaInReg = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
|
||||
unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
|
||||
unsigned Opc, leaInReg;
|
||||
if (TM.getSubtarget<X86Subtarget>().is64Bit()) {
|
||||
Opc = X86::LEA64_32r;
|
||||
leaInReg = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
|
||||
} else {
|
||||
Opc = X86::LEA32r;
|
||||
leaInReg = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
|
||||
}
|
||||
|
||||
// Build and insert into an implicit UNDEF value. This is OK because
|
||||
// well be shifting and then extracting the lower 16-bits.
|
||||
@ -1832,7 +1908,10 @@ X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc,
|
||||
// just a single insert_subreg.
|
||||
addRegReg(MIB, leaInReg, true, leaInReg, false);
|
||||
} else {
|
||||
leaInReg2 = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
|
||||
if (TM.getSubtarget<X86Subtarget>().is64Bit())
|
||||
leaInReg2 = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
|
||||
else
|
||||
leaInReg2 = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
|
||||
// Build and insert into an implicit UNDEF value. This is OK because
|
||||
// well be shifting and then extracting the lower 16-bits.
|
||||
BuildMI(*MFI, &*MIB, MI->getDebugLoc(), get(X86::IMPLICIT_DEF),leaInReg2);
|
||||
@ -1952,16 +2031,25 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
unsigned ShAmt = getTruncatedShiftCount(MI, 2);
|
||||
if (!isTruncatedShiftCountForLEA(ShAmt)) return 0;
|
||||
|
||||
unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
|
||||
|
||||
// LEA can't handle ESP.
|
||||
if (TargetRegisterInfo::isVirtualRegister(Src.getReg()) &&
|
||||
!MF.getRegInfo().constrainRegClass(Src.getReg(),
|
||||
&X86::GR32_NOSPRegClass))
|
||||
bool isKill, isUndef;
|
||||
unsigned SrcReg;
|
||||
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
|
||||
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ false,
|
||||
SrcReg, isKill, isUndef, ImplicitOp))
|
||||
return 0;
|
||||
|
||||
unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest)
|
||||
.addReg(0).addImm(1 << ShAmt).addOperand(Src).addImm(0).addReg(0);
|
||||
.addReg(0).addImm(1 << ShAmt)
|
||||
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
|
||||
.addImm(0).addReg(0);
|
||||
if (ImplicitOp.getReg() != 0)
|
||||
MIB.addOperand(ImplicitOp);
|
||||
NewMI = MIB;
|
||||
|
||||
break;
|
||||
}
|
||||
case X86::SHL16ri: {
|
||||
@ -1986,17 +2074,20 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
assert(MI->getNumOperands() >= 2 && "Unknown inc instruction!");
|
||||
unsigned Opc = MIOpc == X86::INC64r ? X86::LEA64r
|
||||
: (is64Bit ? X86::LEA64_32r : X86::LEA32r);
|
||||
const TargetRegisterClass *RC = MIOpc == X86::INC64r ?
|
||||
(const TargetRegisterClass*)&X86::GR64_NOSPRegClass :
|
||||
(const TargetRegisterClass*)&X86::GR32_NOSPRegClass;
|
||||
|
||||
// LEA can't handle RSP.
|
||||
if (TargetRegisterInfo::isVirtualRegister(Src.getReg()) &&
|
||||
!MF.getRegInfo().constrainRegClass(Src.getReg(), RC))
|
||||
bool isKill, isUndef;
|
||||
unsigned SrcReg;
|
||||
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
|
||||
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ false,
|
||||
SrcReg, isKill, isUndef, ImplicitOp))
|
||||
return 0;
|
||||
|
||||
NewMI = addOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest).addOperand(Src), 1);
|
||||
MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest)
|
||||
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef));
|
||||
if (ImplicitOp.getReg() != 0)
|
||||
MIB.addOperand(ImplicitOp);
|
||||
|
||||
NewMI = addOffset(MIB, 1);
|
||||
break;
|
||||
}
|
||||
case X86::INC16r:
|
||||
@ -2013,16 +2104,22 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
assert(MI->getNumOperands() >= 2 && "Unknown dec instruction!");
|
||||
unsigned Opc = MIOpc == X86::DEC64r ? X86::LEA64r
|
||||
: (is64Bit ? X86::LEA64_32r : X86::LEA32r);
|
||||
const TargetRegisterClass *RC = MIOpc == X86::DEC64r ?
|
||||
(const TargetRegisterClass*)&X86::GR64_NOSPRegClass :
|
||||
(const TargetRegisterClass*)&X86::GR32_NOSPRegClass;
|
||||
// LEA can't handle RSP.
|
||||
if (TargetRegisterInfo::isVirtualRegister(Src.getReg()) &&
|
||||
!MF.getRegInfo().constrainRegClass(Src.getReg(), RC))
|
||||
|
||||
bool isKill, isUndef;
|
||||
unsigned SrcReg;
|
||||
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
|
||||
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ false,
|
||||
SrcReg, isKill, isUndef, ImplicitOp))
|
||||
return 0;
|
||||
|
||||
NewMI = addOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest).addOperand(Src), -1);
|
||||
MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest)
|
||||
.addReg(SrcReg, getUndefRegState(isUndef) | getKillRegState(isKill));
|
||||
if (ImplicitOp.getReg() != 0)
|
||||
MIB.addOperand(ImplicitOp);
|
||||
|
||||
NewMI = addOffset(MIB, -1);
|
||||
|
||||
break;
|
||||
}
|
||||
case X86::DEC16r:
|
||||
@ -2039,36 +2136,41 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
case X86::ADD32rr_DB: {
|
||||
assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
|
||||
unsigned Opc;
|
||||
const TargetRegisterClass *RC;
|
||||
if (MIOpc == X86::ADD64rr || MIOpc == X86::ADD64rr_DB) {
|
||||
if (MIOpc == X86::ADD64rr || MIOpc == X86::ADD64rr_DB)
|
||||
Opc = X86::LEA64r;
|
||||
RC = &X86::GR64_NOSPRegClass;
|
||||
} else {
|
||||
else
|
||||
Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
|
||||
RC = &X86::GR32_NOSPRegClass;
|
||||
}
|
||||
|
||||
|
||||
unsigned Src2 = MI->getOperand(2).getReg();
|
||||
bool isKill2 = MI->getOperand(2).isKill();
|
||||
|
||||
// LEA can't handle RSP.
|
||||
if (TargetRegisterInfo::isVirtualRegister(Src2) &&
|
||||
!MF.getRegInfo().constrainRegClass(Src2, RC))
|
||||
bool isKill, isUndef;
|
||||
unsigned SrcReg;
|
||||
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
|
||||
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ true,
|
||||
SrcReg, isKill, isUndef, ImplicitOp))
|
||||
return 0;
|
||||
|
||||
NewMI = addRegReg(BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest),
|
||||
Src.getReg(), Src.isKill(), Src2, isKill2);
|
||||
const MachineOperand &Src2 = MI->getOperand(2);
|
||||
bool isKill2, isUndef2;
|
||||
unsigned SrcReg2;
|
||||
MachineOperand ImplicitOp2 = MachineOperand::CreateReg(0, false);
|
||||
if (!classifyLEAReg(MI, Src2, Opc, /*AllowSP=*/ false,
|
||||
SrcReg2, isKill2, isUndef2, ImplicitOp2))
|
||||
return 0;
|
||||
|
||||
MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest);
|
||||
if (ImplicitOp.getReg() != 0)
|
||||
MIB.addOperand(ImplicitOp);
|
||||
if (ImplicitOp2.getReg() != 0)
|
||||
MIB.addOperand(ImplicitOp2);
|
||||
|
||||
NewMI = addRegReg(MIB, SrcReg, isKill, SrcReg2, isKill2);
|
||||
|
||||
// Preserve undefness of the operands.
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
bool isUndef2 = MI->getOperand(2).isUndef();
|
||||
NewMI->getOperand(1).setIsUndef(isUndef);
|
||||
NewMI->getOperand(3).setIsUndef(isUndef2);
|
||||
|
||||
if (LV && isKill2)
|
||||
LV->replaceKillInstruction(Src2, MI, NewMI);
|
||||
if (LV && Src2.isKill())
|
||||
LV->replaceKillInstruction(SrcReg2, MI, NewMI);
|
||||
break;
|
||||
}
|
||||
case X86::ADD16rr:
|
||||
@ -2107,9 +2209,21 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
case X86::ADD32ri8_DB: {
|
||||
assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
|
||||
unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
|
||||
NewMI = addOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest).addOperand(Src),
|
||||
MI->getOperand(2).getImm());
|
||||
|
||||
bool isKill, isUndef;
|
||||
unsigned SrcReg;
|
||||
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
|
||||
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ true,
|
||||
SrcReg, isKill, isUndef, ImplicitOp))
|
||||
return 0;
|
||||
|
||||
MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addOperand(Dest)
|
||||
.addReg(SrcReg, getUndefRegState(isUndef) | getKillRegState(isKill));
|
||||
if (ImplicitOp.getReg() != 0)
|
||||
MIB.addOperand(ImplicitOp);
|
||||
|
||||
NewMI = addOffset(MIB, MI->getOperand(2).getImm());
|
||||
break;
|
||||
}
|
||||
case X86::ADD16ri:
|
||||
|
@ -192,6 +192,19 @@ public:
|
||||
const MachineInstr *Orig,
|
||||
const TargetRegisterInfo &TRI) const;
|
||||
|
||||
/// Given an operand within a MachineInstr, insert preceding code to put it
|
||||
/// into the right format for a particular kind of LEA instruction. This may
|
||||
/// involve using an appropriate super-register instead (with an implicit use
|
||||
/// of the original) or creating a new virtual register and inserting COPY
|
||||
/// instructions to get the data into the right class.
|
||||
///
|
||||
/// Reference parameters are set to indicate how caller should add this
|
||||
/// operand to the LEA instruction.
|
||||
bool classifyLEAReg(MachineInstr *MI, const MachineOperand &Src,
|
||||
unsigned LEAOpcode, bool AllowSP,
|
||||
unsigned &NewSrc, bool &isKill,
|
||||
bool &isUndef, MachineOperand &ImplicitOp) const;
|
||||
|
||||
/// convertToThreeAddress - This method must be implemented by targets that
|
||||
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
|
||||
/// may be able to convert a two-address instruction into a true
|
||||
|
@ -523,8 +523,7 @@ def i64i8imm : Operand<i64> {
|
||||
|
||||
def lea64_32mem : Operand<i32> {
|
||||
let PrintMethod = "printi32mem";
|
||||
let AsmOperandLowerMethod = "lower_lea64_32mem";
|
||||
let MIOperandInfo = (ops GR32, i8imm, GR32_NOSP, i32imm, i8imm);
|
||||
let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
|
||||
let ParserMatchClass = X86MemAsmOperand;
|
||||
}
|
||||
|
||||
@ -546,7 +545,7 @@ def lea32addr : ComplexPattern<i32, 5, "SelectLEAAddr",
|
||||
[add, sub, mul, X86mul_imm, shl, or, frameindex],
|
||||
[]>;
|
||||
// In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
|
||||
def lea64_32addr : ComplexPattern<i32, 5, "SelectLEAAddr",
|
||||
def lea64_32addr : ComplexPattern<i32, 5, "SelectLEA64_32Addr",
|
||||
[add, sub, mul, X86mul_imm, shl, or,
|
||||
frameindex, X86WrapperRIP],
|
||||
[]>;
|
||||
|
@ -225,20 +225,6 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
|
||||
// Convert registers in the addr mode according to subreg64.
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
if (!MI->getOperand(OpNo+i).isReg()) continue;
|
||||
|
||||
unsigned Reg = MI->getOperand(OpNo+i).getReg();
|
||||
// LEAs can use RIP-relative addressing, and RIP has no sub/super register.
|
||||
if (Reg == 0 || Reg == X86::RIP) continue;
|
||||
|
||||
MI->getOperand(OpNo+i).setReg(getX86SubSuperRegister(Reg, MVT::i64));
|
||||
}
|
||||
}
|
||||
|
||||
/// LowerUnaryToTwoAddr - R = setb -> R = sbb R, R
|
||||
static void LowerUnaryToTwoAddr(MCInst &OutMI, unsigned NewOpc) {
|
||||
OutMI.setOpcode(NewOpc);
|
||||
@ -364,9 +350,7 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
|
||||
// Handle a few special cases to eliminate operand modifiers.
|
||||
ReSimplify:
|
||||
switch (OutMI.getOpcode()) {
|
||||
case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
|
||||
lower_lea64_32mem(&OutMI, 1);
|
||||
// FALL THROUGH.
|
||||
case X86::LEA64_32r:
|
||||
case X86::LEA64r:
|
||||
case X86::LEA16r:
|
||||
case X86::LEA32r:
|
||||
|
@ -30,10 +30,10 @@ land.lhs.true:
|
||||
%cmp4 = icmp eq i32 %call3, 10
|
||||
br i1 %cmp4, label %do.body.preheader, label %if.then
|
||||
|
||||
; %shl.i should be sinked all the way down to do.body.preheader, but not into the loop.
|
||||
; %add16.i should be sinked all the way down to do.body.preheader, but not into the loop.
|
||||
; CHECK: do.body.preheader
|
||||
; CHECK-NOT: do.body
|
||||
; CHECK: shll $12
|
||||
; CHECK: leal ([[SRC:%r[a-z0-9]+]],[[SRC]],8)
|
||||
|
||||
do.body.preheader:
|
||||
%xor29.i = xor i32 %shr27.i, %add25.i
|
||||
|
@ -6,7 +6,7 @@ define i32 @test1(i32 %x) nounwind {
|
||||
%tmp2 = add i32 %tmp1, 7
|
||||
ret i32 %tmp2
|
||||
; CHECK: test1:
|
||||
; CHECK: leal 7(,[[A0:%rdi|%rcx]],8), %eax
|
||||
; CHECK: leal 7(,%r[[A0:di|cx]],8), %eax
|
||||
}
|
||||
|
||||
|
||||
@ -28,8 +28,9 @@ bb.nph:
|
||||
bb2:
|
||||
ret i32 %x_offs
|
||||
; CHECK: test2:
|
||||
; CHECK: leal -5([[A0]]), %eax
|
||||
; CHECK: movl %e[[A0]], %eax
|
||||
; CHECK: addl $-5, %eax
|
||||
; CHECK: andl $-4, %eax
|
||||
; CHECK: negl %eax
|
||||
; CHECK: leal -4([[A0]],%rax), %eax
|
||||
; CHECK: leal -4(%r[[A0]],%rax), %eax
|
||||
}
|
||||
|
@ -52,13 +52,14 @@ entry:
|
||||
]
|
||||
|
||||
sw.bb: ; preds = %entry, %entry, %entry
|
||||
; CHECK: %sw.bb
|
||||
; CHECK: imull
|
||||
%mul = mul nsw i32 %test_case, 3
|
||||
%mul20 = mul nsw i32 %mul, %scale
|
||||
br i1 undef, label %if.end34, label %sw.bb307
|
||||
|
||||
if.end34: ; preds = %sw.bb
|
||||
; CHECK: %if.end34
|
||||
; CHECK: imull
|
||||
; CHECK: leal
|
||||
; CHECK-NOT: imull
|
||||
tail call void (...)* @printf(i32 %test_case, i32 %mul20) nounwind
|
||||
|
Loading…
Reference in New Issue
Block a user