From 5f7dea85c21e82cf3089ee5a34ad51ac90887642 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 8 Nov 2016 17:44:07 +0000 Subject: [PATCH] GlobalISel: support selecting fpext/fptrunc instructions on AArch64. llvm-svn: 286253 --- .../Target/AArch64/AArch64InstructionSelector.cpp | 54 ++++++++++++++++++++++ .../AArch64/GlobalISel/arm64-instructionselect.mir | 51 ++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index 80ea8d6..ac8323a 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -953,6 +953,60 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { case TargetOpcode::G_BITCAST: return selectCopy(I, TII, MRI, TRI, RBI); + case TargetOpcode::G_FPEXT: { + if (MRI.getType(I.getOperand(0).getReg()) != LLT::scalar(64)) { + DEBUG(dbgs() << "G_FPEXT to type " << Ty + << ", expected: " << LLT::scalar(64) << '\n'); + return false; + } + + if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(32)) { + DEBUG(dbgs() << "G_FPEXT from type " << Ty + << ", expected: " << LLT::scalar(32) << '\n'); + return false; + } + + const unsigned DefReg = I.getOperand(0).getReg(); + const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); + + if (RB.getID() != AArch64::FPRRegBankID) { + DEBUG(dbgs() << "G_FPEXT on bank: " << RB << ", expected: FPR\n"); + return false; + } + + I.setDesc(TII.get(AArch64::FCVTDSr)); + constrainSelectedInstRegOperands(I, TII, TRI, RBI); + + return true; + } + + case TargetOpcode::G_FPTRUNC: { + if (MRI.getType(I.getOperand(0).getReg()) != LLT::scalar(32)) { + DEBUG(dbgs() << "G_FPTRUNC to type " << Ty + << ", expected: " << LLT::scalar(32) << '\n'); + return false; + } + + if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(64)) { + DEBUG(dbgs() << "G_FPTRUNC from type " << Ty + << ", expected: " << LLT::scalar(64) << '\n'); + return false; + } + + const unsigned DefReg = I.getOperand(0).getReg(); + const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); + + if (RB.getID() != AArch64::FPRRegBankID) { + DEBUG(dbgs() << "G_FPTRUNC on bank: " << RB << ", expected: FPR\n"); + return false; + } + + I.setDesc(TII.get(AArch64::FCVTSDr)); + constrainSelectedInstRegOperands(I, TII, TRI, RBI); + + return true; + } + case TargetOpcode::G_SELECT: { if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) { DEBUG(dbgs() << "G_SELECT cond has type: " << Ty diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir index e9c165b..a95829a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir @@ -88,6 +88,9 @@ define void @fptoui_s64_s32_gpr() { ret void } define void @fptoui_s64_s64_gpr() { ret void } + define void @fptrunc() { ret void } + define void @fpext() { ret void } + define void @unconditional_br() { ret void } define void @conditional_br() { ret void } @@ -1826,6 +1829,54 @@ body: | ... --- +# CHECK-LABEL: name: fptrunc +name: fptrunc +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK: - { id: 0, class: fpr64 } +# CHECK: - { id: 1, class: fpr32 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %d0 +# CHECK: %1 = FCVTSDr %0 +body: | + bb.0: + liveins: %d0 + + %0(s64) = COPY %d0 + %1(s32) = G_FPTRUNC %0 +... + +--- +# CHECK-LABEL: name: fpext +name: fpext +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK: - { id: 0, class: fpr32 } +# CHECK: - { id: 1, class: fpr64 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %s0 +# CHECK: %1 = FCVTDSr %0 +body: | + bb.0: + liveins: %d0 + + %0(s32) = COPY %s0 + %1(s64) = G_FPEXT %0 +... + +--- # CHECK-LABEL: name: unconditional_br name: unconditional_br legalized: true -- 2.7.4