Author: joerg Date: Thu Sep 28 07:13:54 2017 New Revision: 314417 URL: http://llvm.org/viewvc/llvm-project?rev=314417&view=rev Log: Merging r311921: ------------------------------------------------------------------------ r311921 | joerg | 2017-08-28 22:20:47 +0200 (Mon, 28 Aug 2017) | 16 lines
Fix ARMv4 support ARMv4 doesn't support the "BX" instruction, which has been introduced with ARMv4t. Adjust the call lowering and tail call implementation accordingly. Further changes are necessary to ensure that presence of the v4t feature is correctly set. Most importantly, the "generic" CPU for thumb-* triples should include ARMv4t, since thumb mode without thumb support would naturally be pointless. Add a couple of asserts to ensure thumb instructions are not emitted without CPU support. Differential Revision: https://reviews.llvm.org/D37030 ------------------------------------------------------------------------ Modified: llvm/branches/release_50/lib/Target/ARM/ARMAsmPrinter.cpp llvm/branches/release_50/lib/Target/ARM/ARMCallLowering.cpp llvm/branches/release_50/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/branches/release_50/lib/Target/ARM/ARMFastISel.cpp llvm/branches/release_50/lib/Target/ARM/ARMFrameLowering.cpp llvm/branches/release_50/lib/Target/ARM/ARMInstrInfo.td llvm/branches/release_50/lib/Target/ARM/ARMLoadStoreOptimizer.cpp llvm/branches/release_50/lib/Target/ARM/ARMSubtarget.h llvm/branches/release_50/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp llvm/branches/release_50/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll llvm/branches/release_50/test/CodeGen/ARM/armv4.ll llvm/branches/release_50/test/CodeGen/ARM/debug-segmented-stacks.ll llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks-dynamic.ll llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks.ll Modified: llvm/branches/release_50/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/ARMAsmPrinter.cpp?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/branches/release_50/lib/Target/ARM/ARMAsmPrinter.cpp Thu Sep 28 07:13:54 2017 @@ -1276,6 +1276,7 @@ void ARMAsmPrinter::EmitInstruction(cons // Add 's' bit operand (always reg0 for this) .addReg(0)); + assert(Subtarget->hasV4TOps()); EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX) .addReg(MI->getOperand(0).getReg())); return; @@ -1896,6 +1897,7 @@ void ARMAsmPrinter::EmitInstruction(cons .addImm(ARMCC::AL) .addReg(0)); + assert(Subtarget->hasV4TOps()); EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX) .addReg(ScratchReg) // Predicate. Modified: llvm/branches/release_50/lib/Target/ARM/ARMCallLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/ARMCallLowering.cpp?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/ARMCallLowering.cpp (original) +++ llvm/branches/release_50/lib/Target/ARM/ARMCallLowering.cpp Thu Sep 28 07:13:54 2017 @@ -251,7 +251,9 @@ bool ARMCallLowering::lowerReturn(Machin const Value *Val, unsigned VReg) const { assert(!Val == !VReg && "Return value without a vreg"); - auto Ret = MIRBuilder.buildInstrNoInsert(ARM::BX_RET).add(predOps(ARMCC::AL)); + auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>(); + unsigned Opcode = ST.getReturnOpcode(); + auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL)); if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret)) return false; Modified: llvm/branches/release_50/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/branches/release_50/lib/Target/ARM/ARMExpandPseudoInsts.cpp Thu Sep 28 07:13:54 2017 @@ -1030,8 +1030,11 @@ bool ARMExpandPseudo::ExpandMI(MachineBa if (STI->isThumb()) MIB.add(predOps(ARMCC::AL)); } else if (RetOpcode == ARM::TCRETURNri) { + unsigned Opcode = + STI->isThumb() ? ARM::tTAILJMPr + : (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4); BuildMI(MBB, MBBI, dl, - TII.get(STI->isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)) + TII.get(Opcode)) .addReg(JumpTarget.getReg(), RegState::Kill); } Modified: llvm/branches/release_50/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/ARMFastISel.cpp?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/branches/release_50/lib/Target/ARM/ARMFastISel.cpp Thu Sep 28 07:13:54 2017 @@ -1332,6 +1332,8 @@ bool ARMFastISel::SelectIndirectBr(const if (AddrReg == 0) return false; unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX; + assert(isThumb2 || Subtarget->hasV4TOps()); + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)).addReg(AddrReg)); @@ -2168,9 +2170,8 @@ bool ARMFastISel::SelectRet(const Instru RetRegs.push_back(VA.getLocReg()); } - unsigned RetOpc = isThumb2 ? ARM::tBX_RET : ARM::BX_RET; MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, - TII.get(RetOpc)); + TII.get(Subtarget->getReturnOpcode())); AddOptionalDefs(MIB); for (unsigned R : RetRegs) MIB.addReg(R, RegState::Implicit); Modified: llvm/branches/release_50/lib/Target/ARM/ARMFrameLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/ARMFrameLowering.cpp?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/ARMFrameLowering.cpp (original) +++ llvm/branches/release_50/lib/Target/ARM/ARMFrameLowering.cpp Thu Sep 28 07:13:54 2017 @@ -2397,9 +2397,8 @@ void ARMFrameLowering::adjustForSegmente BuildMI(AllocMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); - // bx lr - Return from this function. - Opcode = Thumb ? ARM::tBX_RET : ARM::BX_RET; - BuildMI(AllocMBB, DL, TII.get(Opcode)).add(predOps(ARMCC::AL)); + // Return from this function. + BuildMI(AllocMBB, DL, TII.get(ST->getReturnOpcode())).add(predOps(ARMCC::AL)); // Restore SR0 and SR1 in case of __morestack() was not called. // pop {SR0, SR1} Modified: llvm/branches/release_50/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/ARMInstrInfo.td?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/branches/release_50/lib/Target/ARM/ARMInstrInfo.td Thu Sep 28 07:13:54 2017 @@ -2425,7 +2425,7 @@ let isCall = 1, isTerminator = 1, isRetu def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst), 4, IIC_Br, [], (BX GPR:$dst)>, Sched<[WriteBr]>, - Requires<[IsARM]>; + Requires<[IsARM, HasV4T]>; } // Secure Monitor Call is a system instruction. @@ -5589,6 +5589,12 @@ let isBranch = 1, isTerminator = 1, isBa (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in + def TAILJMPr4 : ARMPseudoExpand<(outs), (ins GPR:$dst), + 4, IIC_Br, [], + (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, + Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; + // Large immediate handling. // 32-bit immediate using two piece mod_imms or movw + movt. Modified: llvm/branches/release_50/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/branches/release_50/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Thu Sep 28 07:13:54 2017 @@ -1909,6 +1909,7 @@ bool ARMLoadStoreOpt::CombineMovBx(Machi for (auto Use : Prev->uses()) if (Use.isKill()) { + assert(STI->hasV4TOps()); BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(ARM::tBX)) .addReg(Use.getReg(), RegState::Kill) .add(predOps(ARMCC::AL)) Modified: llvm/branches/release_50/lib/Target/ARM/ARMSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/ARMSubtarget.h?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/ARMSubtarget.h (original) +++ llvm/branches/release_50/lib/Target/ARM/ARMSubtarget.h Thu Sep 28 07:13:54 2017 @@ -729,6 +729,17 @@ public: /// True if fast-isel is used. bool useFastISel() const; + + /// Returns the correct return opcode for the current feature set. + /// Use BX if available to allow mixing thumb/arm code, but fall back + /// to plain mov pc,lr on ARMv4. + unsigned getReturnOpcode() const { + if (isThumb()) + return ARM::tBX_RET; + if (hasV4TOps()) + return ARM::BX_RET; + return ARM::MOVPCLR; + } }; } // end namespace llvm Modified: llvm/branches/release_50/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp (original) +++ llvm/branches/release_50/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp Thu Sep 28 07:13:54 2017 @@ -142,9 +142,9 @@ std::string ARM_MC::ParseARMTriple(const if (isThumb) { if (ARMArchFeature.empty()) - ARMArchFeature = "+thumb-mode"; + ARMArchFeature = "+thumb-mode,+v4t"; else - ARMArchFeature += ",+thumb-mode"; + ARMArchFeature += ",+thumb-mode,+v4t"; } if (TT.isOSNaCl()) { Modified: llvm/branches/release_50/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll (original) +++ llvm/branches/release_50/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll Thu Sep 28 07:13:54 2017 @@ -1,5 +1,5 @@ -; RUN: llc -mtriple arm-unknown -mattr=+vfp2 -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE -; RUN: llc -mtriple armeb-unknown -mattr=+vfp2 -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=BIG +; RUN: llc -mtriple arm-unknown -mattr=+vfp2,+v4t -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE +; RUN: llc -mtriple armeb-unknown -mattr=+vfp2,+v4t -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=BIG define void @test_void_return() { ; CHECK-LABEL: name: test_void_return Modified: llvm/branches/release_50/test/CodeGen/ARM/armv4.ll URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/test/CodeGen/ARM/armv4.ll?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/test/CodeGen/ARM/armv4.ll (original) +++ llvm/branches/release_50/test/CodeGen/ARM/armv4.ll Thu Sep 28 07:13:54 2017 @@ -5,9 +5,24 @@ ; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s -check-prefix=ARM ; RUN: llc < %s -mtriple=armv4t-unknown-eabi | FileCheck %s -check-prefix=THUMB -define i32 @test(i32 %a) nounwind readnone { +define i32 @test_return(i32 %a) nounwind readnone { entry: +; ARM-LABEL: test_return ; ARM: mov pc +; THUMB-LABEL: test_return ; THUMB: bx ret i32 %a } + +@helper = global i32 ()* null, align 4 + +define i32 @test_indirect() #0 { +entry: +; ARM-LABEL: test_indirect +; ARM: mov pc +; THUMB-LABEL: test_indirect +; THUMB: bx + %0 = load i32 ()*, i32 ()** @helper, align 4 + %call = tail call i32 %0() + ret i32 %call +} Modified: llvm/branches/release_50/test/CodeGen/ARM/debug-segmented-stacks.ll URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/test/CodeGen/ARM/debug-segmented-stacks.ll?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/test/CodeGen/ARM/debug-segmented-stacks.ll (original) +++ llvm/branches/release_50/test/CodeGen/ARM/debug-segmented-stacks.ll Thu Sep 28 07:13:54 2017 @@ -1,5 +1,5 @@ -; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs -filetype=asm | FileCheck %s -check-prefix=ARM-linux -; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -filetype=obj +; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -verify-machineinstrs -filetype=asm | FileCheck %s -check-prefix=ARM-linux +; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -filetype=obj !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!9, !10} Modified: llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks-dynamic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks-dynamic.ll?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks-dynamic.ll (original) +++ llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks-dynamic.ll Thu Sep 28 07:13:54 2017 @@ -1,7 +1,7 @@ -; RUN: llc < %s -mtriple=arm-linux-androideabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android -; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux -; RUN: llc < %s -mtriple=arm-linux-androideabi -filetype=obj -; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -filetype=obj +; RUN: llc < %s -mtriple=arm-linux-androideabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android +; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux +; RUN: llc < %s -mtriple=arm-linux-androideabi -mattr=+v4t -filetype=obj +; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -filetype=obj ; Just to prevent the alloca from being optimized away declare void @dummy_use(i32*, i32) Modified: llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks.ll URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks.ll?rev=314417&r1=314416&r2=314417&view=diff ============================================================================== --- llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks.ll (original) +++ llvm/branches/release_50/test/CodeGen/ARM/segmented-stacks.ll Thu Sep 28 07:13:54 2017 @@ -1,5 +1,5 @@ -; RUN: llc < %s -mtriple=arm-linux-androideabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android -; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux +; RUN: llc < %s -mtriple=arm-linux-androideabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android +; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux ; We used to crash with filetype=obj ; RUN: llc < %s -mtriple=arm-linux-androideabi -filetype=obj _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits