From 96601ca332ab388754ca4673be8973396fea2ddd Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 22 Aug 2012 06:07:19 +0000 Subject: Add a getName function to MachineFunction. Use it in places that previously did getFunction()->getName(). Remove includes of Function.h that are no longer needed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162347 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCodeEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index e81b4cc..68406db 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -389,7 +389,7 @@ bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) { do { DEBUG(errs() << "JITTing function '" - << MF.getFunction()->getName() << "'\n"); + << MF.getName() << "'\n"); MCE.startFunction(MF); for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E; ++MBB) { -- cgit v1.1 From 05d96f98cbd96dab7f4ea1ea4ebe4285597e7e88 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Wed, 22 Aug 2012 15:37:57 +0000 Subject: Reduce duplicated hash map lookups. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162362 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMConstantIslandPass.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index a953985..dd05f0c 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1388,10 +1388,9 @@ bool ARMConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) { // If the original WaterList entry was "new water" on this iteration, // propagate that to the new island. This is just keeping NewWaterList // updated to match the WaterList, which will be updated below. - if (NewWaterList.count(WaterBB)) { - NewWaterList.erase(WaterBB); + if (NewWaterList.erase(WaterBB)) NewWaterList.insert(NewIsland); - } + // The new CPE goes before the following block (NewMBB). NewMBB = llvm::next(MachineFunction::iterator(WaterBB)); -- cgit v1.1 From aaf217953bef3b2cc0e0f26bf474616cc20cf7f0 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 24 Aug 2012 00:35:46 +0000 Subject: Fix undefined behavior (negation of INT_MIN) in ARM backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162520 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 2 +- lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 992aba5..6d60a76 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -275,7 +275,7 @@ def imm16_31 : ImmLeaf, PatLeaf<(imm), [{ - int64_t Value = -(int)N->getZExtValue(); + unsigned Value = -(unsigned)N->getZExtValue(); return Value && ARM_AM::getSOImmVal(Value) != -1; }], imm_neg_XFORM> { let ParserMatchClass = so_imm_neg_asmoperand; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 94f1082..1917564 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -783,7 +783,7 @@ getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, // Immediate is always encoded as positive. The 'U' bit controls add vs sub. if (Imm8 < 0) - Imm8 = -Imm8; + Imm8 = -(uint32_t)Imm8; // Scaled by 4. Imm8 /= 4; -- cgit v1.1 From ea47628cbafb48bf2a51554328a6dd77be40f4df Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 24 Aug 2012 14:43:27 +0000 Subject: Add missing SDNPSideEffect flags. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162557 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6d60a76..825dd9c 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -90,9 +90,10 @@ def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>; def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, - [SDNPHasChain, SDNPOutGlue]>; + [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd, - [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; + [SDNPHasChain, SDNPSideEffect, + SDNPOptInGlue, SDNPOutGlue]>; def ARMcopystructbyval : SDNode<"ARMISD::COPY_STRUCT_BYVAL" , SDT_ARMStructByVal, [SDNPHasChain, SDNPInGlue, SDNPOutGlue, @@ -148,14 +149,16 @@ def ARMsube : SDNode<"ARMISD::SUBE", SDTBinaryArithWithFlagsInOut>; def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", - SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>; + SDT_ARMEH_SJLJ_Setjmp, + [SDNPHasChain, SDNPSideEffect]>; def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP", - SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>; + SDT_ARMEH_SJLJ_Longjmp, + [SDNPHasChain, SDNPSideEffect]>; def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER, - [SDNPHasChain]>; + [SDNPHasChain, SDNPSideEffect]>; def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER, - [SDNPHasChain]>; + [SDNPHasChain, SDNPSideEffect]>; def ARMPreload : SDNode<"ARMISD::PRELOAD", SDT_ARMPREFETCH, [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>; -- cgit v1.1 From 0745b649ed5c362f1c2f7db59254a76041ddef05 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 24 Aug 2012 20:52:46 +0000 Subject: Fix call instruction operands in ARMFastISel. The ARM BL and BLX instructions don't have predicate operands, but the thumb variants tBL and tBLX do. The argument registers should be added as implicit uses. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162593 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 50 ++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 34 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 5a5ca1b..436b6ac 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -2212,25 +2212,17 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { unsigned CallOpc = ARMSelectCallOp(EnableARMLongCalls); MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc)); - if (isThumb2) { - // Explicitly adding the predicate here. + // BL / BLX don't take a predicate, but tBL / tBLX do. + if (isThumb2) AddDefaultPred(MIB); - if (EnableARMLongCalls) - MIB.addReg(CalleeReg); - else - MIB.addExternalSymbol(TLI.getLibcallName(Call)); - } else { - if (EnableARMLongCalls) - MIB.addReg(CalleeReg); - else - MIB.addExternalSymbol(TLI.getLibcallName(Call)); + if (EnableARMLongCalls) + MIB.addReg(CalleeReg); + else + MIB.addExternalSymbol(TLI.getLibcallName(Call)); - // Explicitly adding the predicate here. - AddDefaultPred(MIB); - } // Add implicit physical register uses to the call. for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) - MIB.addReg(RegArgs[i]); + MIB.addReg(RegArgs[i], RegState::Implicit); // Add a register mask with the call-preserved registers. // Proper defs for return values will be added by setPhysRegsDeadExcept(). @@ -2358,30 +2350,20 @@ bool ARMFastISel::SelectCall(const Instruction *I, unsigned CallOpc = ARMSelectCallOp(UseReg); MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc)); - if(isThumb2) { - // Explicitly adding the predicate here. - AddDefaultPred(MIB); - if (UseReg) - MIB.addReg(CalleeReg); - else if (!IntrMemName) - MIB.addGlobalAddress(GV, 0, 0); - else - MIB.addExternalSymbol(IntrMemName, 0); - } else { - if (UseReg) - MIB.addReg(CalleeReg); - else if (!IntrMemName) - MIB.addGlobalAddress(GV, 0, 0); - else - MIB.addExternalSymbol(IntrMemName, 0); - // Explicitly adding the predicate here. + // ARM calls don't take a predicate, but tBL / tBLX do. + if(isThumb2) AddDefaultPred(MIB); - } + if (UseReg) + MIB.addReg(CalleeReg); + else if (!IntrMemName) + MIB.addGlobalAddress(GV, 0, 0); + else + MIB.addExternalSymbol(IntrMemName, 0); // Add implicit physical register uses to the call. for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) - MIB.addReg(RegArgs[i]); + MIB.addReg(RegArgs[i], RegState::Implicit); // Add a register mask with the call-preserved registers. // Proper defs for return values will be added by setPhysRegsDeadExcept(). -- cgit v1.1 From 7778ee1ed9f9e8a3aa4911ff4adcf15e46588e03 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 24 Aug 2012 21:44:11 +0000 Subject: Explicitly mark LEApcrel pseudos with hasSideEffects. It's not clear that they should be marked as such, but tbb formation fails if t2LEApcrelJT is hoisted of of a loop. This doesn't change the flags on these instructions, UnmodeledSideEffects was already inferred from the missing pattern. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162603 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 3 +++ lib/Target/ARM/ARMInstrThumb2.td | 1 + 2 files changed, 4 insertions(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 825dd9c..6d701ea 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1794,12 +1794,15 @@ def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label), let Inst{15-12} = Rd; let Inst{11-0} = label{11-0}; } + +let hasSideEffects = 1 in { def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p), 4, IIC_iALUi, []>; def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, nohash_imm:$id, pred:$p), 4, IIC_iALUi, []>; +} //===----------------------------------------------------------------------===// // Control Flow Instructions. diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 8ecf009..dbb8ffc 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1200,6 +1200,7 @@ def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd), let neverHasSideEffects = 1, isReMaterializable = 1 in def t2LEApcrel : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), 4, IIC_iALUi, []>; +let hasSideEffects = 1 in def t2LEApcrelJT : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, nohash_imm:$id, pred:$p), 4, IIC_iALUi, -- cgit v1.1 From 36ff8f25c559f291a8790584b725e0b54ddf2240 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 24 Aug 2012 22:46:55 +0000 Subject: Missed tLEApcrelJT. ARMConstantIslandPass expects this instruction to stay in the same basic block as the jump table branch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162615 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrThumb.td | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 554f6d9..e171f8b 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -1200,6 +1200,7 @@ let neverHasSideEffects = 1, isReMaterializable = 1 in def tLEApcrel : tPseudoInst<(outs tGPR:$Rd), (ins i32imm:$label, pred:$p), 2, IIC_iALUi, []>; +let hasSideEffects = 1 in def tLEApcrelJT : tPseudoInst<(outs tGPR:$Rd), (ins i32imm:$label, nohash_imm:$id, pred:$p), 2, IIC_iALUi, []>; -- cgit v1.1 From 1144af3c9b4da48cd581156e05b24261c8de366a Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 24 Aug 2012 23:29:28 +0000 Subject: Fix integer undefined behavior due to signed left shift overflow in LLVM. Reviewed offline by chandlerc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162623 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index c90751d..c394ed1 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -3170,7 +3170,7 @@ static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, int imm = Val & 0xFF; if (!(Val & 0x100)) imm *= -1; - Inst.addOperand(MCOperand::CreateImm(imm << 2)); + Inst.addOperand(MCOperand::CreateImm(imm * 4)); } return MCDisassembler::Success; -- cgit v1.1 From 47aa9a2bb521994509d21179b968471531986eed Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 27 Aug 2012 22:12:44 +0000 Subject: Make sure we add the predicate after all of the registers are added. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162703 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 29033e5..2112992 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -712,11 +712,12 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB, unsigned Dst = TRI->getSubReg(DestReg, BeginIdx + i*Spacing); unsigned Src = TRI->getSubReg(SrcReg, BeginIdx + i*Spacing); assert(Dst && Src && "Bad sub-register"); - Mov = AddDefaultPred(BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst) - .addReg(Src)); + Mov = BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst) + .addReg(Src); // VORR takes two source operands. if (Opc == ARM::VORRq) Mov.addReg(Src); + Mov = AddDefaultPred(Mov); } // Add implicit super-register defs and kills to the last instruction. Mov->addRegisterDefined(DestReg, TRI); -- cgit v1.1 From dd364419ee64cd5bb234af006ce0cb285e4a84ca Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 27 Aug 2012 23:58:52 +0000 Subject: Add ATOMIC_LDR* pseudo-instructions to model atomic_load on ARM. It is not safe to use normal LDR instructions because they may be reordered by the scheduler. The ATOMIC_LDR pseudos have a mayStore flag that prevents reordering. Atomic loads are also prevented from participating in rematerialization and load folding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162713 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 20 +++++----- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 10 +++-- lib/Target/ARM/ARMInstrInfo.td | 41 +++++++++++++++++--- lib/Target/ARM/ARMInstrThumb.td | 47 ++++++++++++++++++++--- lib/Target/ARM/ARMInstrThumb2.td | 68 +++++++++++++++++++++++++++------- lib/Target/ARM/Thumb2SizeReduction.cpp | 26 ++++++++++--- 6 files changed, 169 insertions(+), 43 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 2112992..378331f 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2778,8 +2778,8 @@ static int adjustDefLatency(const ARMSubtarget &Subtarget, // variants are one cycle cheaper. switch (DefMCID->getOpcode()) { default: break; - case ARM::LDRrs: - case ARM::LDRBrs: { + case ARM::LDRrs: case ARM::ATOMIC_LDRrs: + case ARM::LDRBrs: case ARM::ATOMIC_LDRBrs: { unsigned ShOpVal = DefMI->getOperand(3).getImm(); unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal); if (ShImm == 0 || @@ -2787,9 +2787,9 @@ static int adjustDefLatency(const ARMSubtarget &Subtarget, --Adjust; break; } - case ARM::t2LDRs: - case ARM::t2LDRBs: - case ARM::t2LDRHs: + case ARM::t2LDRs: case ARM::ATOMIC_t2LDRs: + case ARM::t2LDRBs: case ARM::ATOMIC_t2LDRBs: + case ARM::t2LDRHs: case ARM::ATOMIC_t2LDRHs: case ARM::t2LDRSHs: { // Thumb2 mode: lsl only. unsigned ShAmt = DefMI->getOperand(3).getImm(); @@ -3046,8 +3046,8 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, // variants are one cycle cheaper. switch (DefMCID.getOpcode()) { default: break; - case ARM::LDRrs: - case ARM::LDRBrs: { + case ARM::LDRrs: case ARM::ATOMIC_LDRrs: + case ARM::LDRBrs: case ARM::ATOMIC_LDRBrs: { unsigned ShOpVal = cast(DefNode->getOperand(2))->getZExtValue(); unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal); @@ -3056,9 +3056,9 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, --Latency; break; } - case ARM::t2LDRs: - case ARM::t2LDRBs: - case ARM::t2LDRHs: + case ARM::t2LDRs: case ARM::ATOMIC_t2LDRs: + case ARM::t2LDRBs: case ARM::ATOMIC_t2LDRBs: + case ARM::t2LDRHs: case ARM::ATOMIC_t2LDRHs: case ARM::t2LDRSHs: { // Thumb2 mode: lsl only. unsigned ShAmt = diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 9deb96e..828e7d4 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -870,10 +870,14 @@ needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { // return false for everything else. unsigned Opc = MI->getOpcode(); switch (Opc) { - case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12: + case ARM::LDRi12: case ARM::ATOMIC_LDRi12: + case ARM::LDRH: case ARM::ATOMIC_LDRH: + case ARM::LDRBi12: case ARM::ATOMIC_LDRBi12: case ARM::STRi12: case ARM::STRH: case ARM::STRBi12: - case ARM::t2LDRi12: case ARM::t2LDRi8: - case ARM::t2STRi12: case ARM::t2STRi8: + case ARM::t2LDRi12: case ARM::ATOMIC_t2LDRi12: + case ARM::t2LDRi8: case ARM::ATOMIC_t2LDRi8: + case ARM::t2STRi12: + case ARM::t2STRi8: case ARM::VLDRS: case ARM::VLDRD: case ARM::VSTRS: case ARM::VSTRD: case ARM::tSTRspi: case ARM::tLDRspi: diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6d701ea..ae51972 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -4199,6 +4199,37 @@ let usesCustomInserter = 1 in { } } +// Pseudo-instructions for atomic loads. +// These are marked with mayStore so they can't be reordered. +let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in { +def ATOMIC_LDRBrs : ARMPseudoExpand<(outs GPRnopc:$Rt), + (ins ldst_so_reg:$shift, pred:$p), + 4, IIC_iLoad_bh_r, [], + (LDRBrs GPRnopc:$Rt, ldst_so_reg:$shift, pred:$p)>; +def ATOMIC_LDRBi12 : ARMPseudoExpand<(outs GPRnopc:$Rt), + (ins addrmode_imm12:$addr, pred:$p), + 4, IIC_iLoad_bh_si, [], + (LDRBi12 GPRnopc:$Rt, addrmode_imm12:$addr, pred:$p)> { + let AM = AddrMode_i12; +} +def ATOMIC_LDRH : ARMPseudoExpand<(outs GPR:$Rt), + (ins addrmode3:$addr, pred:$p), + 4, IIC_iLoad_bh_r, [], + (LDRH GPR:$Rt, addrmode3:$addr, pred:$p)> { + let AM = AddrMode3; +} +def ATOMIC_LDRi12 : ARMPseudoExpand<(outs GPR:$Rt), + (ins addrmode_imm12:$addr, pred:$p), + 4, IIC_iLoad_si, [], + (LDRi12 GPR:$Rt, addrmode_imm12:$addr, pred:$p)> { + let AM = AddrMode_i12; +} +def ATOMIC_LDRrs : ARMPseudoExpand<(outs GPR:$Rt), + (ins ldst_so_reg:$shift, pred:$p), + 4, IIC_iLoad_r, [], + (LDRrs GPR:$Rt, ldst_so_reg:$shift, pred:$p)>; +} + let usesCustomInserter = 1 in { def COPY_STRUCT_BYVAL_I32 : PseudoInst< (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment), @@ -4902,15 +4933,15 @@ def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)), // Atomic load/store patterns def : ARMPat<(atomic_load_8 ldst_so_reg:$src), - (LDRBrs ldst_so_reg:$src)>; + (ATOMIC_LDRBrs ldst_so_reg:$src)>; def : ARMPat<(atomic_load_8 addrmode_imm12:$src), - (LDRBi12 addrmode_imm12:$src)>; + (ATOMIC_LDRBi12 addrmode_imm12:$src)>; def : ARMPat<(atomic_load_16 addrmode3:$src), - (LDRH addrmode3:$src)>; + (ATOMIC_LDRH addrmode3:$src)>; def : ARMPat<(atomic_load_32 ldst_so_reg:$src), - (LDRrs ldst_so_reg:$src)>; + (ATOMIC_LDRrs ldst_so_reg:$src)>; def : ARMPat<(atomic_load_32 addrmode_imm12:$src), - (LDRi12 addrmode_imm12:$src)>; + (ATOMIC_LDRi12 addrmode_imm12:$src)>; def : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val), (STRBrs GPR:$val, ldst_so_reg:$ptr)>; def : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val), diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index e171f8b..bad7740 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -681,6 +681,41 @@ def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i, let Inst{7-0} = addr; } +// Atomic loads. These pseudos expand to the loads above, but the have mayStore +// = 1 so they can't be reordered. +let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in { +let AM = AddrModeT1_1 in { +def ATOMIC_tLDRBi : tPseudoExpand<(outs tGPR:$Rt), + (ins t_addrmode_is1:$addr, pred:$p), + 2, IIC_iLoad_bh_i, [], + (tLDRBi tGPR:$Rt, t_addrmode_is1:$addr, pred:$p)>; +def ATOMIC_tLDRBr : tPseudoExpand<(outs tGPR:$Rt), + (ins t_addrmode_rrs1:$addr, pred:$p), + 2, IIC_iLoad_bh_r, [], + (tLDRBr tGPR:$Rt, t_addrmode_rrs1:$addr, pred:$p)>; +} +let AM = AddrModeT1_2 in { +def ATOMIC_tLDRHi : tPseudoExpand<(outs tGPR:$Rt), + (ins t_addrmode_is2:$addr, pred:$p), + 2, IIC_iLoad_bh_i, [], + (tLDRHi tGPR:$Rt, t_addrmode_is2:$addr, pred:$p)>; +def ATOMIC_tLDRHr : tPseudoExpand<(outs tGPR:$Rt), + (ins t_addrmode_rrs2:$addr, pred:$p), + 2, IIC_iLoad_bh_r, [], + (tLDRHr tGPR:$Rt, t_addrmode_rrs2:$addr, pred:$p)>; +} +let AM = AddrModeT1_4 in { +def ATOMIC_tLDRi : tPseudoExpand<(outs tGPR:$Rt), + (ins t_addrmode_is4:$addr, pred:$p), + 2, IIC_iLoad_i, [], + (tLDRi tGPR:$Rt, t_addrmode_is4:$addr, pred:$p)>; +def ATOMIC_tLDRr : tPseudoExpand<(outs tGPR:$Rt), + (ins t_addrmode_rrs4:$addr, pred:$p), + 2, IIC_iLoad_r, [], + (tLDRr tGPR:$Rt, t_addrmode_rrs4:$addr, pred:$p)>; +} +} + //===----------------------------------------------------------------------===// // Load / store multiple Instructions. // @@ -1334,17 +1369,17 @@ def : T1Pat<(sextloadi16 t_addrmode_is2:$addr), (tASRri (tLSLri (tLDRHi t_addrmode_is2:$addr), 16), 16)>; def : T1Pat<(atomic_load_8 t_addrmode_is1:$src), - (tLDRBi t_addrmode_is1:$src)>; + (ATOMIC_tLDRBi t_addrmode_is1:$src)>; def : T1Pat<(atomic_load_8 t_addrmode_rrs1:$src), - (tLDRBr t_addrmode_rrs1:$src)>; + (ATOMIC_tLDRBr t_addrmode_rrs1:$src)>; def : T1Pat<(atomic_load_16 t_addrmode_is2:$src), - (tLDRHi t_addrmode_is2:$src)>; + (ATOMIC_tLDRHi t_addrmode_is2:$src)>; def : T1Pat<(atomic_load_16 t_addrmode_rrs2:$src), - (tLDRHr t_addrmode_rrs2:$src)>; + (ATOMIC_tLDRHr t_addrmode_rrs2:$src)>; def : T1Pat<(atomic_load_32 t_addrmode_is4:$src), - (tLDRi t_addrmode_is4:$src)>; + (ATOMIC_tLDRi t_addrmode_is4:$src)>; def : T1Pat<(atomic_load_32 t_addrmode_rrs4:$src), - (tLDRr t_addrmode_rrs4:$src)>; + (ATOMIC_tLDRr t_addrmode_rrs4:$src)>; def : T1Pat<(atomic_store_8 t_addrmode_is1:$ptr, tGPR:$val), (tSTRBi tGPR:$val, t_addrmode_is1:$ptr)>; def : T1Pat<(atomic_store_8 t_addrmode_rrs1:$ptr, tGPR:$val), diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index dbb8ffc..c039caa 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1590,6 +1590,46 @@ defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>; defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>; defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>; +// Pseudos for atomic loads. Setting mayStore prevents reordering. +let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in { +def ATOMIC_t2LDRBi12 : t2PseudoExpand<(outs rGPR:$Rt), + (ins t2addrmode_imm12:$addr, pred:$p), + 4, IIC_iLoad_bh_i, [], + (t2LDRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; +def ATOMIC_t2LDRBi8 : t2PseudoExpand<(outs rGPR:$Rt), + (ins t2addrmode_negimm8:$addr, pred:$p), + 4, IIC_iLoad_bh_i, [], + (t2LDRBi8 rGPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def ATOMIC_t2LDRBs : t2PseudoExpand<(outs rGPR:$Rt), + (ins t2addrmode_so_reg:$addr, pred:$p), + 4, IIC_iLoad_bh_si, [], + (t2LDRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; +def ATOMIC_t2LDRHi12 : t2PseudoExpand<(outs rGPR:$Rt), + (ins t2addrmode_imm12:$addr, pred:$p), + 4, IIC_iLoad_bh_i, [], + (t2LDRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; +def ATOMIC_t2LDRHi8 : t2PseudoExpand<(outs rGPR:$Rt), + (ins t2addrmode_negimm8:$addr, pred:$p), + 4, IIC_iLoad_bh_i, [], + (t2LDRHi8 rGPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def ATOMIC_t2LDRHs : t2PseudoExpand<(outs rGPR:$Rt), + (ins t2addrmode_so_reg:$addr, pred:$p), + 4, IIC_iLoad_bh_si, [], + (t2LDRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; +def ATOMIC_t2LDRi12 : t2PseudoExpand<(outs GPR:$Rt), + (ins t2addrmode_imm12:$addr, pred:$p), + 4, IIC_iLoad_i, [], + (t2LDRi12 GPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; +def ATOMIC_t2LDRi8 : t2PseudoExpand<(outs GPR:$Rt), + (ins t2addrmode_negimm8:$addr, pred:$p), + 4, IIC_iLoad_i, [], + (t2LDRi8 GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def ATOMIC_t2LDRs : t2PseudoExpand<(outs GPR:$Rt), + (ins t2addrmode_so_reg:$addr, pred:$p), + 4, IIC_iLoad_si, [], + (t2LDRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; +} + //===----------------------------------------------------------------------===// // Load / store multiple Instructions. // @@ -3968,24 +4008,24 @@ def : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i16)), Requires<[HasT2ExtractPack, IsThumb2]>; // Atomic load/store patterns -def : T2Pat<(atomic_load_8 t2addrmode_imm12:$addr), - (t2LDRBi12 t2addrmode_imm12:$addr)>; -def : T2Pat<(atomic_load_8 t2addrmode_negimm8:$addr), - (t2LDRBi8 t2addrmode_negimm8:$addr)>; +def : T2Pat<(atomic_load_8 t2addrmode_imm12:$addr), + (ATOMIC_t2LDRBi12 t2addrmode_imm12:$addr)>; +def : T2Pat<(atomic_load_8 t2addrmode_negimm8:$addr), + (ATOMIC_t2LDRBi8 t2addrmode_negimm8:$addr)>; def : T2Pat<(atomic_load_8 t2addrmode_so_reg:$addr), - (t2LDRBs t2addrmode_so_reg:$addr)>; -def : T2Pat<(atomic_load_16 t2addrmode_imm12:$addr), - (t2LDRHi12 t2addrmode_imm12:$addr)>; -def : T2Pat<(atomic_load_16 t2addrmode_negimm8:$addr), - (t2LDRHi8 t2addrmode_negimm8:$addr)>; + (ATOMIC_t2LDRBs t2addrmode_so_reg:$addr)>; +def : T2Pat<(atomic_load_16 t2addrmode_imm12:$addr), + (ATOMIC_t2LDRHi12 t2addrmode_imm12:$addr)>; +def : T2Pat<(atomic_load_16 t2addrmode_negimm8:$addr), + (ATOMIC_t2LDRHi8 t2addrmode_negimm8:$addr)>; def : T2Pat<(atomic_load_16 t2addrmode_so_reg:$addr), - (t2LDRHs t2addrmode_so_reg:$addr)>; -def : T2Pat<(atomic_load_32 t2addrmode_imm12:$addr), - (t2LDRi12 t2addrmode_imm12:$addr)>; + (ATOMIC_t2LDRHs t2addrmode_so_reg:$addr)>; +def : T2Pat<(atomic_load_32 t2addrmode_imm12:$addr), + (ATOMIC_t2LDRi12 t2addrmode_imm12:$addr)>; def : T2Pat<(atomic_load_32 t2addrmode_negimm8:$addr), - (t2LDRi8 t2addrmode_negimm8:$addr)>; + (ATOMIC_t2LDRi8 t2addrmode_negimm8:$addr)>; def : T2Pat<(atomic_load_32 t2addrmode_so_reg:$addr), - (t2LDRs t2addrmode_so_reg:$addr)>; + (ATOMIC_t2LDRs t2addrmode_so_reg:$addr)>; def : T2Pat<(atomic_store_8 t2addrmode_imm12:$addr, GPR:$val), (t2STRBi12 GPR:$val, t2addrmode_imm12:$addr)>; def : T2Pat<(atomic_store_8 t2addrmode_negimm8:$addr, GPR:$val), diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp index f18f491..796927c 100644 --- a/lib/Target/ARM/Thumb2SizeReduction.cpp +++ b/lib/Target/ARM/Thumb2SizeReduction.cpp @@ -114,6 +114,22 @@ namespace { { ARM::t2LDRHs, ARM::tLDRHr, 0, 0, 0, 1, 0, 0,0, 0,1 }, { ARM::t2LDRSBs,ARM::tLDRSB, 0, 0, 0, 1, 0, 0,0, 0,1 }, { ARM::t2LDRSHs,ARM::tLDRSH, 0, 0, 0, 1, 0, 0,0, 0,1 }, + + // At this point it is safe to translate acquire loads to normal loads. + // There is no risk of reordering loads. + { ARM::ATOMIC_t2LDRi12, + ARM::tLDRi, ARM::tLDRspi, 5, 8, 1, 0, 0,0, 0,1 }, + { ARM::ATOMIC_t2LDRs, + ARM::tLDRr, 0, 0, 0, 1, 0, 0,0, 0,1 }, + { ARM::ATOMIC_t2LDRBi12, + ARM::tLDRBi, 0, 5, 0, 1, 0, 0,0, 0,1 }, + { ARM::ATOMIC_t2LDRBs, + ARM::tLDRBr, 0, 0, 0, 1, 0, 0,0, 0,1 }, + { ARM::ATOMIC_t2LDRHi12, + ARM::tLDRHi, 0, 5, 0, 1, 0, 0,0, 0,1 }, + { ARM::ATOMIC_t2LDRHs, + ARM::tLDRHr, 0, 0, 0, 1, 0, 0,0, 0,1 }, + { ARM::t2STRi12,ARM::tSTRi, ARM::tSTRspi, 5, 8, 1, 0, 0,0, 0,1 }, { ARM::t2STRs, ARM::tSTRr, 0, 0, 0, 1, 0, 0,0, 0,1 }, { ARM::t2STRBi12,ARM::tSTRBi, 0, 5, 0, 1, 0, 0,0, 0,1 }, @@ -341,7 +357,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, switch (Entry.WideOpc) { default: llvm_unreachable("Unexpected Thumb2 load / store opcode!"); - case ARM::t2LDRi12: + case ARM::t2LDRi12: case ARM::ATOMIC_t2LDRi12: case ARM::t2STRi12: if (MI->getOperand(1).getReg() == ARM::SP) { Opc = Entry.NarrowOpc2; @@ -353,7 +369,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, HasImmOffset = true; HasOffReg = false; break; - case ARM::t2LDRBi12: + case ARM::t2LDRBi12: case ARM::ATOMIC_t2LDRBi12: case ARM::t2STRBi12: HasImmOffset = true; HasOffReg = false; @@ -364,9 +380,9 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, HasImmOffset = true; HasOffReg = false; break; - case ARM::t2LDRs: - case ARM::t2LDRBs: - case ARM::t2LDRHs: + case ARM::t2LDRs: case ARM::ATOMIC_t2LDRs: + case ARM::t2LDRBs: case ARM::ATOMIC_t2LDRBs: + case ARM::t2LDRHs: case ARM::ATOMIC_t2LDRHs: case ARM::t2LDRSBs: case ARM::t2LDRSHs: case ARM::t2STRs: -- cgit v1.1 From cff9baa95273bc279bf5fadb9e27afbd25cca20b Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 28 Aug 2012 03:11:27 +0000 Subject: Revert r162713: "Add ATOMIC_LDR* pseudo-instructions to model atomic_load on ARM." This wasn't the right way to enforce ordering of atomics. We are already setting the isVolatile bit on memory operands of atomic operations which is good enough to enforce the correct ordering. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162732 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 20 +++++----- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 10 ++--- lib/Target/ARM/ARMInstrInfo.td | 41 +++----------------- lib/Target/ARM/ARMInstrThumb.td | 47 +++-------------------- lib/Target/ARM/ARMInstrThumb2.td | 68 +++++++--------------------------- lib/Target/ARM/Thumb2SizeReduction.cpp | 26 +++---------- 6 files changed, 43 insertions(+), 169 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 378331f..2112992 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2778,8 +2778,8 @@ static int adjustDefLatency(const ARMSubtarget &Subtarget, // variants are one cycle cheaper. switch (DefMCID->getOpcode()) { default: break; - case ARM::LDRrs: case ARM::ATOMIC_LDRrs: - case ARM::LDRBrs: case ARM::ATOMIC_LDRBrs: { + case ARM::LDRrs: + case ARM::LDRBrs: { unsigned ShOpVal = DefMI->getOperand(3).getImm(); unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal); if (ShImm == 0 || @@ -2787,9 +2787,9 @@ static int adjustDefLatency(const ARMSubtarget &Subtarget, --Adjust; break; } - case ARM::t2LDRs: case ARM::ATOMIC_t2LDRs: - case ARM::t2LDRBs: case ARM::ATOMIC_t2LDRBs: - case ARM::t2LDRHs: case ARM::ATOMIC_t2LDRHs: + case ARM::t2LDRs: + case ARM::t2LDRBs: + case ARM::t2LDRHs: case ARM::t2LDRSHs: { // Thumb2 mode: lsl only. unsigned ShAmt = DefMI->getOperand(3).getImm(); @@ -3046,8 +3046,8 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, // variants are one cycle cheaper. switch (DefMCID.getOpcode()) { default: break; - case ARM::LDRrs: case ARM::ATOMIC_LDRrs: - case ARM::LDRBrs: case ARM::ATOMIC_LDRBrs: { + case ARM::LDRrs: + case ARM::LDRBrs: { unsigned ShOpVal = cast(DefNode->getOperand(2))->getZExtValue(); unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal); @@ -3056,9 +3056,9 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, --Latency; break; } - case ARM::t2LDRs: case ARM::ATOMIC_t2LDRs: - case ARM::t2LDRBs: case ARM::ATOMIC_t2LDRBs: - case ARM::t2LDRHs: case ARM::ATOMIC_t2LDRHs: + case ARM::t2LDRs: + case ARM::t2LDRBs: + case ARM::t2LDRHs: case ARM::t2LDRSHs: { // Thumb2 mode: lsl only. unsigned ShAmt = diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 828e7d4..9deb96e 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -870,14 +870,10 @@ needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { // return false for everything else. unsigned Opc = MI->getOpcode(); switch (Opc) { - case ARM::LDRi12: case ARM::ATOMIC_LDRi12: - case ARM::LDRH: case ARM::ATOMIC_LDRH: - case ARM::LDRBi12: case ARM::ATOMIC_LDRBi12: + case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12: case ARM::STRi12: case ARM::STRH: case ARM::STRBi12: - case ARM::t2LDRi12: case ARM::ATOMIC_t2LDRi12: - case ARM::t2LDRi8: case ARM::ATOMIC_t2LDRi8: - case ARM::t2STRi12: - case ARM::t2STRi8: + case ARM::t2LDRi12: case ARM::t2LDRi8: + case ARM::t2STRi12: case ARM::t2STRi8: case ARM::VLDRS: case ARM::VLDRD: case ARM::VSTRS: case ARM::VSTRD: case ARM::tSTRspi: case ARM::tLDRspi: diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index ae51972..6d701ea 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -4199,37 +4199,6 @@ let usesCustomInserter = 1 in { } } -// Pseudo-instructions for atomic loads. -// These are marked with mayStore so they can't be reordered. -let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in { -def ATOMIC_LDRBrs : ARMPseudoExpand<(outs GPRnopc:$Rt), - (ins ldst_so_reg:$shift, pred:$p), - 4, IIC_iLoad_bh_r, [], - (LDRBrs GPRnopc:$Rt, ldst_so_reg:$shift, pred:$p)>; -def ATOMIC_LDRBi12 : ARMPseudoExpand<(outs GPRnopc:$Rt), - (ins addrmode_imm12:$addr, pred:$p), - 4, IIC_iLoad_bh_si, [], - (LDRBi12 GPRnopc:$Rt, addrmode_imm12:$addr, pred:$p)> { - let AM = AddrMode_i12; -} -def ATOMIC_LDRH : ARMPseudoExpand<(outs GPR:$Rt), - (ins addrmode3:$addr, pred:$p), - 4, IIC_iLoad_bh_r, [], - (LDRH GPR:$Rt, addrmode3:$addr, pred:$p)> { - let AM = AddrMode3; -} -def ATOMIC_LDRi12 : ARMPseudoExpand<(outs GPR:$Rt), - (ins addrmode_imm12:$addr, pred:$p), - 4, IIC_iLoad_si, [], - (LDRi12 GPR:$Rt, addrmode_imm12:$addr, pred:$p)> { - let AM = AddrMode_i12; -} -def ATOMIC_LDRrs : ARMPseudoExpand<(outs GPR:$Rt), - (ins ldst_so_reg:$shift, pred:$p), - 4, IIC_iLoad_r, [], - (LDRrs GPR:$Rt, ldst_so_reg:$shift, pred:$p)>; -} - let usesCustomInserter = 1 in { def COPY_STRUCT_BYVAL_I32 : PseudoInst< (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment), @@ -4933,15 +4902,15 @@ def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)), // Atomic load/store patterns def : ARMPat<(atomic_load_8 ldst_so_reg:$src), - (ATOMIC_LDRBrs ldst_so_reg:$src)>; + (LDRBrs ldst_so_reg:$src)>; def : ARMPat<(atomic_load_8 addrmode_imm12:$src), - (ATOMIC_LDRBi12 addrmode_imm12:$src)>; + (LDRBi12 addrmode_imm12:$src)>; def : ARMPat<(atomic_load_16 addrmode3:$src), - (ATOMIC_LDRH addrmode3:$src)>; + (LDRH addrmode3:$src)>; def : ARMPat<(atomic_load_32 ldst_so_reg:$src), - (ATOMIC_LDRrs ldst_so_reg:$src)>; + (LDRrs ldst_so_reg:$src)>; def : ARMPat<(atomic_load_32 addrmode_imm12:$src), - (ATOMIC_LDRi12 addrmode_imm12:$src)>; + (LDRi12 addrmode_imm12:$src)>; def : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val), (STRBrs GPR:$val, ldst_so_reg:$ptr)>; def : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val), diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index bad7740..e171f8b 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -681,41 +681,6 @@ def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i, let Inst{7-0} = addr; } -// Atomic loads. These pseudos expand to the loads above, but the have mayStore -// = 1 so they can't be reordered. -let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in { -let AM = AddrModeT1_1 in { -def ATOMIC_tLDRBi : tPseudoExpand<(outs tGPR:$Rt), - (ins t_addrmode_is1:$addr, pred:$p), - 2, IIC_iLoad_bh_i, [], - (tLDRBi tGPR:$Rt, t_addrmode_is1:$addr, pred:$p)>; -def ATOMIC_tLDRBr : tPseudoExpand<(outs tGPR:$Rt), - (ins t_addrmode_rrs1:$addr, pred:$p), - 2, IIC_iLoad_bh_r, [], - (tLDRBr tGPR:$Rt, t_addrmode_rrs1:$addr, pred:$p)>; -} -let AM = AddrModeT1_2 in { -def ATOMIC_tLDRHi : tPseudoExpand<(outs tGPR:$Rt), - (ins t_addrmode_is2:$addr, pred:$p), - 2, IIC_iLoad_bh_i, [], - (tLDRHi tGPR:$Rt, t_addrmode_is2:$addr, pred:$p)>; -def ATOMIC_tLDRHr : tPseudoExpand<(outs tGPR:$Rt), - (ins t_addrmode_rrs2:$addr, pred:$p), - 2, IIC_iLoad_bh_r, [], - (tLDRHr tGPR:$Rt, t_addrmode_rrs2:$addr, pred:$p)>; -} -let AM = AddrModeT1_4 in { -def ATOMIC_tLDRi : tPseudoExpand<(outs tGPR:$Rt), - (ins t_addrmode_is4:$addr, pred:$p), - 2, IIC_iLoad_i, [], - (tLDRi tGPR:$Rt, t_addrmode_is4:$addr, pred:$p)>; -def ATOMIC_tLDRr : tPseudoExpand<(outs tGPR:$Rt), - (ins t_addrmode_rrs4:$addr, pred:$p), - 2, IIC_iLoad_r, [], - (tLDRr tGPR:$Rt, t_addrmode_rrs4:$addr, pred:$p)>; -} -} - //===----------------------------------------------------------------------===// // Load / store multiple Instructions. // @@ -1369,17 +1334,17 @@ def : T1Pat<(sextloadi16 t_addrmode_is2:$addr), (tASRri (tLSLri (tLDRHi t_addrmode_is2:$addr), 16), 16)>; def : T1Pat<(atomic_load_8 t_addrmode_is1:$src), - (ATOMIC_tLDRBi t_addrmode_is1:$src)>; + (tLDRBi t_addrmode_is1:$src)>; def : T1Pat<(atomic_load_8 t_addrmode_rrs1:$src), - (ATOMIC_tLDRBr t_addrmode_rrs1:$src)>; + (tLDRBr t_addrmode_rrs1:$src)>; def : T1Pat<(atomic_load_16 t_addrmode_is2:$src), - (ATOMIC_tLDRHi t_addrmode_is2:$src)>; + (tLDRHi t_addrmode_is2:$src)>; def : T1Pat<(atomic_load_16 t_addrmode_rrs2:$src), - (ATOMIC_tLDRHr t_addrmode_rrs2:$src)>; + (tLDRHr t_addrmode_rrs2:$src)>; def : T1Pat<(atomic_load_32 t_addrmode_is4:$src), - (ATOMIC_tLDRi t_addrmode_is4:$src)>; + (tLDRi t_addrmode_is4:$src)>; def : T1Pat<(atomic_load_32 t_addrmode_rrs4:$src), - (ATOMIC_tLDRr t_addrmode_rrs4:$src)>; + (tLDRr t_addrmode_rrs4:$src)>; def : T1Pat<(atomic_store_8 t_addrmode_is1:$ptr, tGPR:$val), (tSTRBi tGPR:$val, t_addrmode_is1:$ptr)>; def : T1Pat<(atomic_store_8 t_addrmode_rrs1:$ptr, tGPR:$val), diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index c039caa..dbb8ffc 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1590,46 +1590,6 @@ defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>; defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>; defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>; -// Pseudos for atomic loads. Setting mayStore prevents reordering. -let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in { -def ATOMIC_t2LDRBi12 : t2PseudoExpand<(outs rGPR:$Rt), - (ins t2addrmode_imm12:$addr, pred:$p), - 4, IIC_iLoad_bh_i, [], - (t2LDRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; -def ATOMIC_t2LDRBi8 : t2PseudoExpand<(outs rGPR:$Rt), - (ins t2addrmode_negimm8:$addr, pred:$p), - 4, IIC_iLoad_bh_i, [], - (t2LDRBi8 rGPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; -def ATOMIC_t2LDRBs : t2PseudoExpand<(outs rGPR:$Rt), - (ins t2addrmode_so_reg:$addr, pred:$p), - 4, IIC_iLoad_bh_si, [], - (t2LDRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; -def ATOMIC_t2LDRHi12 : t2PseudoExpand<(outs rGPR:$Rt), - (ins t2addrmode_imm12:$addr, pred:$p), - 4, IIC_iLoad_bh_i, [], - (t2LDRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; -def ATOMIC_t2LDRHi8 : t2PseudoExpand<(outs rGPR:$Rt), - (ins t2addrmode_negimm8:$addr, pred:$p), - 4, IIC_iLoad_bh_i, [], - (t2LDRHi8 rGPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; -def ATOMIC_t2LDRHs : t2PseudoExpand<(outs rGPR:$Rt), - (ins t2addrmode_so_reg:$addr, pred:$p), - 4, IIC_iLoad_bh_si, [], - (t2LDRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; -def ATOMIC_t2LDRi12 : t2PseudoExpand<(outs GPR:$Rt), - (ins t2addrmode_imm12:$addr, pred:$p), - 4, IIC_iLoad_i, [], - (t2LDRi12 GPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; -def ATOMIC_t2LDRi8 : t2PseudoExpand<(outs GPR:$Rt), - (ins t2addrmode_negimm8:$addr, pred:$p), - 4, IIC_iLoad_i, [], - (t2LDRi8 GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; -def ATOMIC_t2LDRs : t2PseudoExpand<(outs GPR:$Rt), - (ins t2addrmode_so_reg:$addr, pred:$p), - 4, IIC_iLoad_si, [], - (t2LDRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; -} - //===----------------------------------------------------------------------===// // Load / store multiple Instructions. // @@ -4008,24 +3968,24 @@ def : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i16)), Requires<[HasT2ExtractPack, IsThumb2]>; // Atomic load/store patterns -def : T2Pat<(atomic_load_8 t2addrmode_imm12:$addr), - (ATOMIC_t2LDRBi12 t2addrmode_imm12:$addr)>; -def : T2Pat<(atomic_load_8 t2addrmode_negimm8:$addr), - (ATOMIC_t2LDRBi8 t2addrmode_negimm8:$addr)>; +def : T2Pat<(atomic_load_8 t2addrmode_imm12:$addr), + (t2LDRBi12 t2addrmode_imm12:$addr)>; +def : T2Pat<(atomic_load_8 t2addrmode_negimm8:$addr), + (t2LDRBi8 t2addrmode_negimm8:$addr)>; def : T2Pat<(atomic_load_8 t2addrmode_so_reg:$addr), - (ATOMIC_t2LDRBs t2addrmode_so_reg:$addr)>; -def : T2Pat<(atomic_load_16 t2addrmode_imm12:$addr), - (ATOMIC_t2LDRHi12 t2addrmode_imm12:$addr)>; -def : T2Pat<(atomic_load_16 t2addrmode_negimm8:$addr), - (ATOMIC_t2LDRHi8 t2addrmode_negimm8:$addr)>; + (t2LDRBs t2addrmode_so_reg:$addr)>; +def : T2Pat<(atomic_load_16 t2addrmode_imm12:$addr), + (t2LDRHi12 t2addrmode_imm12:$addr)>; +def : T2Pat<(atomic_load_16 t2addrmode_negimm8:$addr), + (t2LDRHi8 t2addrmode_negimm8:$addr)>; def : T2Pat<(atomic_load_16 t2addrmode_so_reg:$addr), - (ATOMIC_t2LDRHs t2addrmode_so_reg:$addr)>; -def : T2Pat<(atomic_load_32 t2addrmode_imm12:$addr), - (ATOMIC_t2LDRi12 t2addrmode_imm12:$addr)>; + (t2LDRHs t2addrmode_so_reg:$addr)>; +def : T2Pat<(atomic_load_32 t2addrmode_imm12:$addr), + (t2LDRi12 t2addrmode_imm12:$addr)>; def : T2Pat<(atomic_load_32 t2addrmode_negimm8:$addr), - (ATOMIC_t2LDRi8 t2addrmode_negimm8:$addr)>; + (t2LDRi8 t2addrmode_negimm8:$addr)>; def : T2Pat<(atomic_load_32 t2addrmode_so_reg:$addr), - (ATOMIC_t2LDRs t2addrmode_so_reg:$addr)>; + (t2LDRs t2addrmode_so_reg:$addr)>; def : T2Pat<(atomic_store_8 t2addrmode_imm12:$addr, GPR:$val), (t2STRBi12 GPR:$val, t2addrmode_imm12:$addr)>; def : T2Pat<(atomic_store_8 t2addrmode_negimm8:$addr, GPR:$val), diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp index 796927c..f18f491 100644 --- a/lib/Target/ARM/Thumb2SizeReduction.cpp +++ b/lib/Target/ARM/Thumb2SizeReduction.cpp @@ -114,22 +114,6 @@ namespace { { ARM::t2LDRHs, ARM::tLDRHr, 0, 0, 0, 1, 0, 0,0, 0,1 }, { ARM::t2LDRSBs,ARM::tLDRSB, 0, 0, 0, 1, 0, 0,0, 0,1 }, { ARM::t2LDRSHs,ARM::tLDRSH, 0, 0, 0, 1, 0, 0,0, 0,1 }, - - // At this point it is safe to translate acquire loads to normal loads. - // There is no risk of reordering loads. - { ARM::ATOMIC_t2LDRi12, - ARM::tLDRi, ARM::tLDRspi, 5, 8, 1, 0, 0,0, 0,1 }, - { ARM::ATOMIC_t2LDRs, - ARM::tLDRr, 0, 0, 0, 1, 0, 0,0, 0,1 }, - { ARM::ATOMIC_t2LDRBi12, - ARM::tLDRBi, 0, 5, 0, 1, 0, 0,0, 0,1 }, - { ARM::ATOMIC_t2LDRBs, - ARM::tLDRBr, 0, 0, 0, 1, 0, 0,0, 0,1 }, - { ARM::ATOMIC_t2LDRHi12, - ARM::tLDRHi, 0, 5, 0, 1, 0, 0,0, 0,1 }, - { ARM::ATOMIC_t2LDRHs, - ARM::tLDRHr, 0, 0, 0, 1, 0, 0,0, 0,1 }, - { ARM::t2STRi12,ARM::tSTRi, ARM::tSTRspi, 5, 8, 1, 0, 0,0, 0,1 }, { ARM::t2STRs, ARM::tSTRr, 0, 0, 0, 1, 0, 0,0, 0,1 }, { ARM::t2STRBi12,ARM::tSTRBi, 0, 5, 0, 1, 0, 0,0, 0,1 }, @@ -357,7 +341,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, switch (Entry.WideOpc) { default: llvm_unreachable("Unexpected Thumb2 load / store opcode!"); - case ARM::t2LDRi12: case ARM::ATOMIC_t2LDRi12: + case ARM::t2LDRi12: case ARM::t2STRi12: if (MI->getOperand(1).getReg() == ARM::SP) { Opc = Entry.NarrowOpc2; @@ -369,7 +353,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, HasImmOffset = true; HasOffReg = false; break; - case ARM::t2LDRBi12: case ARM::ATOMIC_t2LDRBi12: + case ARM::t2LDRBi12: case ARM::t2STRBi12: HasImmOffset = true; HasOffReg = false; @@ -380,9 +364,9 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, HasImmOffset = true; HasOffReg = false; break; - case ARM::t2LDRs: case ARM::ATOMIC_t2LDRs: - case ARM::t2LDRBs: case ARM::ATOMIC_t2LDRBs: - case ARM::t2LDRHs: case ARM::ATOMIC_t2LDRHs: + case ARM::t2LDRs: + case ARM::t2LDRBs: + case ARM::t2LDRHs: case ARM::t2LDRSBs: case ARM::t2LDRSHs: case ARM::t2STRs: -- cgit v1.1 From d79dedd458c1de07fbc568ea8c3b4194e94df48e Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 29 Aug 2012 01:58:52 +0000 Subject: cleanup git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162820 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 40 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 2112992..5191c3e 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -705,28 +705,26 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB, else if (ARM::DQuadSpcRegClass.contains(DestReg, SrcReg)) Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 4, Spacing = 2; - if (Opc) { - const TargetRegisterInfo *TRI = &getRegisterInfo(); - MachineInstrBuilder Mov; - for (unsigned i = 0; i != SubRegs; ++i) { - unsigned Dst = TRI->getSubReg(DestReg, BeginIdx + i*Spacing); - unsigned Src = TRI->getSubReg(SrcReg, BeginIdx + i*Spacing); - assert(Dst && Src && "Bad sub-register"); - Mov = BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst) - .addReg(Src); - // VORR takes two source operands. - if (Opc == ARM::VORRq) - Mov.addReg(Src); - Mov = AddDefaultPred(Mov); - } - // Add implicit super-register defs and kills to the last instruction. - Mov->addRegisterDefined(DestReg, TRI); - if (KillSrc) - Mov->addRegisterKilled(SrcReg, TRI); - return; - } + if (!Opc) + llvm_unreachable("Impossible reg-to-reg copy"); - llvm_unreachable("Impossible reg-to-reg copy"); + const TargetRegisterInfo *TRI = &getRegisterInfo(); + MachineInstrBuilder Mov; + for (unsigned i = 0; i != SubRegs; ++i) { + unsigned Dst = TRI->getSubReg(DestReg, BeginIdx + i*Spacing); + unsigned Src = TRI->getSubReg(SrcReg, BeginIdx + i*Spacing); + assert(Dst && Src && "Bad sub-register"); + Mov = BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst) + .addReg(Src); + // VORR takes two source operands. + if (Opc == ARM::VORRq) + Mov.addReg(Src); + Mov = AddDefaultPred(Mov); + } + // Add implicit super-register defs and kills to the last instruction. + Mov->addRegisterDefined(DestReg, TRI); + if (KillSrc) + Mov->addRegisterKilled(SrcReg, TRI); } static const -- cgit v1.1 From f26e43df26bb7b0c7bf4853477e36611e2c90dea Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 29 Aug 2012 01:58:55 +0000 Subject: Fix ARM vector copies of overlapping register tuples. I have tested the fix, but have not been successfull in generating a robust unit test. This can only be exposed through particular register assignments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162821 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 5191c3e..f3c9cf4 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -710,10 +710,23 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB, const TargetRegisterInfo *TRI = &getRegisterInfo(); MachineInstrBuilder Mov; + + // Copy register tuples backward when the first Dest reg overlaps with SrcReg. + if (TRI->regsOverlap(SrcReg, TRI->getSubReg(DestReg, BeginIdx))) { + BeginIdx = BeginIdx + ((SubRegs-1)*Spacing); + Spacing = -Spacing; + } +#ifndef NDEBUG + SmallSet DstRegs; +#endif for (unsigned i = 0; i != SubRegs; ++i) { unsigned Dst = TRI->getSubReg(DestReg, BeginIdx + i*Spacing); unsigned Src = TRI->getSubReg(SrcReg, BeginIdx + i*Spacing); assert(Dst && Src && "Bad sub-register"); +#ifndef NDEBUG + DstRegs.insert(Dst); + assert(!DstRegs.count(Src) && "destructive vector copy"); +#endif Mov = BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst) .addReg(Src); // VORR takes two source operands. -- cgit v1.1 From c4dc2490c4ea2c75e451eec5950179f06d2610a2 Mon Sep 17 00:00:00 2001 From: Jush Lu Date: Wed, 29 Aug 2012 02:41:21 +0000 Subject: [arm-fast-isel] Add support for ARM PIC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162823 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 436b6ac..9849cb5 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -617,10 +617,7 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, EVT VT) { if (VT != MVT::i32) return 0; Reloc::Model RelocM = TM.getRelocationModel(); - - // TODO: Need more magic for ARM PIC. - if (!isThumb2 && (RelocM == Reloc::PIC_)) return 0; - + bool IsIndirect = Subtarget->GVIsIndirectSymbol(GV, RelocM); unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); // Use movw+movt when possible, it avoids constant pool entries. @@ -668,17 +665,30 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, EVT VT) { .addConstantPoolIndex(Idx); if (RelocM == Reloc::PIC_) MIB.addImm(Id); + AddOptionalDefs(MIB); } else { // The extra immediate is for addrmode2. MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRcp), DestReg) .addConstantPoolIndex(Idx) .addImm(0); + AddOptionalDefs(MIB); + + if (RelocM == Reloc::PIC_) { + unsigned Opc = IsIndirect ? ARM::PICLDR : ARM::PICADD; + unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); + + MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, + DL, TII.get(Opc), NewDestReg) + .addReg(DestReg) + .addImm(Id); + AddOptionalDefs(MIB); + return NewDestReg; + } } - AddOptionalDefs(MIB); } - if (Subtarget->GVIsIndirectSymbol(GV, RelocM)) { + if (IsIndirect) { MachineInstrBuilder MIB; unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); if (isThumb2) -- cgit v1.1 From 7611a88b58e0a6960cdb5c72dc18a6c93e44cdc2 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 29 Aug 2012 04:41:37 +0000 Subject: Cleanup sloppy code. Jakob's review. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162825 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index f3c9cf4..4f203ea 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -683,7 +683,7 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB, // Handle register classes that require multiple instructions. unsigned BeginIdx = 0; unsigned SubRegs = 0; - unsigned Spacing = 1; + int Spacing = 1; // Use VORRq when possible. if (ARM::QQPRRegClass.contains(DestReg, SrcReg)) @@ -705,8 +705,7 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB, else if (ARM::DQuadSpcRegClass.contains(DestReg, SrcReg)) Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 4, Spacing = 2; - if (!Opc) - llvm_unreachable("Impossible reg-to-reg copy"); + assert(Opc && "Impossible reg-to-reg copy"); const TargetRegisterInfo *TRI = &getRegisterInfo(); MachineInstrBuilder Mov; @@ -724,8 +723,8 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB, unsigned Src = TRI->getSubReg(SrcReg, BeginIdx + i*Spacing); assert(Dst && Src && "Bad sub-register"); #ifndef NDEBUG - DstRegs.insert(Dst); assert(!DstRegs.count(Src) && "destructive vector copy"); + DstRegs.insert(Dst); #endif Mov = BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst) .addReg(Src); -- cgit v1.1 From 20599ea4bced03634a54b52e98d261018366f279 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 29 Aug 2012 16:36:07 +0000 Subject: Refactor setExecutionDomain to be clearer about what it's doing and more robust. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162844 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 98 ++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 45 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 4f203ea..41d0c57 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -3397,13 +3397,28 @@ ARMBaseInstrInfo::getExecutionDomain(const MachineInstr *MI) const { return std::make_pair(ExeGeneric, 0); } +static unsigned getCorrespondingDRegAndLane(const TargetRegisterInfo *TRI, + unsigned SReg, unsigned &Lane) { + unsigned DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_0, &ARM::DPRRegClass); + Lane = 0; + + if (DReg != ARM::NoRegister) + return DReg; + + Lane = 1; + DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_1, &ARM::DPRRegClass); + + assert(DReg && "S-register with no D super-register?"); + return DReg; +} + + void ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { unsigned DstReg, SrcReg, DReg; unsigned Lane; MachineInstrBuilder MIB(MI); const TargetRegisterInfo *TRI = &getRegisterInfo(); - bool isKill; switch (MI->getOpcode()) { default: llvm_unreachable("cannot handle opcode!"); @@ -3414,77 +3429,70 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { // Zap the predicate operands. assert(!isPredicated(MI) && "Cannot predicate a VORRd"); - MI->RemoveOperand(3); - MI->RemoveOperand(2); - // Change to a VORRd which requires two identical use operands. - MI->setDesc(get(ARM::VORRd)); + // Source instruction is %DDst = VMOVD %DSrc, 14, %noreg (; implicits) + DstReg = MI->getOperand(0).getReg(); + SrcReg = MI->getOperand(1).getReg(); - // Add the extra source operand and new predicates. - // This will go before any implicit ops. - AddDefaultPred(MachineInstrBuilder(MI).addOperand(MI->getOperand(1))); + for (unsigned i = MI->getDesc().getNumOperands(); i; --i) + MI->RemoveOperand(i-1); + + // Change to a %DDst = VORRd %DSrc, %DSrc, 14, %noreg (; implicits) + MI->setDesc(get(ARM::VORRd)); + AddDefaultPred(MIB.addReg(DstReg, RegState::Define) + .addReg(SrcReg) + .addReg(SrcReg)); break; case ARM::VMOVRS: if (Domain != ExeNEON) break; assert(!isPredicated(MI) && "Cannot predicate a VGETLN"); + // Source instruction is %RDst = VMOVRS %SSrc, 14, %noreg (; implicits) DstReg = MI->getOperand(0).getReg(); SrcReg = MI->getOperand(1).getReg(); - DReg = TRI->getMatchingSuperReg(SrcReg, ARM::ssub_0, &ARM::DPRRegClass); - Lane = 0; - if (DReg == ARM::NoRegister) { - DReg = TRI->getMatchingSuperReg(SrcReg, ARM::ssub_1, &ARM::DPRRegClass); - Lane = 1; - assert(DReg && "S-register with no D super-register?"); - } + for (unsigned i = MI->getDesc().getNumOperands(); i; --i) + MI->RemoveOperand(i-1); - MI->RemoveOperand(3); - MI->RemoveOperand(2); - MI->RemoveOperand(1); + DReg = getCorrespondingDRegAndLane(TRI, SrcReg, Lane); + // Convert to %RDst = VGETLNi32 %DSrc, Lane, 14, %noreg (; imps) + // Note that DSrc has been widened and the other lane may be undef, which + // contaminates the entire register. MI->setDesc(get(ARM::VGETLNi32)); - MIB.addReg(DReg); - MIB.addImm(Lane); + AddDefaultPred(MIB.addReg(DstReg, RegState::Define) + .addReg(DReg, RegState::Undef) + .addImm(Lane)); - MIB->getOperand(1).setIsUndef(); + // The old source should be an implicit use, otherwise we might think it + // was dead before here. MIB.addReg(SrcReg, RegState::Implicit); - - AddDefaultPred(MIB); break; case ARM::VMOVSR: if (Domain != ExeNEON) break; assert(!isPredicated(MI) && "Cannot predicate a VSETLN"); + // Source instruction is %SDst = VMOVSR %RSrc, 14, %noreg (; implicits) DstReg = MI->getOperand(0).getReg(); SrcReg = MI->getOperand(1).getReg(); - DReg = TRI->getMatchingSuperReg(DstReg, ARM::ssub_0, &ARM::DPRRegClass); - Lane = 0; - if (DReg == ARM::NoRegister) { - DReg = TRI->getMatchingSuperReg(DstReg, ARM::ssub_1, &ARM::DPRRegClass); - Lane = 1; - assert(DReg && "S-register with no D super-register?"); - } - isKill = MI->getOperand(0).isKill(); - - MI->RemoveOperand(3); - MI->RemoveOperand(2); - MI->RemoveOperand(1); - MI->RemoveOperand(0); - MI->setDesc(get(ARM::VSETLNi32)); - MIB.addReg(DReg, RegState::Define); - MIB.addReg(DReg, RegState::Undef); - MIB.addReg(SrcReg); - MIB.addImm(Lane); + for (unsigned i = MI->getDesc().getNumOperands(); i; --i) + MI->RemoveOperand(i-1); - if (isKill) - MIB->addRegisterKilled(DstReg, TRI, true); - MIB->addRegisterDefined(DstReg, TRI); + DReg = getCorrespondingDRegAndLane(TRI, DstReg, Lane); - AddDefaultPred(MIB); + // Convert to %DDst = VSETLNi32 %DDst, %RSrc, Lane, 14, %noreg (; imps) + // Again DDst may be undefined at the beginning of this instruction. + MI->setDesc(get(ARM::VSETLNi32)); + AddDefaultPred(MIB.addReg(DReg, RegState::Define) + .addReg(DReg, RegState::Undef) + .addReg(SrcReg) + .addImm(Lane)); + + // The destination must be marked as set. + MIB.addReg(DstReg, RegState::Define | RegState::Implicit); break; } -- cgit v1.1 From c4a32e6596f3974a6c00322db1f5f31ea448bd58 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 30 Aug 2012 10:17:45 +0000 Subject: Add support for moving pure S-register to NEON pipeline if desired git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162898 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 73 ++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 41d0c57..7b7b6e3 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -3377,7 +3377,8 @@ ARMBaseInstrInfo::getExecutionDomain(const MachineInstr *MI) const { // converted. if (Subtarget.isCortexA9() && !isPredicated(MI) && (MI->getOpcode() == ARM::VMOVRS || - MI->getOpcode() == ARM::VMOVSR)) + MI->getOpcode() == ARM::VMOVSR || + MI->getOpcode() == ARM::VMOVS)) return std::make_pair(ExeVFP, (1<getOperand(0).getReg(); + SrcReg = MI->getOperand(1).getReg(); + + for (unsigned i = MI->getDesc().getNumOperands(); i; --i) + MI->RemoveOperand(i-1); + + unsigned DstLane = 0, SrcLane = 0, DDst, DSrc; + DDst = getCorrespondingDRegAndLane(TRI, DstReg, DstLane); + DSrc = getCorrespondingDRegAndLane(TRI, SrcReg, SrcLane); + + if (DSrc == DDst) { + // Destination can be: + // %DDst = VDUPLN32d %DDst, Lane, 14, %noreg (; implicits) + MI->setDesc(get(ARM::VDUPLN32d)); + AddDefaultPred(MIB.addReg(DDst, RegState::Define) + .addReg(DDst, RegState::Undef) + .addImm(SrcLane)); + + // Neither the source or the destination are naturally represented any + // more, so add them in manually. + MIB.addReg(DstReg, RegState::Implicit | RegState::Define); + MIB.addReg(SrcReg, RegState::Implicit); + break; + } + + // In general there's no single instruction that can perform an S <-> S + // move in NEON space, but a pair of VEXT instructions *can* do the + // job. It turns out that the VEXTs needed will only use DSrc once, with + // the position based purely on the combination of lane-0 and lane-1 + // involved. For example + // vmov s0, s2 -> vext.32 d0, d0, d1, #1 vext.32 d0, d0, d0, #1 + // vmov s1, s3 -> vext.32 d0, d1, d0, #1 vext.32 d0, d0, d0, #1 + // vmov s0, s3 -> vext.32 d0, d0, d0, #1 vext.32 d0, d1, d0, #1 + // vmov s1, s2 -> vext.32 d0, d0, d0, #1 vext.32 d0, d0, d1, #1 + // + // Pattern of the MachineInstrs is: + // %DDst = VEXTd32 %DSrc1, %DSrc2, Lane, 14, %noreg (;implicits) + MachineInstrBuilder NewMIB; + NewMIB = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), + get(ARM::VEXTd32), DDst); + NewMIB.addReg(SrcLane == 1 && DstLane == 1 ? DSrc : DDst, RegState::Undef); + NewMIB.addReg(SrcLane == 0 && DstLane == 0 ? DSrc : DDst, RegState::Undef); + NewMIB.addImm(1); + AddDefaultPred(NewMIB); + + if (SrcLane == DstLane) + NewMIB.addReg(SrcReg, RegState::Implicit); + + MI->setDesc(get(ARM::VEXTd32)); + MIB.addReg(DDst, RegState::Define); + MIB.addReg(SrcLane == 1 && DstLane == 0 ? DSrc : DDst, RegState::Undef); + MIB.addReg(SrcLane == 0 && DstLane == 1 ? DSrc : DDst, RegState::Undef); + MIB.addImm(1); + AddDefaultPred(MIB); + + if (SrcLane != DstLane) + MIB.addReg(SrcReg, RegState::Implicit); + + // As before, the original destination is no longer represented, add it + // implicitly. + MIB.addReg(DstReg, RegState::Define | RegState::Implicit); + break; + } } } -- cgit v1.1 From 1122fc40c16785d510025daeb6c72a075f7e2e5b Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Thu, 30 Aug 2012 23:00:00 +0000 Subject: Typo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162952 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3a5957b..d981ef9 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -4144,7 +4144,7 @@ cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, return true; } -/// cvtThumbMultiple- Convert parsed operands to MCInst. +/// cvtThumbMultiply - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. bool ARMAsmParser:: -- cgit v1.1 From 64b3444cbf7f5976502ff4cf6fc89aed4986b59c Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Thu, 30 Aug 2012 23:20:38 +0000 Subject: Move a check to the validateInstruction() function where it more properly belongs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162954 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index d981ef9..f1b1cc6 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -4150,17 +4150,6 @@ cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, bool ARMAsmParser:: cvtThumbMultiply(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { - // The second source operand must be the same register as the destination - // operand. - if (Operands.size() == 6 && - (((ARMOperand*)Operands[3])->getReg() != - ((ARMOperand*)Operands[5])->getReg()) && - (((ARMOperand*)Operands[3])->getReg() != - ((ARMOperand*)Operands[4])->getReg())) { - Error(Operands[3]->getStartLoc(), - "destination register must match source register"); - return false; - } ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); // If we have a three-operand form, make sure to set Rn to be the operand @@ -5377,6 +5366,19 @@ validateInstruction(MCInst &Inst, "in register list"); break; } + case ARM::tMUL: { + // The second source operand must be the same register as the destination + // operand. + if (Operands.size() == 6 && + (((ARMOperand*)Operands[3])->getReg() != + ((ARMOperand*)Operands[5])->getReg()) && + (((ARMOperand*)Operands[3])->getReg() != + ((ARMOperand*)Operands[4])->getReg())) { + Error(Operands[3]->getStartLoc(), + "destination register must match source register"); + } + break; + } // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2, // so only issue a diagnostic for thumb1. The instructions will be // switched to the t2 encodings in processInstruction() if necessary. -- cgit v1.1 From fafa283e65bca1473eace94057077129a76dbdcc Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Thu, 30 Aug 2012 23:22:05 +0000 Subject: Fix for r162954. Return the Error. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162955 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index f1b1cc6..c4341bb 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5374,8 +5374,8 @@ validateInstruction(MCInst &Inst, ((ARMOperand*)Operands[5])->getReg()) && (((ARMOperand*)Operands[3])->getReg() != ((ARMOperand*)Operands[4])->getReg())) { - Error(Operands[3]->getStartLoc(), - "destination register must match source register"); + return Error(Operands[3]->getStartLoc(), + "destination register must match source register"); } break; } -- cgit v1.1 From 359956dc1be35df4f8179eb14cea617c3ef10dd7 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 31 Aug 2012 00:03:31 +0000 Subject: With the fix in r162954/162955 every cvt function returns true. Thus, have the ConvertToMCInst() return void, rather then a bool. Update all the cvt functions as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162961 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 106 ++++++++++++------------------ 1 file changed, 42 insertions(+), 64 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index c4341bb..cc2057d 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -181,47 +181,47 @@ class ARMAsmParser : public MCTargetAsmParser { OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index); // Asm Match Converter Methods - bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, + void cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, + void cvtT2StrdPre(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, + void cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, + void cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + void cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, + void cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, + void cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + void cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, + void cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, + void cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, + void cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, + void cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, + void cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, + void cvtLdrdPre(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtStrdPre(MCInst &Inst, unsigned Opcode, + void cvtStrdPre(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, + void cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, + void cvtThumbMultiply(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, + void cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, + void cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, + void cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); - bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, + void cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); bool validateInstruction(MCInst &Inst, @@ -3880,7 +3880,7 @@ parseAM3Offset(SmallVectorImpl &Operands) { /// cvtT2LdrdPre - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Rt, Rt2 @@ -3892,13 +3892,12 @@ cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtT2StrdPre - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtT2StrdPre(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -3910,13 +3909,12 @@ cvtT2StrdPre(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -3926,13 +3924,12 @@ cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -3940,13 +3937,12 @@ cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -3956,13 +3952,12 @@ cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -3972,14 +3967,13 @@ cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -3987,13 +3981,12 @@ cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -4001,13 +3994,12 @@ cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -4015,13 +4007,12 @@ cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Rt @@ -4034,13 +4025,12 @@ cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Rt @@ -4053,13 +4043,12 @@ cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -4072,13 +4061,12 @@ cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -4091,13 +4079,12 @@ cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtLdrdPre - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtLdrdPre(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Rt, Rt2 @@ -4109,13 +4096,12 @@ cvtLdrdPre(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtStrdPre - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtStrdPre(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -4127,13 +4113,12 @@ cvtStrdPre(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -4141,13 +4126,12 @@ cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, Inst.addOperand(MCOperand::CreateImm(0)); ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// cvtThumbMultiply - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: +void ARMAsmParser:: cvtThumbMultiply(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); @@ -4162,11 +4146,9 @@ cvtThumbMultiply(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1); Inst.addOperand(Inst.getOperand(0)); ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); - - return true; } -bool ARMAsmParser:: +void ARMAsmParser:: cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Vd @@ -4177,10 +4159,9 @@ cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } -bool ARMAsmParser:: +void ARMAsmParser:: cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Vd @@ -4193,10 +4174,9 @@ cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } -bool ARMAsmParser:: +void ARMAsmParser:: cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -4207,10 +4187,9 @@ cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } -bool ARMAsmParser:: +void ARMAsmParser:: cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. @@ -4223,7 +4202,6 @@ cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); // pred ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; } /// Parse an ARM memory expression, return false if successful else return true -- cgit v1.1 From 05e80f27148b1dc19925755d56b6466df840da44 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 31 Aug 2012 02:08:34 +0000 Subject: Fix a couple of typos in EmitAtomic. Thumb2 instructions are mostly constrained to rGPR, not tGPR which is for Thumb1. rdar://problem/12203728 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162968 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index df4039b..a02e8d5 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -5418,7 +5418,7 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, exitMBB->transferSuccessorsAndUpdatePHIs(BB); const TargetRegisterClass *TRC = isThumb2 ? - (const TargetRegisterClass*)&ARM::tGPRRegClass : + (const TargetRegisterClass*)&ARM::rGPRRegClass : (const TargetRegisterClass*)&ARM::GPRRegClass; unsigned scratch = MRI.createVirtualRegister(TRC); unsigned scratch2 = (!BinOpcode) ? incr : MRI.createVirtualRegister(TRC); @@ -5529,7 +5529,7 @@ ARMTargetLowering::EmitAtomicBinaryMinMax(MachineInstr *MI, exitMBB->transferSuccessorsAndUpdatePHIs(BB); const TargetRegisterClass *TRC = isThumb2 ? - (const TargetRegisterClass*)&ARM::tGPRRegClass : + (const TargetRegisterClass*)&ARM::rGPRRegClass : (const TargetRegisterClass*)&ARM::GPRRegClass; unsigned scratch = MRI.createVirtualRegister(TRC); unsigned scratch2 = MRI.createVirtualRegister(TRC); -- cgit v1.1 From 5d04a560a875eef5cc7ae2bfadaf7d46ea8a60c5 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 31 Aug 2012 16:41:07 +0000 Subject: The ConvertToMCInst() function can't fail, so remove the now dead Match_ConversionFail enum. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163002 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index cc2057d..1fde5a2 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7520,9 +7520,6 @@ MatchAndEmitInstruction(SMLoc IDLoc, case Match_MnemonicFail: return Error(IDLoc, "invalid instruction", ((ARMOperand*)Operands[0])->getLocRange()); - case Match_ConversionFail: - // The converter function will have already emitted a diagnostic. - return true; case Match_RequiresNotITBlock: return Error(IDLoc, "flag setting instruction only valid outside IT block"); case Match_RequiresITBlock: -- cgit v1.1 From 429af6fa4124d8b6dd310069e0a44dcacb35fc8a Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 31 Aug 2012 17:24:10 +0000 Subject: Add a comment to explain what's really going on. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163005 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 1fde5a2..3ee3db5 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5347,6 +5347,12 @@ validateInstruction(MCInst &Inst, case ARM::tMUL: { // The second source operand must be the same register as the destination // operand. + // + // In this case, we must directly check the parsed operands because the + // cvtThumbMultiply() function is written in such a way that it guarantees + // this first statement is always true for the new Inst. Essentially, the + // destination is unconditionally copied into the second source operand + // without checking to see if it matches what we actually parsed. if (Operands.size() == 6 && (((ARMOperand*)Operands[3])->getReg() != ((ARMOperand*)Operands[5])->getReg()) && -- cgit v1.1 From 756d2cc2f7f6745603fdc0ec1ed4476d06385845 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 31 Aug 2012 22:12:31 +0000 Subject: Remove an unused argument. The MCInst opcode is set in the ConvertToMCInst() function nowadays. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163030 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 89 +++++++++++++++---------------- 1 file changed, 42 insertions(+), 47 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3ee3db5..646b64f 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -181,49 +181,44 @@ class ARMAsmParser : public MCTargetAsmParser { OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index); // Asm Match Converter Methods - void cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &); - void cvtT2StrdPre(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &); - void cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, + void cvtT2LdrdPre(MCInst &Inst, const SmallVectorImpl &); + void cvtT2StrdPre(MCInst &Inst, const SmallVectorImpl &); + void cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, const SmallVectorImpl &); - void cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, + void cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, const SmallVectorImpl &); - void cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + void cvtLdWriteBackRegAddrMode2(MCInst &Inst, const SmallVectorImpl &); - void cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, + void cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, const SmallVectorImpl &); - void cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, + void cvtStWriteBackRegAddrModeImm12(MCInst &Inst, const SmallVectorImpl &); - void cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + void cvtStWriteBackRegAddrMode2(MCInst &Inst, const SmallVectorImpl &); - void cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, + void cvtStWriteBackRegAddrMode3(MCInst &Inst, const SmallVectorImpl &); - void cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, + void cvtLdExtTWriteBackImm(MCInst &Inst, const SmallVectorImpl &); - void cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, + void cvtLdExtTWriteBackReg(MCInst &Inst, const SmallVectorImpl &); - void cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, + void cvtStExtTWriteBackImm(MCInst &Inst, const SmallVectorImpl &); - void cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, + void cvtStExtTWriteBackReg(MCInst &Inst, const SmallVectorImpl &); - void cvtLdrdPre(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &); - void cvtStrdPre(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &); - void cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, + void cvtLdrdPre(MCInst &Inst, const SmallVectorImpl &); + void cvtStrdPre(MCInst &Inst, const SmallVectorImpl &); + void cvtLdWriteBackRegAddrMode3(MCInst &Inst, const SmallVectorImpl &); - void cvtThumbMultiply(MCInst &Inst, unsigned Opcode, + void cvtThumbMultiply(MCInst &Inst, const SmallVectorImpl &); - void cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, + void cvtVLDwbFixed(MCInst &Inst, const SmallVectorImpl &); - void cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, + void cvtVLDwbRegister(MCInst &Inst, const SmallVectorImpl &); - void cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, + void cvtVSTwbFixed(MCInst &Inst, const SmallVectorImpl &); - void cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, + void cvtVSTwbRegister(MCInst &Inst, const SmallVectorImpl &); - bool validateInstruction(MCInst &Inst, const SmallVectorImpl &Ops); bool processInstruction(MCInst &Inst, @@ -3881,7 +3876,7 @@ parseAM3Offset(SmallVectorImpl &Operands) { /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, +cvtT2LdrdPre(MCInst &Inst, const SmallVectorImpl &Operands) { // Rt, Rt2 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -3898,7 +3893,7 @@ cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtT2StrdPre(MCInst &Inst, unsigned Opcode, +cvtT2StrdPre(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateReg(0)); @@ -3915,7 +3910,7 @@ cvtT2StrdPre(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, +cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -3930,7 +3925,7 @@ cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, +cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); @@ -3943,7 +3938,7 @@ cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, +cvtLdWriteBackRegAddrMode2(MCInst &Inst, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -3958,7 +3953,7 @@ cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, +cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -3974,7 +3969,7 @@ cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, +cvtStWriteBackRegAddrModeImm12(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); @@ -3987,7 +3982,7 @@ cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, +cvtStWriteBackRegAddrMode2(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); @@ -4000,7 +3995,7 @@ cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, +cvtStWriteBackRegAddrMode3(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); @@ -4013,7 +4008,7 @@ cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, +cvtLdExtTWriteBackImm(MCInst &Inst, const SmallVectorImpl &Operands) { // Rt ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -4031,7 +4026,7 @@ cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, +cvtLdExtTWriteBackReg(MCInst &Inst, const SmallVectorImpl &Operands) { // Rt ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -4049,7 +4044,7 @@ cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, +cvtStExtTWriteBackImm(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); @@ -4067,7 +4062,7 @@ cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, +cvtStExtTWriteBackReg(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); @@ -4085,7 +4080,7 @@ cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtLdrdPre(MCInst &Inst, unsigned Opcode, +cvtLdrdPre(MCInst &Inst, const SmallVectorImpl &Operands) { // Rt, Rt2 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); @@ -4102,7 +4097,7 @@ cvtLdrdPre(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtStrdPre(MCInst &Inst, unsigned Opcode, +cvtStrdPre(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); @@ -4119,7 +4114,7 @@ cvtStrdPre(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, +cvtLdWriteBackRegAddrMode3(MCInst &Inst, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); // Create a writeback register dummy placeholder. @@ -4132,7 +4127,7 @@ cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. void ARMAsmParser:: -cvtThumbMultiply(MCInst &Inst, unsigned Opcode, +cvtThumbMultiply(MCInst &Inst, const SmallVectorImpl &Operands) { ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); @@ -4149,7 +4144,7 @@ cvtThumbMultiply(MCInst &Inst, unsigned Opcode, } void ARMAsmParser:: -cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, +cvtVLDwbFixed(MCInst &Inst, const SmallVectorImpl &Operands) { // Vd ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); @@ -4162,7 +4157,7 @@ cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, } void ARMAsmParser:: -cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, +cvtVLDwbRegister(MCInst &Inst, const SmallVectorImpl &Operands) { // Vd ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); @@ -4177,7 +4172,7 @@ cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, } void ARMAsmParser:: -cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, +cvtVSTwbFixed(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); @@ -4190,7 +4185,7 @@ cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, } void ARMAsmParser:: -cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, +cvtVSTwbRegister(MCInst &Inst, const SmallVectorImpl &Operands) { // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); -- cgit v1.1 From 8fccd013d87c4b12edb4c9982fd9f3517917d2f7 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Sat, 1 Sep 2012 15:06:36 +0000 Subject: Fix Thumb2 fixup kind in the integrated-as. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163063 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 7d6acbc..b53da3b 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -194,6 +194,10 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case ARM::fixup_arm_uncondbranch: Type = ELF::R_ARM_JUMP24; break; + case ARM::fixup_t2_condbranch: + case ARM::fixup_t2_uncondbranch: + Type = ELF::R_ARM_THM_JUMP24; + break; case ARM::fixup_arm_movt_hi16: case ARM::fixup_arm_movt_hi16_pcrel: Type = ELF::R_ARM_MOVT_PREL; -- cgit v1.1 From 89f49808ee79eebbc3267b6c595514d4ca1f3247 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Sat, 1 Sep 2012 18:07:29 +0000 Subject: Limit domain conversion to cases where it won't break dep chains. NEON domain conversion was too heavy-handed with its widened registers, which could have stripped existing instructions of their dependency, leaving them vulnerable to scheduling errors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163070 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 60 +++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 12 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 7b7b6e3..dc4b67a 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -3484,15 +3484,24 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { DReg = getCorrespondingDRegAndLane(TRI, DstReg, Lane); + // If we insert both a novel and an on the DReg, we break + // any existing dependency chain on the unused lane. Either already being + // present means this instruction is in that chain anyway so we can make + // the transformation. + if (!MI->definesRegister(DReg, TRI) && !MI->readsRegister(DReg, TRI)) + break; + // Convert to %DDst = VSETLNi32 %DDst, %RSrc, Lane, 14, %noreg (; imps) // Again DDst may be undefined at the beginning of this instruction. MI->setDesc(get(ARM::VSETLNi32)); - AddDefaultPred(MIB.addReg(DReg, RegState::Define) - .addReg(DReg, RegState::Undef) - .addReg(SrcReg) - .addImm(Lane)); + MIB.addReg(DReg, RegState::Define) + .addReg(DReg, getUndefRegState(!MI->readsRegister(DReg, TRI))) + .addReg(SrcReg) + .addImm(Lane); + AddDefaultPred(MIB); - // The destination must be marked as set. + // The narrower destination must be marked as set to keep previous chains + // in place. MIB.addReg(DstReg, RegState::Define | RegState::Implicit); break; case ARM::VMOVS: { @@ -3510,13 +3519,21 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { DDst = getCorrespondingDRegAndLane(TRI, DstReg, DstLane); DSrc = getCorrespondingDRegAndLane(TRI, SrcReg, SrcLane); + // If we insert both a novel and an on the DReg, we break + // any existing dependency chain on the unused lane. Either already being + // present means this instruction is in that chain anyway so we can make + // the transformation. + if (!MI->definesRegister(DDst, TRI) && !MI->readsRegister(DDst, TRI)) + break; + if (DSrc == DDst) { // Destination can be: // %DDst = VDUPLN32d %DDst, Lane, 14, %noreg (; implicits) MI->setDesc(get(ARM::VDUPLN32d)); - AddDefaultPred(MIB.addReg(DDst, RegState::Define) - .addReg(DDst, RegState::Undef) - .addImm(SrcLane)); + MIB.addReg(DDst, RegState::Define) + .addReg(DDst, getUndefRegState(!MI->readsRegister(DDst, TRI))) + .addImm(SrcLane); + AddDefaultPred(MIB); // Neither the source or the destination are naturally represented any // more, so add them in manually. @@ -3540,8 +3557,18 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { MachineInstrBuilder NewMIB; NewMIB = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), get(ARM::VEXTd32), DDst); - NewMIB.addReg(SrcLane == 1 && DstLane == 1 ? DSrc : DDst, RegState::Undef); - NewMIB.addReg(SrcLane == 0 && DstLane == 0 ? DSrc : DDst, RegState::Undef); + + // On the first instruction, both DSrc and DDst may be if present. + // Specifically when the original instruction didn't have them as an + // . + unsigned CurReg = SrcLane == 1 && DstLane == 1 ? DSrc : DDst; + bool CurUndef = !MI->readsRegister(CurReg, TRI); + NewMIB.addReg(CurReg, getUndefRegState(CurUndef)); + + CurReg = SrcLane == 0 && DstLane == 0 ? DSrc : DDst; + CurUndef = !MI->readsRegister(CurReg, TRI); + NewMIB.addReg(CurReg, getUndefRegState(CurUndef)); + NewMIB.addImm(1); AddDefaultPred(NewMIB); @@ -3550,8 +3577,17 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { MI->setDesc(get(ARM::VEXTd32)); MIB.addReg(DDst, RegState::Define); - MIB.addReg(SrcLane == 1 && DstLane == 0 ? DSrc : DDst, RegState::Undef); - MIB.addReg(SrcLane == 0 && DstLane == 1 ? DSrc : DDst, RegState::Undef); + + // On the second instruction, DDst has definitely been defined above, so + // it is not . DSrc, if present, can be as above. + CurReg = SrcLane == 1 && DstLane == 0 ? DSrc : DDst; + CurUndef = CurReg == DSrc && !MI->readsRegister(CurReg, TRI); + MIB.addReg(CurReg, getUndefRegState(CurUndef)); + + CurReg = SrcLane == 0 && DstLane == 1 ? DSrc : DDst; + CurUndef = CurReg == DSrc && !MI->readsRegister(CurReg, TRI); + MIB.addReg(CurReg, getUndefRegState(CurUndef)); + MIB.addImm(1); AddDefaultPred(MIB); -- cgit v1.1 From 9f40cb32ac31283f8636d516e7b10f3ad921955c Mon Sep 17 00:00:00 2001 From: Nadav Rotem Date: Sun, 2 Sep 2012 12:10:19 +0000 Subject: Not all targets have efficient ISel code generation for select instructions. For example, the ARM target does not have efficient ISel handling for vector selects with scalar conditions. This patch adds a TLI hook which allows the different targets to report which selects are supported well and which selects should be converted to CF duting codegen prepare. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163093 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 13b83de..757c68e 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -257,6 +257,11 @@ namespace llvm { virtual const char *getTargetNodeName(unsigned Opcode) const; + virtual bool isSelectSupported(SelectSupportKind Kind) const { + // ARM does not support scalar condition selects on vectors. + return (Kind != ScalarCondVectorVal); + } + /// getSetCCResultType - Return the value type to use for ISD::SETCC. virtual EVT getSetCCResultType(EVT VT) const; -- cgit v1.1 From 3a86e1396230748f17a521915bc802939a787eac Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Mon, 3 Sep 2012 02:06:46 +0000 Subject: [ms-inline asm] Expose the Kind and Opcode variables from the MatchInstructionImpl() function. These values are used by the ConvertToMCInst() function to index into the ConversionTable. The values are also needed to call the GetMCInstOperandNum() function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163101 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 646b64f..ebb0f8d 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7456,9 +7456,12 @@ MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out) { MCInst Inst; + unsigned Kind; + unsigned Opcode; unsigned ErrorInfo; unsigned MatchResult; - MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); + + MatchResult = MatchInstructionImpl(Operands, Kind, Opcode, Inst, ErrorInfo); switch (MatchResult) { default: break; case Match_Success: -- cgit v1.1 From c4d2560a2010456f4eea0007eb71829d5668e7dd Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Mon, 3 Sep 2012 03:16:09 +0000 Subject: Removed unused argument. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163104 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index ebb0f8d..fe11bec 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7457,11 +7457,10 @@ MatchAndEmitInstruction(SMLoc IDLoc, MCStreamer &Out) { MCInst Inst; unsigned Kind; - unsigned Opcode; unsigned ErrorInfo; unsigned MatchResult; - MatchResult = MatchInstructionImpl(Operands, Kind, Opcode, Inst, ErrorInfo); + MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo); switch (MatchResult) { default: break; case Match_Success: -- cgit v1.1 From 038f3e31276f8cc86d91d0e4513e1a3ddb8509ba Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Mon, 3 Sep 2012 18:47:45 +0000 Subject: [ms-inline asm] Add an interface to the GetMCInstOperandNum() function in the MCTargetAsmParser class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163122 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index fe11bec..bdb20e8 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -262,6 +262,12 @@ public: bool MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out); + + unsigned GetMCInstOperandNum(unsigned Kind, MCInst &Inst, + const SmallVectorImpl &Operands, + unsigned OperandNum) { + return GetMCInstOperandNumImpl(Kind, Inst, Operands, OperandNum); + } }; } // end anonymous namespace -- cgit v1.1 From 2cc97def7434345e399e4f5f3f2001d6d7a93c6f Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Mon, 3 Sep 2012 20:31:23 +0000 Subject: [ms-inline asm] Asm operands can map to one or more MCOperands. Therefore, add the NumMCOperands argument to the GetMCInstOperandNum() function that is set to the number of MCOperands this asm operand mapped to. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163124 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index bdb20e8..51ba3c3 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -265,8 +265,8 @@ public: unsigned GetMCInstOperandNum(unsigned Kind, MCInst &Inst, const SmallVectorImpl &Operands, - unsigned OperandNum) { - return GetMCInstOperandNumImpl(Kind, Inst, Operands, OperandNum); + unsigned OperandNum, unsigned &NumMCOperands) { + return GetMCInstOperandNumImpl(Kind, Inst, Operands, OperandNum, NumMCOperands); } }; } // end anonymous namespace -- cgit v1.1 From 67514e90669ec9ffd954c1fcb6f8979bafcabe8a Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 4 Sep 2012 14:37:49 +0000 Subject: Patch to implement UMLAL/SMLAL instructions for the ARM architecture This patch corrects the definition of umlal/smlal instructions and adds support for matching them to the ARM dag combiner. Bug 12213 Patch by Yin Ma! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163136 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelDAGToDAG.cpp | 32 ++++++++ lib/Target/ARM/ARMISelLowering.cpp | 156 +++++++++++++++++++++++++++++++++++++ lib/Target/ARM/ARMISelLowering.h | 3 + lib/Target/ARM/ARMInstrInfo.td | 46 ++++++++--- lib/Target/ARM/ARMInstrThumb2.td | 31 ++++++-- 5 files changed, 251 insertions(+), 17 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index c6f9d15..1406620 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -2637,6 +2637,38 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { dl, MVT::i32, MVT::i32, Ops, 5); } } + case ARMISD::UMLAL:{ + if (Subtarget->isThumb()) { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), + N->getOperand(3), getAL(CurDAG), + CurDAG->getRegister(0, MVT::i32)}; + return CurDAG->getMachineNode(ARM::t2UMLAL, dl, MVT::i32, MVT::i32, Ops, 6); + }else{ + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), + N->getOperand(3), getAL(CurDAG), + CurDAG->getRegister(0, MVT::i32), + CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->getMachineNode(Subtarget->hasV6Ops() ? + ARM::UMLAL : ARM::UMLALv5, + dl, MVT::i32, MVT::i32, Ops, 7); + } + } + case ARMISD::SMLAL:{ + if (Subtarget->isThumb()) { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), + N->getOperand(3), getAL(CurDAG), + CurDAG->getRegister(0, MVT::i32)}; + return CurDAG->getMachineNode(ARM::t2SMLAL, dl, MVT::i32, MVT::i32, Ops, 6); + }else{ + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), + N->getOperand(3), getAL(CurDAG), + CurDAG->getRegister(0, MVT::i32), + CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->getMachineNode(Subtarget->hasV6Ops() ? + ARM::SMLAL : ARM::SMLALv5, + dl, MVT::i32, MVT::i32, Ops, 7); + } + } case ISD::LOAD: { SDNode *ResNode = 0; if (Subtarget->isThumb() && Subtarget->hasThumb2()) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index a02e8d5..c17e9ae 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -566,6 +566,11 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) } } + // ARM and Thumb2 support UMLAL/SMLAL. + if (!Subtarget->isThumb1Only()) + setTargetDAGCombine(ISD::ADDC); + + computeRegisterProperties(); // ARM does not have f32 extending load. @@ -981,6 +986,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { case ARMISD::VTBL2: return "ARMISD::VTBL2"; case ARMISD::VMULLs: return "ARMISD::VMULLs"; case ARMISD::VMULLu: return "ARMISD::VMULLu"; + case ARMISD::UMLAL: return "ARMISD::UMLAL"; + case ARMISD::SMLAL: return "ARMISD::SMLAL"; case ARMISD::BUILD_VECTOR: return "ARMISD::BUILD_VECTOR"; case ARMISD::FMAX: return "ARMISD::FMAX"; case ARMISD::FMIN: return "ARMISD::FMIN"; @@ -7193,6 +7200,154 @@ static SDValue AddCombineToVPADDL(SDNode *N, SDValue N0, SDValue N1, return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, tmp); } +static SDValue findMUL_LOHI(SDValue V) { + if (V->getOpcode() == ISD::UMUL_LOHI || + V->getOpcode() == ISD::SMUL_LOHI) + return V; + return SDValue(); +} + +static SDValue AddCombineTo64bitMLAL(SDNode *AddcNode, + TargetLowering::DAGCombinerInfo &DCI, + const ARMSubtarget *Subtarget) { + + if (Subtarget->isThumb1Only()) return SDValue(); + + // Only perform the checks after legalize when the pattern is available. + if (DCI.isBeforeLegalize()) return SDValue(); + + // Look for multiply add opportunities. + // The pattern is a ISD::UMUL_LOHI followed by two add nodes, where + // each add nodes consumes a value from ISD::UMUL_LOHI and there is + // a glue link from the first add to the second add. + // If we find this pattern, we can replace the U/SMUL_LOHI, ADDC, and ADDE by + // a S/UMLAL instruction. + // loAdd UMUL_LOHI + // \ / :lo \ :hi + // \ / \ [no multiline comment] + // ADDC | hiAdd + // \ :glue / / + // \ / / + // ADDE + // + assert(AddcNode->getOpcode() == ISD::ADDC && "Expect an ADDC"); + SDValue AddcOp0 = AddcNode->getOperand(0); + SDValue AddcOp1 = AddcNode->getOperand(1); + + // Check if the two operands are from the same mul_lohi node. + if (AddcOp0.getNode() == AddcOp1.getNode()) + return SDValue(); + + assert(AddcNode->getNumValues() == 2 && + AddcNode->getValueType(0) == MVT::i32 && + AddcNode->getValueType(1) == MVT::Glue && + "Expect ADDC with two result values: i32, glue"); + + // Check that the ADDC adds the low result of the S/UMUL_LOHI. + if (AddcOp0->getOpcode() != ISD::UMUL_LOHI && + AddcOp0->getOpcode() != ISD::SMUL_LOHI && + AddcOp1->getOpcode() != ISD::UMUL_LOHI && + AddcOp1->getOpcode() != ISD::SMUL_LOHI) + return SDValue(); + + // Look for the glued ADDE. + SDNode* AddeNode = AddcNode->getGluedUser(); + if (AddeNode == NULL) + return SDValue(); + + // Make sure it is really an ADDE. + if (AddeNode->getOpcode() != ISD::ADDE) + return SDValue(); + + assert(AddeNode->getNumOperands() == 3 && + AddeNode->getOperand(2).getValueType() == MVT::Glue && + "ADDE node has the wrong inputs"); + + // Check for the triangle shape. + SDValue AddeOp0 = AddeNode->getOperand(0); + SDValue AddeOp1 = AddeNode->getOperand(1); + + // Make sure that the ADDE operands are not coming from the same node. + if (AddeOp0.getNode() == AddeOp1.getNode()) + return SDValue(); + + // Find the MUL_LOHI node walking up ADDE's operands. + bool IsLeftOperandMUL = false; + SDValue MULOp = findMUL_LOHI(AddeOp0); + if (MULOp == SDValue()) + MULOp = findMUL_LOHI(AddeOp1); + else + IsLeftOperandMUL = true; + if (MULOp == SDValue()) + return SDValue(); + + // Figure out the right opcode. + unsigned Opc = MULOp->getOpcode(); + unsigned FinalOpc = (Opc == ISD::SMUL_LOHI) ? ARMISD::SMLAL : ARMISD::UMLAL; + + // Figure out the high and low input values to the MLAL node. + SDValue* HiMul = &MULOp; + SDValue* HiAdd = NULL; + SDValue* LoMul = NULL; + SDValue* LowAdd = NULL; + + if (IsLeftOperandMUL) + HiAdd = &AddeOp1; + else + HiAdd = &AddeOp0; + + + if (AddcOp0->getOpcode() == Opc) { + LoMul = &AddcOp0; + LowAdd = &AddcOp1; + } + if (AddcOp1->getOpcode() == Opc) { + LoMul = &AddcOp1; + LowAdd = &AddcOp0; + } + + if (LoMul == NULL) + return SDValue(); + + if (LoMul->getNode() != HiMul->getNode()) + return SDValue(); + + // Create the merged node. + SelectionDAG &DAG = DCI.DAG; + + // Build operand list. + SmallVector Ops; + Ops.push_back(LoMul->getOperand(0)); + Ops.push_back(LoMul->getOperand(1)); + Ops.push_back(*LowAdd); + Ops.push_back(*HiAdd); + + SDValue MLALNode = DAG.getNode(FinalOpc, AddcNode->getDebugLoc(), + DAG.getVTList(MVT::i32, MVT::i32), + &Ops[0], Ops.size()); + + // Replace the ADDs' nodes uses by the MLA node's values. + SDValue HiMLALResult(MLALNode.getNode(), 1); + DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), HiMLALResult); + + SDValue LoMLALResult(MLALNode.getNode(), 0); + DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), LoMLALResult); + + // Return original node to notify the driver to stop replacing. + SDValue resNode(AddcNode, 0); + return resNode; +} + +/// PerformADDCCombine - Target-specific dag combine transform from +/// ISD::ADDC, ISD::ADDE, and ISD::MUL_LOHI to MLAL. +static SDValue PerformADDCCombine(SDNode *N, + TargetLowering::DAGCombinerInfo &DCI, + const ARMSubtarget *Subtarget) { + + return AddCombineTo64bitMLAL(N, DCI, Subtarget); + +} + /// PerformADDCombineWithOperands - Try DAG combinations for an ADD with /// operands N0 and N1. This is a helper for PerformADDCombine that is /// called with the default operands, and if that fails, with commuted @@ -8764,6 +8919,7 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { switch (N->getOpcode()) { default: break; + case ISD::ADDC: return PerformADDCCombine(N, DCI, Subtarget); case ISD::ADD: return PerformADDCombine(N, DCI, Subtarget); case ISD::SUB: return PerformSUBCombine(N, DCI); case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget); diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 757c68e..2b8f382 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -173,6 +173,9 @@ namespace llvm { VMULLs, // ...signed VMULLu, // ...unsigned + UMLAL, // 64bit Unsigned Accumulate Multiply + SMLAL, // 64bit Signed Accumulate Multiply + // Operands of the standard BUILD_VECTOR node are not legalized, which // is fine if BUILD_VECTORs are always lowered to shuffles or other // operations, but for ARM some BUILD_VECTORs are legal as-is and their diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6d701ea..e6e6d27 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -83,6 +83,13 @@ def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3, SDTCisInt<0>, SDTCisVT<1, i32>, SDTCisVT<4, i32>]>; + +def SDT_ARM64bitmlal : SDTypeProfile<2,4, [ SDTCisVT<0, i32>, SDTCisVT<1, i32>, + SDTCisVT<2, i32>, SDTCisVT<3, i32>, + SDTCisVT<4, i32>, SDTCisVT<5, i32> ] >; +def ARMUmlal : SDNode<"ARMISD::UMLAL", SDT_ARM64bitmlal>; +def ARMSmlal : SDNode<"ARMISD::SMLAL", SDT_ARM64bitmlal>; + // Node definitions. def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>; @@ -3405,6 +3412,18 @@ class AsMul1I64 opcod, dag oops, dag iops, InstrItinClass itin, let Inst{11-8} = Rm; let Inst{3-0} = Rn; } +class AsMla1I64 opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : AsMul1I { + bits<4> RdLo; + bits<4> RdHi; + bits<4> Rm; + bits<4> Rn; + let Inst{19-16} = RdHi; + let Inst{15-12} = RdLo; + let Inst{11-8} = Rm; + let Inst{3-0} = Rn; +} // FIXME: The v5 pseudos are only necessary for the additional Constraint // property. Remove them when it's possible to add those properties @@ -3487,14 +3506,14 @@ def UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), } // Multiply + accumulate -def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, +def SMLAL : AsMla1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi), + (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64, "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, - Requires<[IsARM, HasV6]>; -def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, + RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>; +def UMLAL : AsMla1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi), + (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64, "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, - Requires<[IsARM, HasV6]>; + RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>; def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, @@ -3510,17 +3529,22 @@ def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), let Inst{3-0} = Rn; } -let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { +let Constraints = "$RLo = $RdLo,$RHi = $RdHi" in { def SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s), 4, IIC_iMAC64, [], - (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, + (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, + pred:$p, cc_out:$s)>, Requires<[IsARM, NoV6]>; def UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s), 4, IIC_iMAC64, [], - (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, + (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, + pred:$p, cc_out:$s)>, Requires<[IsARM, NoV6]>; +} + +let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { def UMAALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), (ins GPR:$Rn, GPR:$Rm, pred:$p), 4, IIC_iMAC64, [], diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index dbb8ffc..6b0e6e5 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -523,6 +523,23 @@ class T2MulLong opc22_20, bits<4> opc7_4, let Inst{7-4} = opc7_4; let Inst{3-0} = Rm; } +class T2MlaLong opc22_20, bits<4> opc7_4, + dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : T2I { + bits<4> RdLo; + bits<4> RdHi; + bits<4> Rn; + bits<4> Rm; + + let Inst{31-23} = 0b111110111; + let Inst{22-20} = opc22_20; + let Inst{19-16} = Rn; + let Inst{15-12} = RdLo; + let Inst{11-8} = RdHi; + let Inst{7-4} = opc7_4; + let Inst{3-0} = Rm; +} /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a @@ -2438,15 +2455,17 @@ def t2UMULL : T2MulLong<0b010, 0b0000, } // isCommutable // Multiply + accumulate -def t2SMLAL : T2MulLong<0b100, 0b0000, +def t2SMLAL : T2MlaLong<0b100, 0b0000, (outs rGPR:$RdLo, rGPR:$RdHi), - (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, - "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>; + (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64, + "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, + RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">; -def t2UMLAL : T2MulLong<0b110, 0b0000, +def t2UMLAL : T2MlaLong<0b110, 0b0000, (outs rGPR:$RdLo, rGPR:$RdHi), - (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, - "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>; + (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64, + "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, + RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">; def t2UMAAL : T2MulLong<0b110, 0b0110, (outs rGPR:$RdLo, rGPR:$RdHi), -- cgit v1.1 From 5d637d7e93c1f6058c16b41b8ac7dd36c61b4a5c Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Wed, 5 Sep 2012 01:15:43 +0000 Subject: Fix function name per coding standard. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163187 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 51ba3c3..e1e2f6e 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -263,10 +263,10 @@ public: SmallVectorImpl &Operands, MCStreamer &Out); - unsigned GetMCInstOperandNum(unsigned Kind, MCInst &Inst, + unsigned getMCInstOperandNum(unsigned Kind, MCInst &Inst, const SmallVectorImpl &Operands, unsigned OperandNum, unsigned &NumMCOperands) { - return GetMCInstOperandNumImpl(Kind, Inst, Operands, OperandNum, NumMCOperands); + return getMCInstOperandNumImpl(Kind, Inst, Operands, OperandNum, NumMCOperands); } }; } // end anonymous namespace -- cgit v1.1 From 7bebddf55ece46995f310d79195afb4e5b239886 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 5 Sep 2012 18:37:53 +0000 Subject: Strip old MachineInstrs *after* we know we can put them back. Previous patch accidentally decided it couldn't convert a VFP to a NEON instruction after it had already destroyed the old one. Not a good move. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163230 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index dc4b67a..f8e554f 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -3479,9 +3479,6 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { DstReg = MI->getOperand(0).getReg(); SrcReg = MI->getOperand(1).getReg(); - for (unsigned i = MI->getDesc().getNumOperands(); i; --i) - MI->RemoveOperand(i-1); - DReg = getCorrespondingDRegAndLane(TRI, DstReg, Lane); // If we insert both a novel and an on the DReg, we break @@ -3491,6 +3488,9 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { if (!MI->definesRegister(DReg, TRI) && !MI->readsRegister(DReg, TRI)) break; + for (unsigned i = MI->getDesc().getNumOperands(); i; --i) + MI->RemoveOperand(i-1); + // Convert to %DDst = VSETLNi32 %DDst, %RSrc, Lane, 14, %noreg (; imps) // Again DDst may be undefined at the beginning of this instruction. MI->setDesc(get(ARM::VSETLNi32)); @@ -3512,9 +3512,6 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { DstReg = MI->getOperand(0).getReg(); SrcReg = MI->getOperand(1).getReg(); - for (unsigned i = MI->getDesc().getNumOperands(); i; --i) - MI->RemoveOperand(i-1); - unsigned DstLane = 0, SrcLane = 0, DDst, DSrc; DDst = getCorrespondingDRegAndLane(TRI, DstReg, DstLane); DSrc = getCorrespondingDRegAndLane(TRI, SrcReg, SrcLane); @@ -3526,6 +3523,9 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { if (!MI->definesRegister(DDst, TRI) && !MI->readsRegister(DDst, TRI)) break; + for (unsigned i = MI->getDesc().getNumOperands(); i; --i) + MI->RemoveOperand(i-1); + if (DSrc == DDst) { // Destination can be: // %DDst = VDUPLN32d %DDst, Lane, 14, %noreg (; implicits) -- cgit v1.1 From 59324297650c12a8dccf1a7ad650a9e895fdc17e Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Wed, 5 Sep 2012 22:26:57 +0000 Subject: Stop casting away const qualifier needlessly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163258 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMJITInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMJITInfo.cpp b/lib/Target/ARM/ARMJITInfo.cpp index 3f99cce..254d8f6 100644 --- a/lib/Target/ARM/ARMJITInfo.cpp +++ b/lib/Target/ARM/ARMJITInfo.cpp @@ -168,7 +168,7 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn, intptr_t LazyPtr = getIndirectSymAddr(Fn); if (!LazyPtr) { // In PIC mode, the function stub is loading a lazy-ptr. - LazyPtr= (intptr_t)emitGlobalValueIndirectSym((GlobalValue*)F, Fn, JCE); + LazyPtr= (intptr_t)emitGlobalValueIndirectSym((const GlobalValue*)F, Fn, JCE); DEBUG(if (F) errs() << "JIT: Indirect symbol emitted at [" << LazyPtr << "] for GV '" << F->getName() << "'\n"; -- cgit v1.1 From 098c6a547fe540b3bbace4c3d4713f400c67b8a9 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 5 Sep 2012 23:58:02 +0000 Subject: Use predication instead of pseudo-opcodes when folding into MOVCC. Now that it is possible to dynamically tie MachineInstr operands, predicated instructions are possible in SSA form: %vreg3 = SUBri %vreg1, -2147483647, pred:14, pred:%noreg, %opt:%noreg %vreg4 = MOVCCr %vreg3, %vreg1, %pred:12, pred:%CPSR Becomes a predicated SUBri with a tied imp-use: SUBri %vreg1, -2147483647, pred:13, pred:%CPSR, opt:%noreg, %vreg1 This means that any instruction that is safe to move can be folded into a MOVCC, and the *CC pseudo-instructions are no longer needed. The test case changes reflect that Thumb2SizeReduce recognizes the predicated instructions. It didn't understand the pseudos. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163274 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 87 +++++++++++++------------------------ 1 file changed, 31 insertions(+), 56 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index f8e554f..10c41ee 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1580,16 +1580,20 @@ ARMBaseInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const { } /// Identify instructions that can be folded into a MOVCC instruction, and -/// return the corresponding opcode for the predicated pseudo-instruction. -static unsigned canFoldIntoMOVCC(unsigned Reg, MachineInstr *&MI, - const MachineRegisterInfo &MRI) { +/// return the defining instruction. +static MachineInstr *canFoldIntoMOVCC(unsigned Reg, + const MachineRegisterInfo &MRI, + const TargetInstrInfo *TII) { if (!TargetRegisterInfo::isVirtualRegister(Reg)) return 0; if (!MRI.hasOneNonDBGUse(Reg)) return 0; - MI = MRI.getVRegDef(Reg); + MachineInstr *MI = MRI.getVRegDef(Reg); if (!MI) return 0; + // MI is folded into the MOVCC by predicating it. + if (!MI->isPredicable()) + return 0; // Check if MI has any non-dead defs or physreg uses. This also detects // predicated instructions which will be reading CPSR. for (unsigned i = 1, e = MI->getNumOperands(); i != e; ++i) { @@ -1599,55 +1603,18 @@ static unsigned canFoldIntoMOVCC(unsigned Reg, MachineInstr *&MI, return 0; if (!MO.isReg()) continue; + // MI can't have any tied operands, that would conflict with predication. + if (MO.isTied()) + return 0; if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) return 0; if (MO.isDef() && !MO.isDead()) return 0; } - switch (MI->getOpcode()) { - default: return 0; - case ARM::ANDri: return ARM::ANDCCri; - case ARM::ANDrr: return ARM::ANDCCrr; - case ARM::ANDrsi: return ARM::ANDCCrsi; - case ARM::ANDrsr: return ARM::ANDCCrsr; - case ARM::t2ANDri: return ARM::t2ANDCCri; - case ARM::t2ANDrr: return ARM::t2ANDCCrr; - case ARM::t2ANDrs: return ARM::t2ANDCCrs; - case ARM::EORri: return ARM::EORCCri; - case ARM::EORrr: return ARM::EORCCrr; - case ARM::EORrsi: return ARM::EORCCrsi; - case ARM::EORrsr: return ARM::EORCCrsr; - case ARM::t2EORri: return ARM::t2EORCCri; - case ARM::t2EORrr: return ARM::t2EORCCrr; - case ARM::t2EORrs: return ARM::t2EORCCrs; - case ARM::ORRri: return ARM::ORRCCri; - case ARM::ORRrr: return ARM::ORRCCrr; - case ARM::ORRrsi: return ARM::ORRCCrsi; - case ARM::ORRrsr: return ARM::ORRCCrsr; - case ARM::t2ORRri: return ARM::t2ORRCCri; - case ARM::t2ORRrr: return ARM::t2ORRCCrr; - case ARM::t2ORRrs: return ARM::t2ORRCCrs; - - // ARM ADD/SUB - case ARM::ADDri: return ARM::ADDCCri; - case ARM::ADDrr: return ARM::ADDCCrr; - case ARM::ADDrsi: return ARM::ADDCCrsi; - case ARM::ADDrsr: return ARM::ADDCCrsr; - case ARM::SUBri: return ARM::SUBCCri; - case ARM::SUBrr: return ARM::SUBCCrr; - case ARM::SUBrsi: return ARM::SUBCCrsi; - case ARM::SUBrsr: return ARM::SUBCCrsr; - - // Thumb2 ADD/SUB - case ARM::t2ADDri: return ARM::t2ADDCCri; - case ARM::t2ADDri12: return ARM::t2ADDCCri12; - case ARM::t2ADDrr: return ARM::t2ADDCCrr; - case ARM::t2ADDrs: return ARM::t2ADDCCrs; - case ARM::t2SUBri: return ARM::t2SUBCCri; - case ARM::t2SUBri12: return ARM::t2SUBCCri12; - case ARM::t2SUBrr: return ARM::t2SUBCCrr; - case ARM::t2SUBrs: return ARM::t2SUBCCrs; - } + bool DontMoveAcrossStores = true; + if (!MI->isSafeToMove(TII, /* AliasAnalysis = */ 0, DontMoveAcrossStores)) + return 0; + return MI; } bool ARMBaseInstrInfo::analyzeSelect(const MachineInstr *MI, @@ -1676,19 +1643,18 @@ MachineInstr *ARMBaseInstrInfo::optimizeSelect(MachineInstr *MI, assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) && "Unknown select instruction"); const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo(); - MachineInstr *DefMI = 0; - unsigned Opc = canFoldIntoMOVCC(MI->getOperand(2).getReg(), DefMI, MRI); - bool Invert = !Opc; - if (!Opc) - Opc = canFoldIntoMOVCC(MI->getOperand(1).getReg(), DefMI, MRI); - if (!Opc) + MachineInstr *DefMI = canFoldIntoMOVCC(MI->getOperand(2).getReg(), MRI, this); + bool Invert = !DefMI; + if (!DefMI) + DefMI = canFoldIntoMOVCC(MI->getOperand(1).getReg(), MRI, this); + if (!DefMI) return 0; // Create a new predicated version of DefMI. // Rfalse is the first use. MachineInstrBuilder NewMI = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), - get(Opc), MI->getOperand(0).getReg()) - .addOperand(MI->getOperand(Invert ? 2 : 1)); + DefMI->getDesc(), + MI->getOperand(0).getReg()); // Copy all the DefMI operands, excluding its (null) predicate. const MCInstrDesc &DefDesc = DefMI->getDesc(); @@ -1707,6 +1673,15 @@ MachineInstr *ARMBaseInstrInfo::optimizeSelect(MachineInstr *MI, if (NewMI->hasOptionalDef()) AddDefaultCC(NewMI); + // The output register value when the predicate is false is an implicit + // register operand tied to the first def. + // The tie makes the register allocator ensure the FalseReg is allocated the + // same register as operand 0. + MachineOperand FalseReg = MI->getOperand(Invert ? 2 : 1); + FalseReg.setImplicit(); + NewMI->addOperand(FalseReg); + NewMI->tieOperands(0, NewMI->getNumOperands() - 1); + // The caller will erase MI, but not DefMI. DefMI->eraseFromParent(); return NewMI; -- cgit v1.1 From f632d80e0c83248909b2dbbe2decef7de84718f9 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 5 Sep 2012 23:58:04 +0000 Subject: Remove predicated pseudo-instructions. These pseudos are no longer needed now that it is possible to represent predicated instructions in SSA form. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163275 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 42 ----------------------------- lib/Target/ARM/ARMInstrThumb2.td | 58 ---------------------------------------- 2 files changed, 100 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index e6e6d27..e23989e 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -4016,48 +4016,6 @@ def MVNCCi : ARMPseudoInst<(outs GPR:$Rd), [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>, RegConstraint<"$false = $Rd">; -// Conditional instructions -multiclass AsI1_bincc_irs { - def ri : ARMPseudoExpand<(outs GPR:$Rd), - (ins GPR:$Rfalse, GPR:$Rn, so_imm:$imm, - pred:$p, cc_out:$s), - 4, iii, [], - (iri GPR:$Rd, GPR:$Rn, so_imm:$imm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; - def rr : ARMPseudoExpand<(outs GPR:$Rd), - (ins GPR:$Rfalse, GPR:$Rn, GPR:$Rm, - pred:$p, cc_out:$s), - 4, iir, [], - (irr GPR:$Rd, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; - def rsi : ARMPseudoExpand<(outs GPR:$Rd), - (ins GPR:$Rfalse, GPR:$Rn, so_reg_imm:$shift, - pred:$p, cc_out:$s), - 4, iis, [], - (irsi GPR:$Rd, GPR:$Rn, so_reg_imm:$shift, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; - def rsr : ARMPseudoExpand<(outs GPRnopc:$Rd), - (ins GPRnopc:$Rfalse, GPRnopc:$Rn, so_reg_reg:$shift, - pred:$p, cc_out:$s), - 4, iis, [], - (irsr GPR:$Rd, GPR:$Rn, so_reg_reg:$shift, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; -} - -defm ANDCC : AsI1_bincc_irs; -defm ORRCC : AsI1_bincc_irs; -defm EORCC : AsI1_bincc_irs; -defm ADDCC : AsI1_bincc_irs; -defm SUBCC : AsI1_bincc_irs; - } // neverHasSideEffects diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 6b0e6e5..f1a6cce 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -774,33 +774,6 @@ multiclass T2I_bin_ii12rs op23_21, string opc, PatFrag opnode, let Inst{24} = 1; let Inst{23-21} = op23_21; } - - // Predicated versions. - def CCri : t2PseudoExpand<(outs GPRnopc:$Rd), - (ins GPRnopc:$Rfalse, GPRnopc:$Rn, t2_so_imm:$imm, - pred:$p, cc_out:$s), 4, IIC_iALUi, [], - (!cast(NAME#ri) GPRnopc:$Rd, - GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; - def CCri12 : t2PseudoExpand<(outs GPRnopc:$Rd), - (ins GPRnopc:$Rfalse, GPR:$Rn, imm0_4095:$imm, - pred:$p), - 4, IIC_iALUi, [], - (!cast(NAME#ri12) GPRnopc:$Rd, - GPR:$Rn, imm0_4095:$imm, pred:$p)>, - RegConstraint<"$Rfalse = $Rd">; - def CCrr : t2PseudoExpand<(outs GPRnopc:$Rd), - (ins GPRnopc:$Rfalse, GPRnopc:$Rn, rGPR:$Rm, - pred:$p, cc_out:$s), 4, IIC_iALUr, [], - (!cast(NAME#rr) GPRnopc:$Rd, - GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; - def CCrs : t2PseudoExpand<(outs GPRnopc:$Rd), - (ins GPRnopc:$Rfalse, GPRnopc:$Rn, t2_so_reg:$Rm, - pred:$p, cc_out:$s), 4, IIC_iALUsi, [], - (!cast(NAME#rs) GPRnopc:$Rd, - GPRnopc:$Rn, t2_so_reg:$Rm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; } /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns @@ -3069,37 +3042,6 @@ def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd), RegConstraint<"$false = $Rd">; } // isCodeGenOnly = 1 -multiclass T2I_bincc_irs { - // shifted imm - def ri : t2PseudoExpand<(outs rGPR:$Rd), - (ins rGPR:$Rfalse, rGPR:$Rn, t2_so_imm:$imm, - pred:$p, cc_out:$s), - 4, iii, [], - (iri rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; - // register - def rr : t2PseudoExpand<(outs rGPR:$Rd), - (ins rGPR:$Rfalse, rGPR:$Rn, rGPR:$Rm, - pred:$p, cc_out:$s), - 4, iir, [], - (irr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; - // shifted register - def rs : t2PseudoExpand<(outs rGPR:$Rd), - (ins rGPR:$Rfalse, rGPR:$Rn, t2_so_reg:$ShiftedRm, - pred:$p, cc_out:$s), - 4, iis, [], - (irs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rfalse = $Rd">; -} // T2I_bincc_irs - -defm t2ANDCC : T2I_bincc_irs; -defm t2ORRCC : T2I_bincc_irs; -defm t2EORCC : T2I_bincc_irs; } // neverHasSideEffects //===----------------------------------------------------------------------===// -- cgit v1.1 From 6c822eea47dbef96940819b1ea085fabc49a1e71 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Thu, 6 Sep 2012 09:16:01 +0000 Subject: Optimize codegen for VSETLNi{8,16,32} operating on Q registers. Degenerate to a VSETLN on D registers, instead of an (INSERT_SUBREG (VSETLN (EXTRACT_SUBREG ))) sequence to help the register coalescer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163298 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMExpandPseudoInsts.cpp | 51 +++++++++++++++++++++++++++++++++ lib/Target/ARM/ARMInstrNEON.td | 32 ++++++++++----------- 2 files changed, 66 insertions(+), 17 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 15bb32e..8ed6b75 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -1208,6 +1208,57 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, ExpandLaneOp(MBBI); return true; + case ARM::VSETLNi8Q: + case ARM::VSETLNi16Q: { + // Expand VSETLNs acting on a Q register to equivalent VSETLNs acting + // on the respective D register. + + unsigned QReg = MI.getOperand(1).getReg(); + unsigned QLane = MI.getOperand(3).getImm(); + + unsigned NewOpcode, DLane, DSubReg; + switch (Opcode) { + default: llvm_unreachable("Invalid opcode!"); + case ARM::VSETLNi8Q: + // 4 possible 8-bit lanes per DPR: + NewOpcode = ARM::VSETLNi8; + DLane = QLane % 8; + DSubReg = (QLane / 8) ? ARM::dsub_1 : ARM::dsub_0; + break; + case ARM::VSETLNi16Q: + // 4 possible 16-bit lanes per DPR. + NewOpcode = ARM::VSETLNi16; + DLane = QLane % 4; + DSubReg = (QLane / 4) ? ARM::dsub_1 : ARM::dsub_0; + break; + } + + MachineInstrBuilder MIB = + BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpcode)); + + unsigned DReg = TRI->getSubReg(QReg, DSubReg); + + MIB.addReg(DReg, RegState::Define); // Output DPR + MIB.addReg(DReg); // Input DPR + MIB.addOperand(MI.getOperand(2)); // Input GPR + MIB.addImm(DLane); // Lane + + // Add the predicate operands. + MIB.addOperand(MI.getOperand(4)); + MIB.addOperand(MI.getOperand(5)); + + if (MI.getOperand(1).isKill()) // Add an implicit kill for the Q register. + MIB->addRegisterKilled(QReg, TRI, true); + // And an implicit def of the output register (which should always be the + // same as the input register). + MIB->addRegisterDefined(QReg, TRI); + + TransferImpOps(MI, MIB, MIB); + + MI.eraseFromParent(); + return true; + } + case ARM::VTBL3Pseudo: ExpandVTBL(MBBI, ARM::VTBL3, false); return true; case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false); return true; case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true; diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 048d340..c5f3a83 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -5045,25 +5045,23 @@ def VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$V), GPR:$R, imm:$lane))]> { let Inst{21} = lane{0}; } + +def VSETLNi8Q : PseudoNeonI<(outs QPR:$V), + (ins QPR:$src1, GPR:$R, VectorIndex8:$lane), + IIC_VMOVISL, "", + [(set QPR:$V, (vector_insert (v16i8 QPR:$src1), + GPR:$R, imm:$lane))]>; +def VSETLNi16Q : PseudoNeonI<(outs QPR:$V), + (ins QPR:$src1, GPR:$R, VectorIndex16:$lane), + IIC_VMOVISL, "", + [(set QPR:$V, (vector_insert (v8i16 QPR:$src1), + GPR:$R, imm:$lane))]>; } -def : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane), - (v16i8 (INSERT_SUBREG QPR:$src1, - (v8i8 (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1, - (DSubReg_i8_reg imm:$lane))), - GPR:$src2, (SubReg_i8_lane imm:$lane))), - (DSubReg_i8_reg imm:$lane)))>; -def : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane), - (v8i16 (INSERT_SUBREG QPR:$src1, - (v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1, - (DSubReg_i16_reg imm:$lane))), - GPR:$src2, (SubReg_i16_lane imm:$lane))), - (DSubReg_i16_reg imm:$lane)))>; + def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane), - (v4i32 (INSERT_SUBREG QPR:$src1, - (v2i32 (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1, - (DSubReg_i32_reg imm:$lane))), - GPR:$src2, (SubReg_i32_lane imm:$lane))), - (DSubReg_i32_reg imm:$lane)))>; + (v4i32 (INSERT_SUBREG QPR:$src1, + GPR:$src2, + (SSubReg_f32_reg imm:$lane)))>; def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)), (INSERT_SUBREG (v2f32 (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2)), -- cgit v1.1 From ba8562af4440753ba6175ccd54d71f79f5c4f3dc Mon Sep 17 00:00:00 2001 From: James Molloy Date: Thu, 6 Sep 2012 09:55:02 +0000 Subject: Improve codegen for BUILD_VECTORs on ARM. If we have a BUILD_VECTOR that is mostly a constant splat, it is often better to splat that constant then insertelement the non-constant lanes instead of insertelementing every lane from an undef base. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163304 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 66 ++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 10 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index c17e9ae..62c7589 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -4161,10 +4161,21 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG, } // Scan through the operands to see if only one value is used. + // + // As an optimisation, even if more than one value is used it may be more + // profitable to splat with one value then change some lanes. + // + // Heuristically we decide to do this if the vector has a "dominant" value, + // defined as splatted to more than half of the lanes. unsigned NumElts = VT.getVectorNumElements(); bool isOnlyLowElement = true; bool usesOnlyOneValue = true; + bool hasDominantValue = false; bool isConstant = true; + + // Map of the number of times a particular SDValue appears in the + // element list. + DenseMap ValueCounts; SDValue Value; for (unsigned i = 0; i < NumElts; ++i) { SDValue V = Op.getOperand(i); @@ -4175,13 +4186,21 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG, if (!isa(V) && !isa(V)) isConstant = false; - if (!Value.getNode()) + ValueCounts.insert(std::make_pair(V, 0)); + int &Count = ValueCounts[V]; + + // Is this value dominant? (takes up more than half of the lanes) + if (++Count > (NumElts / 2)) { + hasDominantValue = true; Value = V; - else if (V != Value) - usesOnlyOneValue = false; + } } + if (ValueCounts.size() != 1) + usesOnlyOneValue = false; + if (!Value.getNode() && ValueCounts.size() > 0) + Value = ValueCounts.begin()->first; - if (!Value.getNode()) + if (ValueCounts.size() == 0) return DAG.getUNDEF(VT); if (isOnlyLowElement) @@ -4191,9 +4210,34 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG, // Use VDUP for non-constant splats. For f32 constant splats, reduce to // i32 and try again. - if (usesOnlyOneValue && EltSize <= 32) { - if (!isConstant) - return DAG.getNode(ARMISD::VDUP, dl, VT, Value); + if (hasDominantValue && EltSize <= 32) { + if (!isConstant) { + SDValue N; + + // If we are VDUPing a value that comes directly from a vector, that will + // cause an unnecessary move to and from a GPR, where instead we could + // just use VDUPLANE. + if (Value->getOpcode() == ISD::EXTRACT_VECTOR_ELT) + N = DAG.getNode(ARMISD::VDUPLANE, dl, VT, + Value->getOperand(0), Value->getOperand(1)); + else + N = DAG.getNode(ARMISD::VDUP, dl, VT, Value); + + if (!usesOnlyOneValue) { + // The dominant value was splatted as 'N', but we now have to insert + // all differing elements. + for (unsigned I = 0; I < NumElts; ++I) { + if (Op.getOperand(I) == Value) + continue; + SmallVector Ops; + Ops.push_back(N); + Ops.push_back(Op.getOperand(I)); + Ops.push_back(DAG.getConstant(I, MVT::i32)); + N = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, &Ops[0], 3); + } + } + return N; + } if (VT.getVectorElementType().isFloatingPoint()) { SmallVector Ops; for (unsigned i = 0; i < NumElts; ++i) @@ -4205,9 +4249,11 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG, if (Val.getNode()) return DAG.getNode(ISD::BITCAST, dl, VT, Val); } - SDValue Val = IsSingleInstrConstant(Value, DAG, ST, dl); - if (Val.getNode()) - return DAG.getNode(ARMISD::VDUP, dl, VT, Val); + if (usesOnlyOneValue) { + SDValue Val = IsSingleInstrConstant(Value, DAG, ST, dl); + if (isConstant && Val.getNode()) + return DAG.getNode(ARMISD::VDUP, dl, VT, Val); + } } // If all elements are constants and the case above didn't get hit, fall back -- cgit v1.1 From 951543491fcc01486a926f0dcb37815ffff2051f Mon Sep 17 00:00:00 2001 From: James Molloy Date: Thu, 6 Sep 2012 10:32:08 +0000 Subject: Fix self-host; ensure signedness is consistent. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163306 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 62c7589..5f3a9c7 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -4175,7 +4175,7 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG, // Map of the number of times a particular SDValue appears in the // element list. - DenseMap ValueCounts; + DenseMap ValueCounts; SDValue Value; for (unsigned i = 0; i < NumElts; ++i) { SDValue V = Op.getOperand(i); @@ -4187,7 +4187,7 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG, isConstant = false; ValueCounts.insert(std::make_pair(V, 0)); - int &Count = ValueCounts[V]; + unsigned &Count = ValueCounts[V]; // Is this value dominant? (takes up more than half of the lanes) if (++Count > (NumElts / 2)) { -- cgit v1.1 From e757640df0615510dbc42921cf6271aa76c405ee Mon Sep 17 00:00:00 2001 From: Nadav Rotem Date: Thu, 6 Sep 2012 11:13:55 +0000 Subject: Fix a few old-GCC warnings. No functional change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163309 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 9849cb5..045d904 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -2642,7 +2642,7 @@ bool ARMFastISel::SelectShift(const Instruction *I, unsigned Reg1 = getRegForValue(Src1Value); if (Reg1 == 0) return false; - unsigned Reg2; + unsigned Reg2 = 0; if (Opc == ARM::MOVsr) { Reg2 = getRegForValue(Src2Value); if (Reg2 == 0) return false; -- cgit v1.1 From 64eacd9136dc45e54dd2728117f71403701fd39c Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 6 Sep 2012 14:36:55 +0000 Subject: Use correct part of complex operand to encode VST1 alignment. Patch by Chris Lidbury. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163318 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrNEON.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index c5f3a83..8158a11 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -1980,7 +1980,7 @@ def VST1LNd8 : VST1LN<0b0000, {?,?,?,0}, "8", v8i8, truncstorei8, def VST1LNd16 : VST1LN<0b0100, {?,?,0,?}, "16", v4i16, truncstorei16, NEONvgetlaneu, addrmode6> { let Inst{7-6} = lane{1-0}; - let Inst{4} = Rn{5}; + let Inst{4} = Rn{4}; } def VST1LNd32 : VST1LN<0b1000, {?,0,?,?}, "32", v2i32, store, extractelt, @@ -2023,7 +2023,7 @@ def VST1LNd8_UPD : VST1LNWB<0b0000, {?,?,?,0}, "8", v8i8, post_truncsti8, def VST1LNd16_UPD : VST1LNWB<0b0100, {?,?,0,?}, "16", v4i16, post_truncsti16, NEONvgetlaneu, addrmode6> { let Inst{7-6} = lane{1-0}; - let Inst{4} = Rn{5}; + let Inst{4} = Rn{4}; } def VST1LNd32_UPD : VST1LNWB<0b1000, {?,0,?,?}, "32", v2i32, post_store, extractelt, addrmode6oneL32> { -- cgit v1.1 From eae1d34029c159306ce4a0472294de6cf9baedac Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 6 Sep 2012 15:17:49 +0000 Subject: Check for invalid alignment values when decoding VLDn/VSTn (single ln) instructions. Patch by Chris Lidbury. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163321 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 46 ++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index c394ed1..657c103 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -3710,8 +3710,16 @@ static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, if (fieldFromInstruction(Insn, 6, 1)) return MCDisassembler::Fail; // UNDEFINED index = fieldFromInstruction(Insn, 7, 1); - if (fieldFromInstruction(Insn, 4, 2) != 0) - align = 4; + + switch (fieldFromInstruction(Insn, 4, 2)) { + case 0 : + align = 0; break; + case 3: + align = 4; break; + default: + return MCDisassembler::Fail; + } + break; } if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) @@ -3769,8 +3777,16 @@ static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, if (fieldFromInstruction(Insn, 6, 1)) return MCDisassembler::Fail; // UNDEFINED index = fieldFromInstruction(Insn, 7, 1); - if (fieldFromInstruction(Insn, 4, 2) != 0) - align = 4; + + switch (fieldFromInstruction(Insn, 4, 2)) { + case 0: + align = 0; break; + case 3: + align = 4; break; + default: + return MCDisassembler::Fail; + } + break; } if (Rm != 0xF) { // Writeback @@ -4090,8 +4106,15 @@ static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, inc = 2; break; case 2: - if (fieldFromInstruction(Insn, 4, 2)) - align = 4 << fieldFromInstruction(Insn, 4, 2); + switch (fieldFromInstruction(Insn, 4, 2)) { + case 0: + align = 0; break; + case 3: + return MCDisassembler::Fail; + default: + align = 4 << fieldFromInstruction(Insn, 4, 2); break; + } + index = fieldFromInstruction(Insn, 7, 1); if (fieldFromInstruction(Insn, 6, 1)) inc = 2; @@ -4164,8 +4187,15 @@ static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, inc = 2; break; case 2: - if (fieldFromInstruction(Insn, 4, 2)) - align = 4 << fieldFromInstruction(Insn, 4, 2); + switch (fieldFromInstruction(Insn, 4, 2)) { + case 0: + align = 0; break; + case 3: + return MCDisassembler::Fail; + default: + align = 4 << fieldFromInstruction(Insn, 4, 2); break; + } + index = fieldFromInstruction(Insn, 7, 1); if (fieldFromInstruction(Insn, 6, 1)) inc = 2; -- cgit v1.1 From 24b9f258f194c5e472bf133f9bbf5ca26ad500d3 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 6 Sep 2012 15:27:12 +0000 Subject: Diagnose invalid alignments on duplicating VLDn instructions. Patch by Chris Lidbury. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163323 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 657c103..57642e1 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -2701,6 +2701,8 @@ static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn, unsigned align = fieldFromInstruction(Insn, 4, 1); unsigned size = fieldFromInstruction(Insn, 6, 2); + if (size == 0 && align == 1) + return MCDisassembler::Fail; align *= (1 << size); switch (Inst.getOpcode()) { @@ -2831,6 +2833,8 @@ static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn, unsigned align = fieldFromInstruction(Insn, 4, 1); if (size == 0x3) { + if (align == 0) + return MCDisassembler::Fail; size = 4; align = 16; } else { -- cgit v1.1 From 39646d96e76aea5d20bffb386233a0dbb5932a21 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 7 Sep 2012 17:25:13 +0000 Subject: MC: Overhaul handling of .lcomm - Darwin lied about not supporting .lcomm and turned it into zerofill in the asm parser. Push the zerofill-conversion down into macho-specific code. - This makes the tri-state LCOMMType enum superfluous, there are no targets without .lcomm. - Do proper error reporting when trying to use .lcomm with alignment on a target that doesn't support it. - .comm and .lcomm alignment was parsed in bytes on COFF, should be power of 2. - Fixes PR13755 (.lcomm crashes on ELF). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163395 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp index d32805e..c1aab9c 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -50,7 +50,6 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo() { Code32Directive = ".code\t32"; WeakRefDirective = "\t.weak\t"; - LCOMMDirectiveType = LCOMM::NoAlignment; HasLEB128 = true; SupportsDebugInformation = true; -- cgit v1.1 From a7390fadbaa8da49649d76786555c93bcb680de6 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 7 Sep 2012 17:34:15 +0000 Subject: Custom DAGCombine for and/or/xor are for all ARMs. The 'select' transformations apply to all ARM architectures and don't require hasV6T2Ops. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163396 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 5f3a9c7..29ca8ea 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -796,12 +796,9 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setTargetDAGCombine(ISD::ADD); setTargetDAGCombine(ISD::SUB); setTargetDAGCombine(ISD::MUL); - - if (Subtarget->hasV6T2Ops() || Subtarget->hasNEON()) { - setTargetDAGCombine(ISD::AND); - setTargetDAGCombine(ISD::OR); - setTargetDAGCombine(ISD::XOR); - } + setTargetDAGCombine(ISD::AND); + setTargetDAGCombine(ISD::OR); + setTargetDAGCombine(ISD::XOR); if (Subtarget->hasV6Ops()) setTargetDAGCombine(ISD::SRL); -- cgit v1.1 From a1fb1d2ed7342c7e6b491a78af073b5320bc9867 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sat, 8 Sep 2012 04:58:43 +0000 Subject: Set operation action for FFLOOR to Expand for all vector types for X86. Set FFLOOR of v4f32 to Expand for ARM. v2f64 was already correct. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163458 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 29ca8ea..e51315e 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -514,6 +514,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::FLOG10, MVT::v4f32, Expand); setOperationAction(ISD::FEXP, MVT::v4f32, Expand); setOperationAction(ISD::FEXP2, MVT::v4f32, Expand); + setOperationAction(ISD::FFLOOR, MVT::v4f32, Expand); // Neon does not support some operations on v1i64 and v2i64 types. setOperationAction(ISD::MUL, MVT::v1i64, Expand); -- cgit v1.1 From 519daf5d2dd80614ac4e529b199e6f3e595bfc80 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 10 Sep 2012 19:17:25 +0000 Subject: Don't attempt to use flags from predicated instructions. The ARM backend can eliminate cmp instructions by reusing flags from a nearby sub instruction with similar arguments. Don't do that if the sub is predicated - the flags are not written unconditionally. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163535 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 10c41ee..e2f0d7d 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2028,13 +2028,14 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, // Masked compares sometimes use the same register as the corresponding 'and'. if (CmpMask != ~0) { - if (!isSuitableForMask(MI, SrcReg, CmpMask, false)) { + if (!isSuitableForMask(MI, SrcReg, CmpMask, false) || isPredicated(MI)) { MI = 0; for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg), UE = MRI->use_end(); UI != UE; ++UI) { if (UI->getParent() != CmpInstr->getParent()) continue; MachineInstr *PotentialAND = &*UI; - if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true)) + if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true) || + isPredicated(PotentialAND)) continue; MI = PotentialAND; break; @@ -2100,6 +2101,10 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, // The single candidate is called MI. if (!MI) MI = Sub; + // We can't use a predicated instruction - it doesn't always write the flags. + if (isPredicated(MI)) + return false; + switch (MI->getOpcode()) { default: break; case ARM::RSBrr: @@ -2206,6 +2211,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, // Toggle the optional operand to CPSR. MI->getOperand(5).setReg(ARM::CPSR); MI->getOperand(5).setIsDef(true); + assert(!isPredicated(MI) && "Can't use flags from predicated instruction"); CmpInstr->eraseFromParent(); // Modify the condition code of operands in OperandsToUpdate. -- cgit v1.1 From 2de0572caec55e3779857cae0bbcd962af2e495d Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Mon, 10 Sep 2012 21:26:47 +0000 Subject: Remove redundant semicolons which are null statements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163547 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Target/ARM') diff --git a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp index a51e0fa..95640f7 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -410,7 +410,7 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer, if (Type == macho::RIT_ARM_Half) { // The other-half value only gets populated for the movt and movw // relocation entries. - uint32_t Value = 0;; + uint32_t Value = 0; switch ((unsigned)Fixup.getKind()) { default: break; case ARM::fixup_arm_movw_lo16: -- cgit v1.1