From 0517764ca4ced57933024e032f33d2684ba62ab6 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Thu, 22 Dec 2016 21:56:31 +0000 Subject: [PATCH] [AArch64][CallLowering] Constraint registers on target specific instruction The InstructionSelect pass will not look at target specific instructions since they are already selected. As a result, the operands of target specific instructions must be properly constrained, because it is not going to fix them. This fixes invalid register classes on call instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290377 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64CallLowering.cpp | 13 ++++++++++++- test/CodeGen/AArch64/GlobalISel/call-translator.ll | 7 +++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/Target/AArch64/AArch64CallLowering.cpp b/lib/Target/AArch64/AArch64CallLowering.cpp index ebf3acc5f49..a4950af3209 100644 --- a/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/lib/Target/AArch64/AArch64CallLowering.cpp @@ -16,8 +16,10 @@ #include "AArch64CallLowering.h" #include "AArch64ISelLowering.h" -#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/Analysis.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -277,6 +279,15 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, // Now we can add the actual call instruction to the correct basic block. MIRBuilder.insertInstr(MIB); + // If Callee is a reg, since it is used by a target specific + // instruction, it must have a register class matching the + // constraint of that instruction. + if (Callee.isReg()) + MIB->getOperand(0).setReg(constrainOperandRegClass( + MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(), + *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(), + Callee.getReg(), 0)); + // Finally we can copy the returned value back into its virtual-register. In // symmetry with the arugments, the physical register must be an // implicit-define of the call instruction. diff --git a/test/CodeGen/AArch64/GlobalISel/call-translator.ll b/test/CodeGen/AArch64/GlobalISel/call-translator.ll index 4c6fff6ab28..7bedad38de1 100644 --- a/test/CodeGen/AArch64/GlobalISel/call-translator.ll +++ b/test/CodeGen/AArch64/GlobalISel/call-translator.ll @@ -31,8 +31,11 @@ define void @test_simple_arg(i32 %in) { } ; CHECK-LABEL: name: test_indirect_call -; CHECK: [[FUNC:%[0-9]+]](p0) = COPY %x0 -; CHECK: BLR [[FUNC]](p0), csr_aarch64_aapcs, implicit-def %lr, implicit %sp +; CHECK: registers: +; Make sure the register feeding the indirect call is properly constrained. +; CHECK: - { id: [[FUNC:[0-9]+]], class: gpr64 } +; CHECK: %[[FUNC]](p0) = COPY %x0 +; CHECK: BLR %[[FUNC]](p0), csr_aarch64_aapcs, implicit-def %lr, implicit %sp ; CHECK: RET_ReallyLR define void @test_indirect_call(void()* %func) { call void %func() -- 2.11.0