From 126f155f7f38df81ca81a67bcd7f07f8d7886615 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Thu, 16 Feb 2017 12:19:52 +0000 Subject: [PATCH] [ARM] GlobalISel: Select double G_FADD and copies Just use VADDD if available, bail out if not. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295309 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstructionSelector.cpp | 35 ++++++++++++++++++---- .../ARM/GlobalISel/arm-instruction-select.mir | 34 +++++++++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/lib/Target/ARM/ARMInstructionSelector.cpp b/lib/Target/ARM/ARMInstructionSelector.cpp index dcdd0e83550..5201ddba781 100644 --- a/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/lib/Target/ARM/ARMInstructionSelector.cpp @@ -61,8 +61,12 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterClass *RC = &ARM::GPRRegClass; if (RegBank->getID() == ARM::FPRRegBankID) { - assert(DstSize == 32 && "Only 32-bit FP values are supported"); - RC = &ARM::SPRRegClass; + if (DstSize == 32) + RC = &ARM::SPRRegClass; + else if (DstSize == 64) + RC = &ARM::DPRRegClass; + else + llvm_unreachable("Unsupported destination size"); } // No need to constrain SrcReg. It will get constrained when @@ -76,6 +80,28 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, return true; } +static bool selectFAdd(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, + MachineRegisterInfo &MRI) { + assert(TII.getSubtarget().hasVFP2() && "Can't select fp add without vfp"); + + LLT Ty = MRI.getType(MIB->getOperand(0).getReg()); + unsigned ValSize = Ty.getSizeInBits(); + + if (ValSize == 32) { + if (TII.getSubtarget().useNEONForSinglePrecisionFP()) + return false; + MIB->setDesc(TII.get(ARM::VADDS)); + } else { + assert(ValSize == 64 && "Unsupported size for floating point value"); + if (TII.getSubtarget().isFPOnlySP()) + return false; + MIB->setDesc(TII.get(ARM::VADDD)); + } + MIB.add(predOps(ARMCC::AL)); + + return true; +} + /// Select the opcode for simple extensions (that translate to a single SXT/UXT /// instruction). Extension operations more complicated than that should not /// invoke this. @@ -186,11 +212,8 @@ bool ARMInstructionSelector::select(MachineInstr &I) const { MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); break; case G_FADD: - if (!TII.getSubtarget().hasVFP2() || - TII.getSubtarget().useNEONForSinglePrecisionFP()) + if (!selectFAdd(MIB, TII, MRI)) return false; - I.setDesc(TII.get(ARM::VADDS)); - MIB.add(predOps(ARMCC::AL)); break; case G_FRAME_INDEX: // Add 0 to the given frame index and hope it will eventually be folded into diff --git a/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir b/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir index 48d58d71eb6..659c52c338d 100644 --- a/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir +++ b/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir @@ -10,6 +10,7 @@ define void @test_add_s32() { ret void } define void @test_fadd_s32() #0 { ret void } + define void @test_fadd_s64() #0 { ret void } define void @test_load_from_stack() { ret void } @@ -254,6 +255,39 @@ body: | ; CHECK: BX_RET 14, _, implicit %s0 ... --- +name: test_fadd_s64 +# CHECK-LABEL: name: test_fadd_s64 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: fprb } +# CHECK: id: 0, class: dpr +# CHECK: id: 1, class: dpr +# CHECK: id: 2, class: dpr +body: | + bb.0: + liveins: %d0, %d1 + + %0(s64) = COPY %d0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %d0 + + %1(s64) = COPY %d1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %d1 + + %2(s64) = G_FADD %0, %1 + ; CHECK: [[VREGSUM:%[0-9]+]] = VADDD [[VREGX]], [[VREGY]], 14, _ + + %d0 = COPY %2(s64) + ; CHECK: %d0 = COPY [[VREGSUM]] + + BX_RET 14, _, implicit %d0 + ; CHECK: BX_RET 14, _, implicit %d0 +... +--- name: test_load_from_stack # CHECK-LABEL: name: test_load_from_stack legalized: true -- 2.11.0