[llvm] r289940 - [ARM] GlobalISel: Select add i32, i32
Diana Picus via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 16 04:54:47 PST 2016
Author: rovka
Date: Fri Dec 16 06:54:46 2016
New Revision: 289940
URL: http://llvm.org/viewvc/llvm-project?rev=289940&view=rev
Log:
[ARM] GlobalISel: Select add i32, i32
Add the minimal support necessary to select a function that returns the sum of
two i32 values.
This includes some support for argument/return lowering of i32 values through
registers, as well as the handling of copy and add instructions throughout the
GlobalISel pipeline.
Differential Revision: https://reviews.llvm.org/D26677
Added:
llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel.ll
llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir
llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir
Modified:
llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp
llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
llvm/trunk/lib/Target/ARM/ARMCallLowering.h
llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
llvm/trunk/lib/Target/ARM/ARMInstructionSelector.h
llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp
llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.h
llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
Modified: llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp Fri Dec 16 06:54:46 2016
@@ -43,6 +43,11 @@ bool InstructionSelector::constrainSelec
if (TRI.isPhysicalRegister(MO.getReg()))
continue;
+ // Register operands with a value of 0 (e.g. predicate operands) don't need
+ // to be constrained.
+ if (MO.getReg() == 0)
+ continue;
+
const TargetRegisterClass *RC = TII.getRegClass(I.getDesc(), OpI, &TRI, MF);
assert(RC && "Selected inst should have regclass operand");
Modified: llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp Fri Dec 16 06:54:46 2016
@@ -29,19 +29,148 @@ using namespace llvm;
ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI)
: CallLowering(&TLI) {}
+static bool isSupportedType(const DataLayout DL, const ARMTargetLowering &TLI,
+ Type *T) {
+ EVT VT = TLI.getValueType(DL, T);
+ return VT.isSimple() && VT.isInteger() &&
+ VT.getSimpleVT().getSizeInBits() == 32;
+}
+
+namespace {
+struct FuncReturnHandler : public CallLowering::ValueHandler {
+ FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+ MachineInstrBuilder &MIB)
+ : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
+
+ unsigned getStackAddress(uint64_t Size, int64_t Offset,
+ MachinePointerInfo &MPO) override {
+ llvm_unreachable("Don't know how to get a stack address yet");
+ }
+
+ void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
+ CCValAssign &VA) override {
+ assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
+ assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
+
+ assert(VA.getValVT().getSizeInBits() == 32 && "Unsupported value size");
+ assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
+
+ MIRBuilder.buildCopy(PhysReg, ValVReg);
+ MIB.addUse(PhysReg, RegState::Implicit);
+ }
+
+ void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
+ MachinePointerInfo &MPO, CCValAssign &VA) override {
+ llvm_unreachable("Don't know how to assign a value to an address yet");
+ }
+
+ MachineInstrBuilder &MIB;
+};
+} // End anonymous namespace.
+
+/// Lower the return value for the already existing \p Ret. This assumes that
+/// \p MIRBuilder's insertion point is correct.
+bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
+ const Value *Val, unsigned VReg,
+ MachineInstrBuilder &Ret) const {
+ if (!Val)
+ // Nothing to do here.
+ return true;
+
+ auto &MF = MIRBuilder.getMF();
+ const auto &F = *MF.getFunction();
+
+ auto DL = MF.getDataLayout();
+ auto &TLI = *getTLI<ARMTargetLowering>();
+ if (!isSupportedType(DL, TLI, Val->getType()))
+ return false;
+
+ CCAssignFn *AssignFn =
+ TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
+
+ ArgInfo RetInfo(VReg, Val->getType());
+ setArgFlags(RetInfo, AttributeSet::ReturnIndex, DL, F);
+
+ FuncReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
+ return handleAssignments(MIRBuilder, AssignFn, RetInfo, RetHandler);
+}
+
bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
const Value *Val, unsigned VReg) const {
- // We're currently only handling void returns
- if (Val != nullptr)
- return false;
+ assert(!Val == !VReg && "Return value without a vreg");
- AddDefaultPred(MIRBuilder.buildInstr(ARM::BX_RET));
+ auto Ret = AddDefaultPred(MIRBuilder.buildInstrNoInsert(ARM::BX_RET));
+ if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
+ return false;
+
+ MIRBuilder.insertInstr(Ret);
return true;
}
+namespace {
+struct FormalArgHandler : public CallLowering::ValueHandler {
+ FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
+ : ValueHandler(MIRBuilder, MRI) {}
+
+ unsigned getStackAddress(uint64_t Size, int64_t Offset,
+ MachinePointerInfo &MPO) override {
+ llvm_unreachable("Don't know how to get a stack address yet");
+ }
+
+ void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
+ CCValAssign &VA) override {
+ assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
+ assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
+
+ assert(VA.getValVT().getSizeInBits() == 32 && "Unsupported value size");
+ assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
+
+ MIRBuilder.getMBB().addLiveIn(PhysReg);
+ MIRBuilder.buildCopy(ValVReg, PhysReg);
+ }
+
+ void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
+ MachinePointerInfo &MPO, CCValAssign &VA) override {
+ llvm_unreachable("Don't know how to assign a value to an address yet");
+ }
+};
+} // End anonymous namespace
+
bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
const Function &F,
ArrayRef<unsigned> VRegs) const {
- return F.arg_empty();
+ // Quick exit if there aren't any args
+ if (F.arg_empty())
+ return true;
+
+ // Stick to only 4 arguments for now
+ if (F.arg_size() > 4)
+ return false;
+
+ if (F.isVarArg())
+ return false;
+
+ auto DL = MIRBuilder.getMF().getDataLayout();
+ auto &TLI = *getTLI<ARMTargetLowering>();
+
+ auto &Args = F.getArgumentList();
+ for (auto &Arg : Args)
+ if (!isSupportedType(DL, TLI, Arg.getType()))
+ return false;
+
+ CCAssignFn *AssignFn =
+ TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
+
+ SmallVector<ArgInfo, 8> ArgInfos;
+ unsigned Idx = 0;
+ for (auto &Arg : Args) {
+ ArgInfo AInfo(VRegs[Idx], Arg.getType());
+ setArgFlags(AInfo, Idx + 1, DL, F);
+ ArgInfos.push_back(AInfo);
+ Idx++;
+ }
+
+ FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
+ return handleAssignments(MIRBuilder, AssignFn, ArgInfos, ArgHandler);
}
Modified: llvm/trunk/lib/Target/ARM/ARMCallLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCallLowering.h?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCallLowering.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMCallLowering.h Fri Dec 16 06:54:46 2016
@@ -22,6 +22,7 @@
namespace llvm {
class ARMTargetLowering;
+class MachineInstrBuilder;
class ARMCallLowering : public CallLowering {
public:
@@ -32,6 +33,10 @@ public:
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
ArrayRef<unsigned> VRegs) const override;
+
+private:
+ bool lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val,
+ unsigned VReg, MachineInstrBuilder &Ret) const;
};
} // End of namespace llvm
#endif
Modified: llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp Fri Dec 16 06:54:46 2016
@@ -15,6 +15,7 @@
#include "ARMRegisterBankInfo.h"
#include "ARMSubtarget.h"
#include "ARMTargetMachine.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "arm-isel"
@@ -28,8 +29,58 @@ using namespace llvm;
ARMInstructionSelector::ARMInstructionSelector(const ARMSubtarget &STI,
const ARMRegisterBankInfo &RBI)
: InstructionSelector(), TII(*STI.getInstrInfo()),
- TRI(*STI.getRegisterInfo()) {}
+ TRI(*STI.getRegisterInfo()), RBI(RBI) {}
-bool ARMInstructionSelector::select(llvm::MachineInstr &I) const {
- return !isPreISelGenericOpcode(I.getOpcode());
+static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
+ MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI) {
+ unsigned DstReg = I.getOperand(0).getReg();
+ if (TargetRegisterInfo::isPhysicalRegister(DstReg))
+ return true;
+
+ const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
+ assert(RegBank && "Can't get reg bank for virtual register");
+
+ const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
+ unsigned SrcReg = I.getOperand(1).getReg();
+ const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
+ (void)SrcSize;
+ assert(DstSize == SrcSize && "Copy with different width?!");
+
+ assert(RegBank->getID() == ARM::GPRRegBankID && "Unsupported reg bank");
+ const TargetRegisterClass *RC = &ARM::GPRRegClass;
+
+ // No need to constrain SrcReg. It will get constrained when
+ // we hit another of its uses or its defs.
+ // Copies do not have constraints.
+ if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
+ DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
+ << " operand\n");
+ return false;
+ }
+ return true;
+}
+
+bool ARMInstructionSelector::select(MachineInstr &I) const {
+ assert(I.getParent() && "Instruction should be in a basic block!");
+ assert(I.getParent()->getParent() && "Instruction should be in a function!");
+
+ auto &MBB = *I.getParent();
+ auto &MF = *MBB.getParent();
+ auto &MRI = MF.getRegInfo();
+
+ if (!isPreISelGenericOpcode(I.getOpcode())) {
+ if (I.isCopy())
+ return selectCopy(I, TII, MRI, TRI, RBI);
+
+ return true;
+ }
+
+ if (I.getOpcode() == TargetOpcode::G_ADD) {
+ I.setDesc(TII.get(ARM::ADDrr));
+ AddDefaultCC(AddDefaultPred(MachineInstrBuilder(MF, I)));
+ return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+ }
+
+ return false;
}
Modified: llvm/trunk/lib/Target/ARM/ARMInstructionSelector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstructionSelector.h?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstructionSelector.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstructionSelector.h Fri Dec 16 06:54:46 2016
@@ -32,6 +32,7 @@ public:
private:
const ARMBaseInstrInfo &TII;
const ARMBaseRegisterInfo &TRI;
+ const ARMRegisterBankInfo &RBI;
};
} // End llvm namespace.
Modified: llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp Fri Dec 16 06:54:46 2016
@@ -24,5 +24,10 @@ using namespace llvm;
#endif
ARMLegalizerInfo::ARMLegalizerInfo() {
+ using namespace TargetOpcode;
+ const LLT s32 = LLT::scalar(32);
+
+ setAction({G_ADD, s32}, Legal);
+
computeTables();
}
Modified: llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp Fri Dec 16 06:54:46 2016
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ARMRegisterBankInfo.h"
+#include "ARMInstrInfo.h" // For the register classes
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -23,5 +24,91 @@ using namespace llvm;
#error "You shouldn't build this"
#endif
+// FIXME: TableGen this.
+// If it grows too much and TableGen still isn't ready to do the job, extract it
+// into an ARMGenRegisterBankInfo.def (similar to AArch64).
+namespace llvm {
+namespace ARM {
+RegisterBank GPRRegBank;
+RegisterBank *RegBanks[] = {&GPRRegBank};
+
+RegisterBankInfo::PartialMapping GPRPartialMapping{0, 32, GPRRegBank};
+
+RegisterBankInfo::ValueMapping ValueMappings[] = {
+ {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}};
+} // end namespace arm
+} // end namespace llvm
+
ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI)
- : RegisterBankInfo(nullptr, 0) {}
+ : RegisterBankInfo(ARM::RegBanks, ARM::NumRegisterBanks) {
+ static bool AlreadyInit = false;
+ // We have only one set of register banks, whatever the subtarget
+ // is. Therefore, the initialization of the RegBanks table should be
+ // done only once. Indeed the table of all register banks
+ // (ARM::RegBanks) is unique in the compiler. At some point, it
+ // will get tablegen'ed and the whole constructor becomes empty.
+ if (AlreadyInit)
+ return;
+ AlreadyInit = true;
+
+ // Initialize the GPR bank.
+ createRegisterBank(ARM::GPRRegBankID, "GPRB");
+
+ addRegBankCoverage(ARM::GPRRegBankID, ARM::GPRRegClassID, TRI);
+ addRegBankCoverage(ARM::GPRRegBankID, ARM::GPRwithAPSRRegClassID, TRI);
+ const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID);
+ (void)RBGPR;
+ assert(&ARM::GPRRegBank == &RBGPR && "The order in RegBanks is messed up");
+ assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRRegClassID)) &&
+ "Subclass not added?");
+ assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRwithAPSRRegClassID)) &&
+ "Subclass not added?");
+ assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnopcRegClassID)) &&
+ "Subclass not added?");
+ assert(RBGPR.covers(*TRI.getRegClass(ARM::rGPRRegClassID)) &&
+ "Subclass not added?");
+ assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPRRegClassID)) &&
+ "Subclass not added?");
+ assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) &&
+ "Subclass not added?");
+ assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPR_and_tcGPRRegClassID)) &&
+ "Subclass not added?");
+ assert(RBGPR.getSize() == 32 && "GPRs should hold up to 32-bit");
+}
+
+const RegisterBank &ARMRegisterBankInfo::getRegBankFromRegClass(
+ const TargetRegisterClass &RC) const {
+ using namespace ARM;
+
+ switch (RC.getID()) {
+ case GPRRegClassID:
+ case tGPR_and_tcGPRRegClassID:
+ return getRegBank(ARM::GPRRegBankID);
+ default:
+ llvm_unreachable("Unsupported register kind");
+ }
+
+ llvm_unreachable("Switch should handle all register classes");
+}
+
+RegisterBankInfo::InstructionMapping
+ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
+ auto Opc = MI.getOpcode();
+
+ // Try the default logic for non-generic instructions that are either copies
+ // or already have some operands assigned to banks.
+ if (!isPreISelGenericOpcode(Opc)) {
+ InstructionMapping Mapping = getInstrMappingImpl(MI);
+ if (Mapping.isValid())
+ return Mapping;
+ }
+
+ if (Opc == TargetOpcode::G_ADD) {
+ unsigned NumOperands = MI.getNumOperands();
+ ValueMapping *OperandsMapping = &ARM::ValueMappings[0];
+ return InstructionMapping{DefaultMappingID, /*Cost=*/1, OperandsMapping,
+ NumOperands};
+ }
+
+ return InstructionMapping{};
+}
Modified: llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.h?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.h Fri Dec 16 06:54:46 2016
@@ -20,10 +20,22 @@ namespace llvm {
class TargetRegisterInfo;
+namespace ARM {
+enum {
+ GPRRegBankID = 0, // General purpose registers
+ NumRegisterBanks,
+};
+} // end namespace ARM
+
/// This class provides the information for the target register banks.
class ARMRegisterBankInfo final : public RegisterBankInfo {
public:
ARMRegisterBankInfo(const TargetRegisterInfo &TRI);
+
+ const RegisterBank &
+ getRegBankFromRegClass(const TargetRegisterClass &RC) const override;
+
+ InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
};
} // End llvm namespace.
#endif
Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir?rev=289940&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir Fri Dec 16 06:54:46 2016
@@ -0,0 +1,37 @@
+# RUN: llc -O0 -mtriple arm-- -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+--- |
+ define void @test_adds32() { ret void }
+...
+---
+name: test_adds32
+# CHECK-LABEL: name: test_adds32
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+#CHECK: id: 0, class: gpr
+#CHECK: id: 1, class: gpr
+#CHECK: id: 2, class: gpr
+body: |
+ bb.0:
+ liveins: %r0, %r1
+
+ %0(s32) = COPY %r0
+ ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0
+
+ %1(s32) = COPY %r1
+ ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
+
+ %2(s32) = G_ADD %0, %1
+ ; CHECK: [[VREGSUM:%[0-9]+]] = ADDrr [[VREGX]], [[VREGY]], 14, _, _
+
+ %r0 = COPY %2(s32)
+ ; CHECK: %r0 = COPY [[VREGSUM]]
+
+ BX_RET 14, _, implicit %r0
+ ; CHECK: BX_RET 14, _, implicit %r0
+...
Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll?rev=289940&r1=289939&r2=289940&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll Fri Dec 16 06:54:46 2016
@@ -7,3 +7,15 @@ entry:
ret void
}
+define i32 @test_add(i32 %x, i32 %y) {
+; CHECK-LABEL: name: test_add
+; CHECK: liveins: %r0, %r1
+; CHECK: [[VREGX:%[0-9]+]]{{.*}} = COPY %r0
+; CHECK: [[VREGY:%[0-9]+]]{{.*}} = COPY %r1
+; CHECK: [[SUM:%[0-9]+]]{{.*}} = G_ADD [[VREGX]], [[VREGY]]
+; CHECK: %r0 = COPY [[SUM]]
+; CHECK: BX_RET 14, _, implicit %r0
+entry:
+ %sum = add i32 %x, %y
+ ret i32 %sum
+}
Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel.ll?rev=289940&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel.ll Fri Dec 16 06:54:46 2016
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple arm-unknown -global-isel %s -o - | FileCheck %s
+
+define void @test_void_return() {
+; CHECK-LABEL: test_void_return:
+; CHECK: bx lr
+entry:
+ ret void
+}
+
+define i32 @test_add(i32 %x, i32 %y) {
+; CHECK-LABEL: test_add:
+; CHECK: add r0, r0, r1
+; CHECK: bx lr
+entry:
+ %sum = add i32 %x, %y
+ ret i32 %sum
+}
Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir?rev=289940&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir Fri Dec 16 06:54:46 2016
@@ -0,0 +1,29 @@
+# RUN: llc -mtriple arm-- -global-isel -run-pass=legalizer %s -o - | FileCheck %s
+--- |
+ define void @test_add_s32() { ret void }
+...
+---
+name: test_add_s32
+# CHECK-LABEL: name: test_add_s32
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0:
+ liveins: %r0, %r1
+
+ %0(s32) = COPY %r0
+ %1(s32) = COPY %r1
+ %2(s32) = G_ADD %0, %1
+ ; G_ADD with s32 is legal, so we should find it unchanged in the output
+ ; CHECK: {{%[0-9]+}}(s32) = G_ADD {{%[0-9]+, %[0-9]+}}
+ %r0 = COPY %2(s32)
+ BX_RET 14, _, implicit %r0
+
+...
Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir?rev=289940&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir Fri Dec 16 06:54:46 2016
@@ -0,0 +1,30 @@
+# RUN: llc -mtriple arm-- -global-isel -run-pass=regbankselect %s -o - | FileCheck %s
+--- |
+ define void @test_add_s32() { ret void }
+...
+---
+name: test_add_s32
+# CHECK-LABEL: name: test_add_s32
+legalized: true
+regBankSelected: false
+selected: false
+# CHECK: registers:
+# CHECK: - { id: 0, class: gprb }
+# CHECK: - { id: 1, class: gprb }
+# CHECK: - { id: 2, class: gprb }
+
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0:
+ liveins: %r0, %r1
+
+ %0(s32) = COPY %r0
+ %1(s32) = COPY %r1
+ %2(s32) = G_ADD %0, %1
+ %r0 = COPY %2(s32)
+ BX_RET 14, _, implicit %r0
+
+...
More information about the llvm-commits
mailing list