diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86InstrInfo.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.cpp | 175 |
1 files changed, 125 insertions, 50 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index c29029daeec9..245346d82731 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -1761,10 +1761,11 @@ MachineInstr *X86InstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI, case X86::VCMPPSZ128rrik: case X86::VCMPPDZ256rrik: case X86::VCMPPSZ256rrik: { - unsigned Imm = MI.getOperand(MI.getNumOperands() - 1).getImm() & 0x1f; + unsigned Imm = + MI.getOperand(MI.getNumExplicitOperands() - 1).getImm() & 0x1f; Imm = X86::getSwappedVCMPImm(Imm); auto &WorkingMI = cloneIfNew(MI); - WorkingMI.getOperand(MI.getNumOperands() - 1).setImm(Imm); + WorkingMI.getOperand(MI.getNumExplicitOperands() - 1).setImm(Imm); return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, OpIdx1, OpIdx2); } @@ -2304,7 +2305,7 @@ unsigned X86::getCMovOpcode(unsigned RegBytes, bool HasMemoryOperand) { default: llvm_unreachable("Illegal register size!"); case 2: return HasMemoryOperand ? X86::CMOV16rm : X86::CMOV16rr; case 4: return HasMemoryOperand ? X86::CMOV32rm : X86::CMOV32rr; - case 8: return HasMemoryOperand ? X86::CMOV32rm : X86::CMOV64rr; + case 8: return HasMemoryOperand ? X86::CMOV64rm : X86::CMOV64rr; } } @@ -2963,8 +2964,8 @@ static unsigned CopyToFromAsymmetricReg(unsigned DestReg, unsigned SrcReg, void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const DebugLoc &DL, unsigned DestReg, - unsigned SrcReg, bool KillSrc) const { + const DebugLoc &DL, MCRegister DestReg, + MCRegister SrcReg, bool KillSrc) const { // First deal with the normal symmetric copies. bool HasAVX = Subtarget.hasAVX(); bool HasVLX = Subtarget.hasVLX(); @@ -3046,15 +3047,11 @@ void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB, report_fatal_error("Cannot emit physreg copy instruction"); } -bool X86InstrInfo::isCopyInstrImpl(const MachineInstr &MI, - const MachineOperand *&Src, - const MachineOperand *&Dest) const { - if (MI.isMoveReg()) { - Dest = &MI.getOperand(0); - Src = &MI.getOperand(1); - return true; - } - return false; +Optional<DestSourcePair> +X86InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { + if (MI.isMoveReg()) + return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; + return None; } static unsigned getLoadStoreRegOpcode(unsigned Reg, @@ -3221,8 +3218,9 @@ bool X86InstrInfo::getMemOperandWithOffset( Offset = DispMO.getImm(); - assert(BaseOp->isReg() && "getMemOperandWithOffset only supports base " - "operands of type register."); + if (!BaseOp->isReg()) + return false; + return true; } @@ -3963,9 +3961,7 @@ static bool ExpandMOVImmSExti8(MachineInstrBuilder &MIB, MachineFunction &MF = *MBB.getParent(); const X86FrameLowering *TFL = Subtarget.getFrameLowering(); bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); - bool NeedsDwarfCFI = - !IsWin64Prologue && - (MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry()); + bool NeedsDwarfCFI = !IsWin64Prologue && MF.needsFrameMoves(); bool EmitCFI = !TFL->hasFP(MF) && NeedsDwarfCFI; if (EmitCFI) { TFL->BuildCFI(MBB, I, DL, @@ -4708,6 +4704,10 @@ static MachineInstr *FuseInst(MachineFunction &MF, unsigned Opcode, updateOperandRegConstraints(MF, *NewMI, TII); + // Copy the NoFPExcept flag from the instruction we're fusing. + if (MI.getFlag(MachineInstr::MIFlag::NoFPExcept)) + NewMI->setFlag(MachineInstr::MIFlag::NoFPExcept); + MachineBasicBlock *MBB = InsertPt->getParent(); MBB->insert(InsertPt, NewMI); @@ -7233,8 +7233,8 @@ bool X86InstrInfo::hasHighOperandLatency(const TargetSchedModel &SchedModel, bool X86InstrInfo::hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const { - assert((Inst.getNumOperands() == 3 || Inst.getNumOperands() == 4) && - "Reassociation needs binary operators"); + assert(Inst.getNumExplicitOperands() == 3 && Inst.getNumExplicitDefs() == 1 && + Inst.getNumDefs() <= 2 && "Reassociation needs binary operators"); // Integer binary math/logic instructions have a third source operand: // the EFLAGS register. That operand must be both defined here and never @@ -7242,13 +7242,11 @@ bool X86InstrInfo::hasReassociableOperands(const MachineInstr &Inst, // not change anything because rearranging the operands could affect other // instructions that depend on the exact status flags (zero, sign, etc.) // that are set by using these particular operands with this operation. - if (Inst.getNumOperands() == 4) { - assert(Inst.getOperand(3).isReg() && - Inst.getOperand(3).getReg() == X86::EFLAGS && - "Unexpected operand in reassociable instruction"); - if (!Inst.getOperand(3).isDead()) - return false; - } + const MachineOperand *FlagDef = Inst.findRegisterDefOperand(X86::EFLAGS); + assert((Inst.getNumDefs() == 1 || FlagDef) && + "Implicit def isn't flags?"); + if (FlagDef && !FlagDef->isDead()) + return false; return TargetInstrInfo::hasReassociableOperands(Inst, MBB); } @@ -7558,15 +7556,57 @@ bool X86InstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst) const { } } +/// If \p DescribedReg overlaps with the MOVrr instruction's destination +/// register then, if possible, describe the value in terms of the source +/// register. +static Optional<ParamLoadedValue> +describeMOVrrLoadedValue(const MachineInstr &MI, Register DescribedReg, + const TargetRegisterInfo *TRI) { + Register DestReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); + + auto Expr = DIExpression::get(MI.getMF()->getFunction().getContext(), {}); + + // If the described register is the destination, just return the source. + if (DestReg == DescribedReg) + return ParamLoadedValue(MachineOperand::CreateReg(SrcReg, false), Expr); + + // If the described register is a sub-register of the destination register, + // then pick out the source register's corresponding sub-register. + if (unsigned SubRegIdx = TRI->getSubRegIndex(DestReg, DescribedReg)) { + unsigned SrcSubReg = TRI->getSubReg(SrcReg, SubRegIdx); + return ParamLoadedValue(MachineOperand::CreateReg(SrcSubReg, false), Expr); + } + + // The remaining case to consider is when the described register is a + // super-register of the destination register. MOV8rr and MOV16rr does not + // write to any of the other bytes in the register, meaning that we'd have to + // describe the value using a combination of the source register and the + // non-overlapping bits in the described register, which is not currently + // possible. + if (MI.getOpcode() == X86::MOV8rr || MI.getOpcode() == X86::MOV16rr || + !TRI->isSuperRegister(DestReg, DescribedReg)) + return None; + + assert(MI.getOpcode() == X86::MOV32rr && "Unexpected super-register case"); + return ParamLoadedValue(MachineOperand::CreateReg(SrcReg, false), Expr); +} + Optional<ParamLoadedValue> -X86InstrInfo::describeLoadedValue(const MachineInstr &MI) const { +X86InstrInfo::describeLoadedValue(const MachineInstr &MI, Register Reg) const { const MachineOperand *Op = nullptr; DIExpression *Expr = nullptr; + const TargetRegisterInfo *TRI = &getRegisterInfo(); + switch (MI.getOpcode()) { case X86::LEA32r: case X86::LEA64r: case X86::LEA64_32r: { + // We may need to describe a 64-bit parameter with a 32-bit LEA. + if (!TRI->isSuperRegisterEq(MI.getOperand(0).getReg(), Reg)) + return None; + // Operand 4 could be global address. For now we do not support // such situation. if (!MI.getOperand(4).isImm() || !MI.getOperand(2).isImm()) @@ -7574,7 +7614,6 @@ X86InstrInfo::describeLoadedValue(const MachineInstr &MI) const { const MachineOperand &Op1 = MI.getOperand(1); const MachineOperand &Op2 = MI.getOperand(3); - const TargetRegisterInfo *TRI = &getRegisterInfo(); assert(Op2.isReg() && (Op2.getReg() == X86::NoRegister || Register::isPhysicalRegister(Op2.getReg()))); @@ -7638,13 +7677,56 @@ X86InstrInfo::describeLoadedValue(const MachineInstr &MI) const { return ParamLoadedValue(*Op, Expr);; } + case X86::MOV32ri: + case X86::MOV64ri: + case X86::MOV64ri32: + // MOV32ri may be used for producing zero-extended 32-bit immediates in + // 64-bit parameters, so we need to consider super-registers. + if (!TRI->isSuperRegisterEq(MI.getOperand(0).getReg(), Reg)) + return None; + return ParamLoadedValue(MI.getOperand(1), Expr); + case X86::MOV8rr: + case X86::MOV16rr: + case X86::MOV32rr: + case X86::MOV64rr: + return describeMOVrrLoadedValue(MI, Reg, TRI); case X86::XOR32rr: { + // 64-bit parameters are zero-materialized using XOR32rr, so also consider + // super-registers. + if (!TRI->isSuperRegisterEq(MI.getOperand(0).getReg(), Reg)) + return None; if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) return ParamLoadedValue(MachineOperand::CreateImm(0), Expr); return None; } + case X86::MOVSX64rr32: { + // We may need to describe the lower 32 bits of the MOVSX; for example, in + // cases like this: + // + // $ebx = [...] + // $rdi = MOVSX64rr32 $ebx + // $esi = MOV32rr $edi + if (!TRI->isSubRegisterEq(MI.getOperand(0).getReg(), Reg)) + return None; + + Expr = DIExpression::get(MI.getMF()->getFunction().getContext(), {}); + + // If the described register is the destination register we need to + // sign-extend the source register from 32 bits. The other case we handle + // is when the described register is the 32-bit sub-register of the + // destination register, in case we just need to return the source + // register. + if (Reg == MI.getOperand(0).getReg()) + Expr = DIExpression::appendExt(Expr, 32, 64, true); + else + assert(X86MCRegisterClasses[X86::GR32RegClassID].contains(Reg) && + "Unhandled sub-register case for MOVSX64rr32"); + + return ParamLoadedValue(MI.getOperand(1), Expr); + } default: - return TargetInstrInfo::describeLoadedValue(MI); + assert(!MI.isMoveImmediate() && "Unexpected MoveImm instruction"); + return TargetInstrInfo::describeLoadedValue(MI, Reg); } } @@ -7654,38 +7736,31 @@ void X86InstrInfo::setSpecialOperandAttr(MachineInstr &OldMI1, MachineInstr &OldMI2, MachineInstr &NewMI1, MachineInstr &NewMI2) const { - // Integer instructions define an implicit EFLAGS source register operand as - // the third source (fourth total) operand. - if (OldMI1.getNumOperands() != 4 || OldMI2.getNumOperands() != 4) - return; + // Integer instructions may define an implicit EFLAGS dest register operand. + MachineOperand *OldFlagDef1 = OldMI1.findRegisterDefOperand(X86::EFLAGS); + MachineOperand *OldFlagDef2 = OldMI2.findRegisterDefOperand(X86::EFLAGS); - assert(NewMI1.getNumOperands() == 4 && NewMI2.getNumOperands() == 4 && + assert(!OldFlagDef1 == !OldFlagDef2 && "Unexpected instruction type for reassociation"); - MachineOperand &OldOp1 = OldMI1.getOperand(3); - MachineOperand &OldOp2 = OldMI2.getOperand(3); - MachineOperand &NewOp1 = NewMI1.getOperand(3); - MachineOperand &NewOp2 = NewMI2.getOperand(3); + if (!OldFlagDef1 || !OldFlagDef2) + return; - assert(OldOp1.isReg() && OldOp1.getReg() == X86::EFLAGS && OldOp1.isDead() && - "Must have dead EFLAGS operand in reassociable instruction"); - assert(OldOp2.isReg() && OldOp2.getReg() == X86::EFLAGS && OldOp2.isDead() && + assert(OldFlagDef1->isDead() && OldFlagDef2->isDead() && "Must have dead EFLAGS operand in reassociable instruction"); - (void)OldOp1; - (void)OldOp2; + MachineOperand *NewFlagDef1 = NewMI1.findRegisterDefOperand(X86::EFLAGS); + MachineOperand *NewFlagDef2 = NewMI2.findRegisterDefOperand(X86::EFLAGS); - assert(NewOp1.isReg() && NewOp1.getReg() == X86::EFLAGS && - "Unexpected operand in reassociable instruction"); - assert(NewOp2.isReg() && NewOp2.getReg() == X86::EFLAGS && + assert(NewFlagDef1 && NewFlagDef2 && "Unexpected operand in reassociable instruction"); // Mark the new EFLAGS operands as dead to be helpful to subsequent iterations // of this pass or other passes. The EFLAGS operands must be dead in these new // instructions because the EFLAGS operands in the original instructions must // be dead in order for reassociation to occur. - NewOp1.setIsDead(); - NewOp2.setIsDead(); + NewFlagDef1->setIsDead(); + NewFlagDef2->setIsDead(); } std::pair<unsigned, unsigned> |