summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86FastISel.cpp32
-rw-r--r--llvm/lib/Target/X86/X86ISelDAGToDAG.cpp13
-rw-r--r--llvm/lib/Target/X86/X86InstrCompiler.td6
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.cpp23
-rw-r--r--llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp10
5 files changed, 41 insertions, 43 deletions
diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp
index a49ad8bd59d..b87f4802473 100644
--- a/llvm/lib/Target/X86/X86FastISel.cpp
+++ b/llvm/lib/Target/X86/X86FastISel.cpp
@@ -1916,8 +1916,8 @@ bool X86FastISel::X86SelectDivRem(const Instruction *I) {
{ &X86::GR64RegClass, X86::RAX, X86::RDX, {
{ X86::IDIV64r, X86::CQO, Copy, X86::RAX, S }, // SDiv
{ X86::IDIV64r, X86::CQO, Copy, X86::RDX, S }, // SRem
- { X86::DIV64r, X86::MOV32r0, Copy, X86::RAX, U }, // UDiv
- { X86::DIV64r, X86::MOV32r0, Copy, X86::RDX, U }, // URem
+ { X86::DIV64r, X86::MOV64r0, Copy, X86::RAX, U }, // UDiv
+ { X86::DIV64r, X86::MOV64r0, Copy, X86::RDX, U }, // URem
}
}, // i64
};
@@ -1964,26 +1964,22 @@ bool X86FastISel::X86SelectDivRem(const Instruction *I) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(OpEntry.OpSignExtend));
else {
- unsigned Zero32 = createResultReg(&X86::GR32RegClass);
+ unsigned ZeroReg = createResultReg(VT == MVT::i64 ? &X86::GR64RegClass
+ : &X86::GR32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(X86::MOV32r0), Zero32);
+ TII.get(OpEntry.OpSignExtend), ZeroReg);
// Copy the zero into the appropriate sub/super/identical physical
// register. Unfortunately the operations needed are not uniform enough
// to fit neatly into the table above.
- if (VT == MVT::i16) {
+ if (VT == MVT::i16)
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Copy), TypeEntry.HighInReg)
- .addReg(Zero32, 0, X86::sub_16bit);
- } else if (VT == MVT::i32) {
+ .addReg(ZeroReg, 0, X86::sub_16bit);
+ else
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Copy), TypeEntry.HighInReg)
- .addReg(Zero32);
- } else if (VT == MVT::i64) {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(TargetOpcode::SUBREG_TO_REG), TypeEntry.HighInReg)
- .addImm(0).addReg(Zero32).addImm(X86::sub_32bit);
- }
+ .addReg(ZeroReg);
}
}
// Generate the DIV/IDIV instruction.
@@ -3708,6 +3704,9 @@ unsigned X86FastISel::X86MaterializeInt(const ConstantInt *CI, MVT VT) {
uint64_t Imm = CI->getZExtValue();
if (Imm == 0) {
+ if (VT.SimpleTy == MVT::i64)
+ return fastEmitInst_(X86::MOV64r0, &X86::GR64RegClass);
+
unsigned SrcReg = fastEmitInst_(X86::MOV32r0, &X86::GR32RegClass);
switch (VT.SimpleTy) {
default: llvm_unreachable("Unexpected value type");
@@ -3720,13 +3719,6 @@ unsigned X86FastISel::X86MaterializeInt(const ConstantInt *CI, MVT VT) {
X86::sub_16bit);
case MVT::i32:
return SrcReg;
- case MVT::i64: {
- unsigned ResultReg = createResultReg(&X86::GR64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
- .addImm(0).addReg(SrcReg).addImm(X86::sub_32bit);
- return ResultReg;
- }
}
}
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index 4b803c5a81b..83d5be34dc7 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -3569,7 +3569,10 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InFlag),0);
} else {
// Zero out the high part, effectively zero extending the input.
- SDValue ClrNode = SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, NVT), 0);
+ unsigned ClrOpc = NVT.SimpleTy == MVT::i64 ? X86::MOV64r0
+ : X86::MOV32r0;
+ MVT ClrVT = NVT.SimpleTy == MVT::i64 ? MVT::i64 : MVT::i32;
+ SDValue ClrNode = SDValue(CurDAG->getMachineNode(ClrOpc, dl, ClrVT), 0);
switch (NVT.SimpleTy) {
case MVT::i16:
ClrNode =
@@ -3580,15 +3583,7 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
0);
break;
case MVT::i32:
- break;
case MVT::i64:
- ClrNode =
- SDValue(CurDAG->getMachineNode(
- TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
- CurDAG->getTargetConstant(0, dl, MVT::i64), ClrNode,
- CurDAG->getTargetConstant(X86::sub_32bit, dl,
- MVT::i32)),
- 0);
break;
default:
llvm_unreachable("Unexpected division source");
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 051832bf4bc..11d6edd55d4 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -275,16 +275,18 @@ def MORESTACK_RET_RESTORE_R10 : I<0, Pseudo, (outs), (ins), "", []>;
// Alias instruction mapping movr0 to xor.
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1,
- isPseudo = 1, AddedComplexity = 10 in
+ isPseudo = 1, AddedComplexity = 10 in {
def MOV32r0 : I<0, Pseudo, (outs GR32:$dst), (ins), "",
[(set GR32:$dst, 0)]>, Sched<[WriteZero]>;
+def MOV64r0 : I<0, Pseudo, (outs GR64:$dst), (ins), "",
+ [(set GR64:$dst, 0)]>, Sched<[WriteZero]>;
+}
// Other widths can also make use of the 32-bit xor, which may have a smaller
// encoding and avoid partial register updates.
let AddedComplexity = 10 in {
def : Pat<(i8 0), (EXTRACT_SUBREG (MOV32r0), sub_8bit)>;
def : Pat<(i16 0), (EXTRACT_SUBREG (MOV32r0), sub_16bit)>;
-def : Pat<(i64 0), (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit)>;
}
let Predicates = [OptForSize, Not64BitMode],
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 1eddb27847d..e62c8403693 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -683,8 +683,10 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
if (ClobbersEFLAGS && !isSafeToClobberEFLAGS(MBB, I)) {
// The instruction clobbers EFLAGS. Re-materialize as MOV32ri to avoid side
// effects.
+ unsigned NewOpc = X86::MOV32ri;
int Value;
switch (Orig.getOpcode()) {
+ case X86::MOV64r0: NewOpc = X86::MOV32ri64; Value = 0; break;
case X86::MOV32r0: Value = 0; break;
case X86::MOV32r1: Value = 1; break;
case X86::MOV32r_1: Value = -1; break;
@@ -693,7 +695,7 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
}
const DebugLoc &DL = Orig.getDebugLoc();
- BuildMI(MBB, I, DL, get(X86::MOV32ri))
+ BuildMI(MBB, I, DL, get(NewOpc))
.add(Orig.getOperand(0))
.addImm(Value);
} else {
@@ -3750,7 +3752,9 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
// MOV32r0 etc. are implemented with xor which clobbers condition code.
// They are safe to move up, if the definition to EFLAGS is dead and
// earlier instructions do not read or write EFLAGS.
- if (!Movr0Inst && Instr.getOpcode() == X86::MOV32r0 &&
+ if (!Movr0Inst &&
+ (Instr.getOpcode() == X86::MOV32r0 ||
+ Instr.getOpcode() == X86::MOV64r0) &&
Instr.registerDefIsDead(X86::EFLAGS, TRI)) {
Movr0Inst = &Instr;
continue;
@@ -4155,6 +4159,15 @@ bool X86InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
switch (MI.getOpcode()) {
case X86::MOV32r0:
return Expand2AddrUndef(MIB, get(X86::XOR32rr));
+ case X86::MOV64r0: {
+ const TargetRegisterInfo *TRI = &getRegisterInfo();
+ unsigned Reg = MIB->getOperand(0).getReg();
+ unsigned Reg32 = TRI->getSubReg(Reg, X86::sub_32bit);
+ MIB->getOperand(0).setReg(Reg32);
+ Expand2AddrUndef(MIB, get(X86::XOR32rr));
+ MIB.addReg(Reg, RegState::ImplicitDefine);
+ return true;
+ }
case X86::MOV32r1:
return expandMOV32r1(MIB, *this, /*MinusOne=*/ false);
case X86::MOV32r_1:
@@ -4898,8 +4911,10 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
isTwoAddrFold = true;
} else {
if (OpNum == 0) {
- if (MI.getOpcode() == X86::MOV32r0) {
- NewMI = MakeM0Inst(*this, X86::MOV32mi, MOs, InsertPt, MI);
+ if (MI.getOpcode() == X86::MOV32r0 || MI.getOpcode() == X86::MOV64r0) {
+ unsigned NewOpc = MI.getOpcode() == X86::MOV64r0 ? X86::MOV64mi32
+ : X86::MOV32mi;
+ NewMI = MakeM0Inst(*this, NewOpc, MOs, InsertPt, MI);
if (NewMI)
return NewMI;
}
diff --git a/llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp b/llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
index 14e4c455a08..20997ecc07d 100644
--- a/llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
+++ b/llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
@@ -487,20 +487,14 @@ bool X86SpeculativeLoadHardeningPass::runOnMachineFunction(
// Otherwise, just build the predicate state itself by zeroing a register
// as we don't need any initial state.
PS->InitialReg = MRI->createVirtualRegister(PS->RC);
- unsigned PredStateSubReg = MRI->createVirtualRegister(&X86::GR32RegClass);
- auto ZeroI = BuildMI(Entry, EntryInsertPt, Loc, TII->get(X86::MOV32r0),
- PredStateSubReg);
+ auto ZeroI = BuildMI(Entry, EntryInsertPt, Loc, TII->get(X86::MOV64r0),
+ PS->InitialReg);
++NumInstsInserted;
MachineOperand *ZeroEFLAGSDefOp =
ZeroI->findRegisterDefOperand(X86::EFLAGS);
assert(ZeroEFLAGSDefOp && ZeroEFLAGSDefOp->isImplicit() &&
"Must have an implicit def of EFLAGS!");
ZeroEFLAGSDefOp->setIsDead(true);
- BuildMI(Entry, EntryInsertPt, Loc, TII->get(X86::SUBREG_TO_REG),
- PS->InitialReg)
- .addImm(0)
- .addReg(PredStateSubReg)
- .addImm(X86::sub_32bit);
}
// We're going to need to trace predicate state throughout the function's
OpenPOWER on IntegriCloud