[AArch64][CallLowering] Constraint registers on target specific instruction
authorQuentin Colombet <qcolombet@apple.com>
Thu, 22 Dec 2016 21:56:31 +0000 (21:56 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Thu, 22 Dec 2016 21:56:31 +0000 (21:56 +0000)
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.

llvm-svn: 290377

llvm/lib/Target/AArch64/AArch64CallLowering.cpp
llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll

index ebf3acc..a4950af 100644 (file)
 #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.
index 4c6fff6..7bedad3 100644 (file)
@@ -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()