llvm.org GIT mirror llvm / 43bd69c
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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@314417 91177308-0d34-0410-b5e6-96231b3b80d8 Joerg Sonnenberger 2 years ago
14 changed file(s) with 61 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
12751275 // Add 's' bit operand (always reg0 for this)
12761276 .addReg(0));
12771277
1278 assert(Subtarget->hasV4TOps());
12781279 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
12791280 .addReg(MI->getOperand(0).getReg()));
12801281 return;
18951896 .addImm(ARMCC::AL)
18961897 .addReg(0));
18971898
1899 assert(Subtarget->hasV4TOps());
18981900 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
18991901 .addReg(ScratchReg)
19001902 // Predicate.
250250 const Value *Val, unsigned VReg) const {
251251 assert(!Val == !VReg && "Return value without a vreg");
252252
253 auto Ret = MIRBuilder.buildInstrNoInsert(ARM::BX_RET).add(predOps(ARMCC::AL));
253 auto const &ST = MIRBuilder.getMF().getSubtarget();
254 unsigned Opcode = ST.getReturnOpcode();
255 auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
254256
255257 if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
256258 return false;
10291029 if (STI->isThumb())
10301030 MIB.add(predOps(ARMCC::AL));
10311031 } else if (RetOpcode == ARM::TCRETURNri) {
1032 unsigned Opcode =
1033 STI->isThumb() ? ARM::tTAILJMPr
1034 : (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4);
10321035 BuildMI(MBB, MBBI, dl,
1033 TII.get(STI->isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr))
1036 TII.get(Opcode))
10341037 .addReg(JumpTarget.getReg(), RegState::Kill);
10351038 }
10361039
13311331 if (AddrReg == 0) return false;
13321332
13331333 unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX;
1334 assert(isThumb2 || Subtarget->hasV4TOps());
1335
13341336 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
13351337 TII.get(Opc)).addReg(AddrReg));
13361338
21672169 RetRegs.push_back(VA.getLocReg());
21682170 }
21692171
2170 unsigned RetOpc = isThumb2 ? ARM::tBX_RET : ARM::BX_RET;
21712172 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2172 TII.get(RetOpc));
2173 TII.get(Subtarget->getReturnOpcode()));
21732174 AddOptionalDefs(MIB);
21742175 for (unsigned R : RetRegs)
21752176 MIB.addReg(R, RegState::Implicit);
23962396 BuildMI(AllocMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
23972397 .addCFIIndex(CFIIndex);
23982398
2399 // bx lr - Return from this function.
2400 Opcode = Thumb ? ARM::tBX_RET : ARM::BX_RET;
2401 BuildMI(AllocMBB, DL, TII.get(Opcode)).add(predOps(ARMCC::AL));
2399 // Return from this function.
2400 BuildMI(AllocMBB, DL, TII.get(ST->getReturnOpcode())).add(predOps(ARMCC::AL));
24022401
24032402 // Restore SR0 and SR1 in case of __morestack() was not called.
24042403 // pop {SR0, SR1}
24242424 def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst),
24252425 4, IIC_Br, [],
24262426 (BX GPR:$dst)>, Sched<[WriteBr]>,
2427 Requires<[IsARM]>;
2427 Requires<[IsARM, HasV4T]>;
24282428 }
24292429
24302430 // Secure Monitor Call is a system instruction.
55885588 (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
55895589 Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>;
55905590
5591 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in
5592 def TAILJMPr4 : ARMPseudoExpand<(outs), (ins GPR:$dst),
5593 4, IIC_Br, [],
5594 (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
5595 Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>;
5596
55915597 // Large immediate handling.
55925598
55935599 // 32-bit immediate using two piece mod_imms or movw + movt.
19081908
19091909 for (auto Use : Prev->uses())
19101910 if (Use.isKill()) {
1911 assert(STI->hasV4TOps());
19111912 BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(ARM::tBX))
19121913 .addReg(Use.getReg(), RegState::Kill)
19131914 .add(predOps(ARMCC::AL))
728728
729729 /// True if fast-isel is used.
730730 bool useFastISel() const;
731
732 /// Returns the correct return opcode for the current feature set.
733 /// Use BX if available to allow mixing thumb/arm code, but fall back
734 /// to plain mov pc,lr on ARMv4.
735 unsigned getReturnOpcode() const {
736 if (isThumb())
737 return ARM::tBX_RET;
738 if (hasV4TOps())
739 return ARM::BX_RET;
740 return ARM::MOVPCLR;
741 }
731742 };
732743
733744 } // end namespace llvm
141141
142142 if (isThumb) {
143143 if (ARMArchFeature.empty())
144 ARMArchFeature = "+thumb-mode";
144 ARMArchFeature = "+thumb-mode,+v4t";
145145 else
146 ARMArchFeature += ",+thumb-mode";
146 ARMArchFeature += ",+thumb-mode,+v4t";
147147 }
148148
149149 if (TT.isOSNaCl()) {
None ; RUN: llc -mtriple arm-unknown -mattr=+vfp2 -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE
1 ; RUN: llc -mtriple armeb-unknown -mattr=+vfp2 -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=BIG
0 ; 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
1 ; 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
22
33 define void @test_void_return() {
44 ; CHECK-LABEL: name: test_void_return
44 ; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s -check-prefix=ARM
55 ; RUN: llc < %s -mtriple=armv4t-unknown-eabi | FileCheck %s -check-prefix=THUMB
66
7 define i32 @test(i32 %a) nounwind readnone {
7 define i32 @test_return(i32 %a) nounwind readnone {
88 entry:
9 ; ARM-LABEL: test_return
910 ; ARM: mov pc
11 ; THUMB-LABEL: test_return
1012 ; THUMB: bx
1113 ret i32 %a
1214 }
15
16 @helper = global i32 ()* null, align 4
17
18 define i32 @test_indirect() #0 {
19 entry:
20 ; ARM-LABEL: test_indirect
21 ; ARM: mov pc
22 ; THUMB-LABEL: test_indirect
23 ; THUMB: bx
24 %0 = load i32 ()*, i32 ()** @helper, align 4
25 %call = tail call i32 %0()
26 ret i32 %call
27 }
None ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs -filetype=asm | FileCheck %s -check-prefix=ARM-linux
1 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -filetype=obj
0 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -verify-machineinstrs -filetype=asm | FileCheck %s -check-prefix=ARM-linux
1 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -filetype=obj
22
33 !llvm.dbg.cu = !{!0}
44 !llvm.module.flags = !{!9, !10}
None ; RUN: llc < %s -mtriple=arm-linux-androideabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
1 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
2 ; RUN: llc < %s -mtriple=arm-linux-androideabi -filetype=obj
3 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -filetype=obj
0 ; RUN: llc < %s -mtriple=arm-linux-androideabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
1 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
2 ; RUN: llc < %s -mtriple=arm-linux-androideabi -mattr=+v4t -filetype=obj
3 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -filetype=obj
44
55 ; Just to prevent the alloca from being optimized away
66 declare void @dummy_use(i32*, i32)
None ; RUN: llc < %s -mtriple=arm-linux-androideabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
1 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
0 ; RUN: llc < %s -mtriple=arm-linux-androideabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
1 ; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
22
33 ; We used to crash with filetype=obj
44 ; RUN: llc < %s -mtriple=arm-linux-androideabi -filetype=obj