diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 0deafae73853..db33d540a4d8 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -205,7 +205,8 @@ ARMBaseRegisterInfo::getRegAllocationHints(unsigned VirtReg, } // First prefer the paired physreg. - if (PairedPhys) + if (PairedPhys && + std::find(Order.begin(), Order.end(), PairedPhys) != Order.end()) Hints.push_back(PairedPhys); // Then prefer even or odd registers. diff --git a/llvm/test/CodeGen/Thumb2/2013-02-19-tail-call-register-hint.ll b/llvm/test/CodeGen/Thumb2/2013-02-19-tail-call-register-hint.ll new file mode 100644 index 000000000000..502b138f65c8 --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/2013-02-19-tail-call-register-hint.ll @@ -0,0 +1,53 @@ +; RUN: llc < %s -mtriple=thumbv7s-apple-ios6.0.0 -verify-machineinstrs + +; Check to make sure the tail-call return at the end doesn't use a +; callee-saved register. Register hinting from t2LDRDri was getting this +; wrong. The intervening call will force allocation to try a high register +; first, so the hint will attempt to fire, but must be rejected due to +; not being in the allocation order for the tcGPR register class. +; The machine instruction verifier will make sure that all actually worked +; out the way it's supposed to. + +%"myclass" = type { %struct.foo } +%struct.foo = type { i32, [40 x i8] } + +define hidden void @func(i8* %Data) nounwind ssp { + %1 = getelementptr inbounds i8* %Data, i32 12 + %2 = bitcast i8* %1 to %"myclass"* + tail call void @abc(%"myclass"* %2) nounwind + tail call void @def(%"myclass"* %2) nounwind + %3 = getelementptr inbounds i8* %Data, i32 8 + %4 = bitcast i8* %3 to i8** + %5 = load i8** %4, align 4, !tbaa !0 + tail call void @ghi(i8* %5) nounwind + %6 = bitcast i8* %Data to void (i8*)** + %7 = load void (i8*)** %6, align 4, !tbaa !0 + %8 = getelementptr inbounds i8* %Data, i32 4 + %9 = bitcast i8* %8 to i8** + %10 = load i8** %9, align 4, !tbaa !0 + %11 = icmp eq i8* %Data, null + br i1 %11, label %14, label %12 + +;