From e7f301e079ee4b86f0a54b1108222ee3b6938ca1 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Fri, 29 Aug 2014 23:48:06 +0000 Subject: [PATCH] [FastISel][AArch64] Use the correct register class for branches. Also constrain the register class for branches. This fixes rdar://problem/18181496. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216804 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64FastISel.cpp | 16 +++++++++------- test/CodeGen/AArch64/arm64-fast-isel-call.ll | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index 7ee8c47930a..ac1b5d5fa8e 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -2182,15 +2182,16 @@ bool AArch64FastISel::FastLowerCall(CallLoweringInfo &CLI) { // Issue the call. MachineInstrBuilder MIB; if (CM == CodeModel::Small) { - unsigned CallOpc = Addr.getReg() ? AArch64::BLR : AArch64::BL; - MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CallOpc)); + const MCInstrDesc &II = TII.get(Addr.getReg() ? AArch64::BLR : AArch64::BL); + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II); if (SymName) MIB.addExternalSymbol(SymName, 0); else if (Addr.getGlobalValue()) MIB.addGlobalAddress(Addr.getGlobalValue(), 0, 0); - else if (Addr.getReg()) - MIB.addReg(Addr.getReg()); - else + else if (Addr.getReg()) { + unsigned Reg = constrainOperandRegClass(II, Addr.getReg(), 0); + MIB.addReg(Reg); + } else return false; } else { unsigned CallReg = 0; @@ -2214,8 +2215,9 @@ bool AArch64FastISel::FastLowerCall(CallLoweringInfo &CLI) { if (!CallReg) return false; - MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, - TII.get(AArch64::BLR)).addReg(CallReg); + const MCInstrDesc &II = TII.get(AArch64::BLR); + CallReg = constrainOperandRegClass(II, CallReg, 0); + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II).addReg(CallReg); } // Add implicit physical register uses to the call. diff --git a/test/CodeGen/AArch64/arm64-fast-isel-call.ll b/test/CodeGen/AArch64/arm64-fast-isel-call.ll index 6e22fcf7dc7..f1e2c40a33c 100644 --- a/test/CodeGen/AArch64/arm64-fast-isel-call.ll +++ b/test/CodeGen/AArch64/arm64-fast-isel-call.ll @@ -252,3 +252,18 @@ define void @call_arguments9(i8 %a1, i16 %a2, i32 %a3, i64 %a4, float %a5, doubl ; CHECK-LABEL: call_arguments9 ret void } + +; Test that we use the correct register class for the branch. +define void @call_blr(i64 %Fn, i1 %c) { +; CHECK-LABEL: call_blr +; CHECK: blr + br i1 %c, label %bb1, label %bb2 +bb1: + %1 = inttoptr i64 %Fn to void (i64)* + br label %bb2 +bb2: + %2 = phi void (i64)* [ %1, %bb1 ], [ undef, %0 ] + call void %2(i64 1) + ret void +} +