[llvm] r322651 - [ARM GlobalISel] Legalize G_FPEXT and G_FPTRUNC

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 17 05:34:11 PST 2018


Author: rovka
Date: Wed Jan 17 05:34:10 2018
New Revision: 322651

URL: http://llvm.org/viewvc/llvm-project?rev=322651&view=rev
Log:
[ARM GlobalISel] Legalize G_FPEXT and G_FPTRUNC

Mark G_FPEXT and G_FPTRUNC as legal or libcall, depending on hardware
support, but only for conversions between float and double.

Also add the necessary boilerplate so that the LegalizerHelper can
introduce the required libcalls. This also works only for float and
double, but isn't too difficult to extend when the need arises.

Modified:
    llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
    llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir

Modified: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp?rev=322651&r1=322650&r2=322651&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp Wed Jan 17 05:34:10 2018
@@ -126,6 +126,7 @@ llvm::createLibcall(MachineIRBuilder &MI
   return LegalizerHelper::Legalized;
 }
 
+// Useful for libcalls where all operands have the same type.
 static LegalizerHelper::LegalizeResult
 simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
               Type *OpType) {
@@ -138,6 +139,28 @@ simpleLibcall(MachineInstr &MI, MachineI
                        Args);
 }
 
+static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType,
+                                       Type *FromType) {
+  auto ToMVT = MVT::getVT(ToType);
+  auto FromMVT = MVT::getVT(FromType);
+
+  switch (Opcode) {
+  case TargetOpcode::G_FPEXT:
+    return RTLIB::getFPEXT(FromMVT, ToMVT);
+  case TargetOpcode::G_FPTRUNC:
+    return RTLIB::getFPROUND(FromMVT, ToMVT);
+  }
+  llvm_unreachable("Unsupported libcall function");
+}
+
+static LegalizerHelper::LegalizeResult
+conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType,
+                  Type *FromType) {
+  RTLIB::Libcall Libcall = getConvRTLibDesc(MI.getOpcode(), ToType, FromType);
+  return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ToType},
+                       {{MI.getOperand(1).getReg(), FromType}});
+}
+
 LegalizerHelper::LegalizeResult
 LegalizerHelper::libcall(MachineInstr &MI) {
   LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
@@ -171,6 +194,30 @@ LegalizerHelper::libcall(MachineInstr &M
     if (Status != Legalized)
       return Status;
     break;
+  }
+  case TargetOpcode::G_FPEXT: {
+    // FIXME: Support other floating point types (half, fp128 etc)
+    unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
+    unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
+    if (ToSize != 64 || FromSize != 32)
+      return UnableToLegalize;
+    LegalizeResult Status = conversionLibcall(
+        MI, MIRBuilder, Type::getDoubleTy(Ctx), Type::getFloatTy(Ctx));
+    if (Status != Legalized)
+      return Status;
+    break;
+  }
+  case TargetOpcode::G_FPTRUNC: {
+    // FIXME: Support other floating point types (half, fp128 etc)
+    unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
+    unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
+    if (ToSize != 32 || FromSize != 64)
+      return UnableToLegalize;
+    LegalizeResult Status = conversionLibcall(
+        MI, MIRBuilder, Type::getFloatTy(Ctx), Type::getDoubleTy(Ctx));
+    if (Status != Legalized)
+      return Status;
+    break;
   }
   }
 

