[llvm] r295310 - [ARM] GlobalISel: Select G_SEQUENCE and G_EXTRACT
Diana Picus via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 16 04:19:57 PST 2017
Author: rovka
Date: Thu Feb 16 06:19:57 2017
New Revision: 295310
URL: http://llvm.org/viewvc/llvm-project?rev=295310&view=rev
Log:
[ARM] GlobalISel: Select G_SEQUENCE and G_EXTRACT
Since they're only used for passing around double precision floating point
values into the general purpose registers, we'll lower them to VMOVDRR and
VMOVRRD.
Modified:
llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
Modified: llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp?rev=295310&r1=295309&r2=295310&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp Thu Feb 16 06:19:57 2017
@@ -102,6 +102,74 @@ static bool selectFAdd(MachineInstrBuild
return true;
}
+static bool selectSequence(MachineInstrBuilder &MIB,
+ const ARMBaseInstrInfo &TII,
+ MachineRegisterInfo &MRI,
+ const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI) {
+ assert(TII.getSubtarget().hasVFP2() && "Can't select sequence without VFP");
+
+ // We only support G_SEQUENCE as a way to stick together two scalar GPRs
+ // into one DPR.
+ unsigned VReg0 = MIB->getOperand(0).getReg();
+ (void)VReg0;
+ assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
+ RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+ unsigned VReg1 = MIB->getOperand(1).getReg();
+ (void)VReg1;
+ assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
+ RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+ unsigned VReg2 = MIB->getOperand(3).getReg();
+ (void)VReg2;
+ assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
+ RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+
+ // Remove the operands corresponding to the offsets.
+ MIB->RemoveOperand(4);
+ MIB->RemoveOperand(2);
+
+ MIB->setDesc(TII.get(ARM::VMOVDRR));
+ MIB.add(predOps(ARMCC::AL));
+
+ return true;
+}
+
+static bool selectExtract(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
+ MachineRegisterInfo &MRI,
+ const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI) {
+ assert(TII.getSubtarget().hasVFP2() && "Can't select extract without VFP");
+
+ // We only support G_EXTRACT as a way to break up one DPR into two GPRs.
+ unsigned VReg0 = MIB->getOperand(0).getReg();
+ (void)VReg0;
+ assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
+ RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+ unsigned VReg1 = MIB->getOperand(1).getReg();
+ (void)VReg1;
+ assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
+ RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+ unsigned VReg2 = MIB->getOperand(2).getReg();
+ (void)VReg2;
+ assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
+ RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
+ "Unsupported operand for G_SEQUENCE");
+
+ // Remove the operands corresponding to the offsets.
+ MIB->RemoveOperand(4);
+ MIB->RemoveOperand(3);
+
+ MIB->setDesc(TII.get(ARM::VMOVRRD));
+ 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.
@@ -237,6 +305,16 @@ bool ARMInstructionSelector::select(Mach
MIB.addImm(0).add(predOps(ARMCC::AL));
break;
}
+ case G_SEQUENCE: {
+ if (!selectSequence(MIB, TII, MRI, TRI, RBI))
+ return false;
+ break;
+ }
+ case G_EXTRACT: {
+ if (!selectExtract(MIB, TII, MRI, TRI, RBI))
+ return false;
+ break;
+ }
default:
return false;
}
Modified: 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=295310&r1=295309&r2=295310&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir Thu Feb 16 06:19:57 2017
@@ -14,6 +14,8 @@
define void @test_load_from_stack() { ret void }
+ define void @test_soft_fp_double() #0 { ret void }
+
attributes #0 = { "target-features"="+vfp2,-neonfp" }
...
---
@@ -328,3 +330,46 @@ body: |
BX_RET 14, _
; CHECK: BX_RET 14, _
...
+---
+name: test_soft_fp_double
+# CHECK-LABEL: name: test_soft_fp_double
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: fprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+# CHECK-DAG: id: {{[0-9]+}}, class: gpr
+# CHECK-DAG: id: {{[0-9]+}}, class: gpr
+# CHECK-DAG: id: {{[0-9]+}}, class: gpr
+# CHECK-DAG: id: {{[0-9]+}}, class: gpr
+# CHECK-DAG: id: [[DREG:[0-9]+]], class: dpr
+body: |
+ bb.0:
+ liveins: %r0, %r1, %r2, %r3
+
+ %0(s32) = COPY %r2
+ ; CHECK: [[IN1:%[0-9]+]] = COPY %r2
+
+ %1(s32) = COPY %r3
+ ; CHECK: [[IN2:%[0-9]+]] = COPY %r3
+
+ %2(s64) = G_SEQUENCE %0(s32), 0, %1(s32), 1
+ ; CHECK: %[[DREG]] = VMOVDRR [[IN1]], [[IN2]]
+
+ %3(s32), %4(s32) = G_EXTRACT %2(s64), 0, 32
+ ; CHECK: [[OUT1:%[0-9]+]], [[OUT2:%[0-9]+]] = VMOVRRD %[[DREG]]
+
+ %r0 = COPY %3
+ ; CHECK: %r0 = COPY [[OUT1]]
+
+ %r1 = COPY %4
+ ; CHECK: %r1 = COPY [[OUT2]]
+
+ BX_RET 14, _, implicit %r0, implicit %r1
+ ; CHECK: BX_RET 14, _, implicit %r0, implicit %r1
+...
More information about the llvm-commits
mailing list