[ARM GlobalISel] Select G_FCONSTANT into pools
authorDiana Picus <diana.picus@linaro.org>
Wed, 10 Apr 2019 09:14:24 +0000 (09:14 +0000)
committerDiana Picus <diana.picus@linaro.org>
Wed, 10 Apr 2019 09:14:24 +0000 (09:14 +0000)
Put all floating point constants into constant pools and load their
values from there.

llvm-svn: 358062

llvm/lib/Target/ARM/ARMInstructionSelector.cpp
llvm/test/CodeGen/ARM/GlobalISel/select-fp-const.mir [new file with mode: 0644]

index 6df74ec..0f56504 100644 (file)
@@ -958,6 +958,27 @@ bool ARMInstructionSelector::select(MachineInstr &I,
     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
     break;
   }
+  case G_FCONSTANT: {
+    // Load from constant pool
+    unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits() / 8;
+    unsigned Alignment = Size;
+
+    assert((Size == 4 || Size == 8) && "Unsupported FP constant type");
+    auto LoadOpcode = Size == 4 ? ARM::VLDRS : ARM::VLDRD;
+
+    auto ConstPool = MF.getConstantPool();
+    auto CPIndex =
+        ConstPool->getConstantPoolIndex(I.getOperand(1).getFPImm(), Alignment);
+    MIB->setDesc(TII.get(LoadOpcode));
+    MIB->RemoveOperand(1);
+    MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
+        .addMemOperand(
+            MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
+                                    MachineMemOperand::MOLoad, Size, Alignment))
+        .addImm(0)
+        .add(predOps(ARMCC::AL));
+    break;
+  }
   case G_INTTOPTR:
   case G_PTRTOINT: {
     auto SrcReg = I.getOperand(1).getReg();
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/select-fp-const.mir b/llvm/test/CodeGen/ARM/GlobalISel/select-fp-const.mir
new file mode 100644 (file)
index 0000000..8eac01d
--- /dev/null
@@ -0,0 +1,135 @@
+# RUN: llc -O0 -mtriple arm-- -mattr=+vfp3,-neonfp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,VFP3
+# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2,+vfp3,-neonfp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,VFP3
+# RUN: llc -O0 -mtriple arm-- -mattr=+vfp2,-neonfp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,VFP2
+# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2,+vfp2,-neonfp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,VFP2
+--- |
+  define void @test_fpconst_zero_s32() { ret void }
+  define void @test_fpconst_zero_s64() { ret void }
+
+  define void @test_fpconst_8bit_s32() { ret void }
+  define void @test_fpconst_8bit_s64() { ret void }
+...
+---
+name:            test_fpconst_zero_s32
+# CHECK-LABEL: name: test_fpconst_zero_s32
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: fprb }
+# CHECK: constants:
+# CHECK-NEXT: id: 0
+# CHECK-NEXT: value: 'float 0.000000e+00'
+# CHECK-NEXT: alignment: 4
+# CHECK-NEXT: isTargetSpecific: false
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(p0) = COPY $r0
+    ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s32) = G_FCONSTANT float 0.0
+    ; CHECK: [[VREG:%[0-9]+]]:spr = VLDRS %const.0, 0, 14, $noreg :: (load 4 from constant-pool)
+
+    G_STORE %1(s32), %0 :: (store 4)
+    ; CHECK: VSTRS [[VREG]], [[PTR]], 0, 14, $noreg
+
+    BX_RET 14, $noreg
+    ; CHECK: BX_RET 14, $noreg
+...
+---
+name:            test_fpconst_zero_s64
+# CHECK-LABEL: name: test_fpconst_zero_s64
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: fprb }
+# CHECK: constants:
+# CHECK-NEXT: id: 0
+# CHECK-NEXT: value: 'double 0.000000e+00'
+# CHECK-NEXT: alignment: 8
+# CHECK-NEXT: isTargetSpecific: false
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(p0) = COPY $r0
+    ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s64) = G_FCONSTANT double 0.0
+    ; CHECK: [[VREG:%[0-9]+]]:dpr = VLDRD %const.0, 0, 14, $noreg :: (load 8 from constant-pool)
+
+    G_STORE %1(s64), %0 :: (store 8)
+    ; CHECK: VSTRD [[VREG]], [[PTR]], 0, 14, $noreg
+
+    BX_RET 14, $noreg
+    ; CHECK: BX_RET 14, $noreg
+...
+---
+name:            test_fpconst_8bit_s32
+# CHECK-LABEL: name: test_fpconst_8bit_s32
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: fprb }
+# CHECK: constants:
+# CHECK-NEXT: id: 0
+# CHECK-NEXT: value: 'float -2.000000e+00'
+# CHECK-NEXT: alignment: 4
+# CHECK-NEXT: isTargetSpecific: false
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(p0) = COPY $r0
+    ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s32) = G_FCONSTANT float -2.0
+    ; CHECK: [[VREG:%[0-9]+]]:spr = VLDRS %const.0, 0, 14, $noreg :: (load 4 from constant-pool)
+
+    G_STORE %1(s32), %0 :: (store 4)
+    ; CHECK: VSTRS [[VREG]], [[PTR]], 0, 14, $noreg
+
+    BX_RET 14, $noreg
+    ; CHECK: BX_RET 14, $noreg
+...
+---
+name:            test_fpconst_8bit_s64
+# CHECK-LABEL: name: test_fpconst_8bit_s64
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: fprb }
+# CHECK: constants:
+# CHECK-NEXT: id: 0
+# CHECK-NEXT: value: double 5.000000e-01
+# CHECK-NEXT: alignment: 8
+# CHECK-NEXT: isTargetSpecific: false
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(p0) = COPY $r0
+    ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s64) = G_FCONSTANT double 5.0e-1
+    ; CHECK: [[VREG:%[0-9]+]]:dpr = VLDRD %const.0, 0, 14, $noreg :: (load 8 from constant-pool)
+
+    G_STORE %1(s64), %0 :: (store 8)
+    ; CHECK: VSTRD [[VREG]], [[PTR]], 0, 14, $noreg
+
+    BX_RET 14, $noreg
+    ; CHECK: BX_RET 14, $noreg
+...