Modified: llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp?rev=322651&r1=322650&r2=322651&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp Wed Jan 17 05:34:10 2018
@@ -178,6 +178,12 @@ ARMLegalizerInfo::ARMLegalizerInfo(const
     setAction({G_MERGE_VALUES, 1, s32}, Legal);
     setAction({G_UNMERGE_VALUES, s32}, Legal);
     setAction({G_UNMERGE_VALUES, 1, s64}, Legal);
+
+    setAction({G_FPEXT, s64}, Legal);
+    setAction({G_FPEXT, 1, s32}, Legal);
+
+    setAction({G_FPTRUNC, s32}, Legal);
+    setAction({G_FPTRUNC, 1, s64}, Legal);
   } else {
     for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
       for (auto Ty : {s32, s64})
@@ -192,6 +198,12 @@ ARMLegalizerInfo::ARMLegalizerInfo(const
     setAction({G_FCMP, 1, s32}, Custom);
     setAction({G_FCMP, 1, s64}, Custom);
 
+    setAction({G_FPEXT, s64}, Legal);
+    setAction({G_FPEXT, 1, s32}, Libcall);
+
+    setAction({G_FPTRUNC, s32}, Legal);
+    setAction({G_FPTRUNC, 1, s64}, Libcall);
+
     if (AEABI(ST))
       setFCmpLibcallsAEABI();
     else

Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir?rev=322651&r1=322650&r2=322651&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir Wed Jan 17 05:34:10 2018
@@ -26,6 +26,9 @@
   define void @test_fneg_float() { ret void }
   define void @test_fneg_double() { ret void }
 
+  define void @test_fpext_float_to_double() { ret void }
+  define void @test_fptrunc_double_to_float() { ret void }
+
   define void @test_fcmp_true_s32() { ret void }
   define void @test_fcmp_false_s32() { ret void }
 
@@ -734,6 +737,82 @@ body:             |
     BX_RET 14, %noreg, implicit %r0, implicit %r1
 ...
 ---
+name:            test_fpext_float_to_double
+# CHECK-LABEL: name: test_fpext_float_to_double
+legalized:       false
+# CHECK: legalized: true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+body:             |
+  bb.0:
+    liveins: %r0
+
+    ; CHECK-DAG: [[X:%[0-9]+]]:_(s32) = COPY %r0
+    %0(s32) = COPY %r0
+    ; HARD: [[R:%[0-9]+]]:_(s64) = G_FPEXT [[X]]
+    ; SOFT-NOT: G_FPEXT
+    ; SOFT: ADJCALLSTACKDOWN
+    ; SOFT-DAG: %r0 = COPY [[X]]
+    ; SOFT-AEABI: BL &__aeabi_f2d, {{.*}}, implicit %r0, implicit-def %r0, implicit-def %r1
+    ; SOFT-DEFAULT: BL &__extendsfdf2, {{.*}}, implicit %r0, implicit-def %r0, implicit-def %r1
+    ; SOFT: [[R0:%[0-9]+]]:_(s32) = COPY %r0
+    ; SOFT: [[R1:%[0-9]+]]:_(s32) = COPY %r1
+    ; SOFT: ADJCALLSTACKUP
+    ; SOFT-NOT: G_FPEXT
+    %1(s64) = G_FPEXT %0(s32)
+    ; HARD: G_UNMERGE_VALUES [[R]](s64)
+    ; SOFT-DAG: %r{{[0-1]}} = COPY [[R0]]
+    ; SOFT-DAG: %r{{[0-1]}} = COPY [[R1]]
+    %2(s32), %3(s32) = G_UNMERGE_VALUES %1(s64)
+    %r0 = COPY %2(s32)
+    %r1 = COPY %3(s32)
+    BX_RET 14, %noreg, implicit %r0, implicit %r1
+...
+---
+name:            test_fptrunc_double_to_float
+# CHECK-LABEL: name: test_fptrunc_double_to_float
+legalized:       false
+# CHECK: legalized: true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    ; CHECK-DAG: [[X0:%[0-9]+]]:_(s32) = COPY %r0
+    ; CHECK-DAG: [[X1:%[0-9]+]]:_(s32) = COPY %r1
+    ; HARD: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[X0]]
+    %0(s32) = COPY %r0
+    %1(s32) = COPY %r1
+    %2(s64) = G_MERGE_VALUES %0(s32), %1(s32)
+    ; HARD: [[R:%[0-9]+]]:_(s32) = G_FPTRUNC [[X]]
+    ; SOFT-NOT: G_FPTRUNC
+    ; SOFT: ADJCALLSTACKDOWN
+    ; SOFT-DAG: %r0 = COPY [[X0]]
+    ; SOFT-DAG: %r1 = COPY [[X1]]
+    ; SOFT-AEABI: BL &__aeabi_d2f, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+    ; SOFT-DEFAULT: BL &__truncdfsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+    ; SOFT: [[R:%[0-9]+]]:_(s32) = COPY %r0
+    ; SOFT: ADJCALLSTACKUP
+    ; SOFT-NOT: G_FPTRUNC
+    %3(s32) = G_FPTRUNC %2(s64)
+    ; CHECK: %r0 = COPY [[R]]
+    %r0 = COPY %3(s32)
+    BX_RET 14, %noreg, implicit %r0
+---
+...
 name:            test_fcmp_true_s32
 # CHECK-LABEL: name: test_fcmp_true_s32
 legalized:       false




More information about the llvm-commits mailing list