GlobalISel: teach legalizer how to handle integer constants.
authorTim Northover <tnorthover@apple.com>
Fri, 19 Aug 2016 22:40:00 +0000 (22:40 +0000)
committerTim Northover <tnorthover@apple.com>
Fri, 19 Aug 2016 22:40:00 +0000 (22:40 +0000)
llvm-svn: 279340

llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp
llvm/test/CodeGen/AArch64/GlobalISel/legalize-constant.mir [new file with mode: 0644]

index 29fdee8..632d629 100644 (file)
@@ -104,6 +104,7 @@ MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) {
 
 MachineLegalizeHelper::LegalizeResult
 MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
+  unsigned WideSize = WideTy.getSizeInBits();
   switch (MI.getOpcode()) {
   default:
     return UnableToLegalize;
@@ -116,7 +117,6 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
     // Perform operation at larger width (any extension is fine here, high bits
     // don't affect the result) and then truncate the result back to the
     // original type.
-    unsigned WideSize = WideTy.getSizeInBits();
 
     MIRBuilder.setInstr(MI);
 
@@ -133,6 +133,14 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
     MI.eraseFromParent();
     return Legalized;
   }
+  case TargetOpcode::G_CONSTANT: {
+    MIRBuilder.setInstr(MI);
+    unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
+    MIRBuilder.buildConstant(WideTy, DstExt, MI.getOperand(1).getImm());
+    MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
+    MI.eraseFromParent();
+    return Legalized;
+  }
   }
 }
 
index 881b502..fa23627 100644 (file)
@@ -119,8 +119,9 @@ LLT MachineLegalizer::findLegalType(unsigned Opcode, LLT Ty,
                          [&](LLT Ty) -> LLT { return Ty.halfScalarSize(); });
   }
   case WidenScalar: {
-    return findLegalType(Opcode, Ty,
-                         [&](LLT Ty) -> LLT { return Ty.doubleScalarSize(); });
+    return findLegalType(Opcode, Ty, [&](LLT Ty) -> LLT {
+      return Ty.getSizeInBits() < 8 ? LLT::scalar(8) : Ty.doubleScalarSize();
+    });
   }
   case FewerElements: {
     return findLegalType(Opcode, Ty,
index 36f7f4e..a06eee0 100644 (file)
@@ -26,6 +26,7 @@ using namespace llvm;
 
 AArch64MachineLegalizer::AArch64MachineLegalizer() {
   using namespace TargetOpcode;
+  const LLT s1 = LLT::scalar(1);
   const LLT s8 = LLT::scalar(8);
   const LLT s16 = LLT::scalar(16);
   const LLT s32 = LLT::scalar(32);
@@ -54,6 +55,14 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() {
     for (auto Ty : {s32, s64})
       setAction(MemOp, Ty, Legal);
 
+  for (auto Ty : {s32, s64}) {
+    setAction(TargetOpcode::G_CONSTANT, Ty, Legal);
+    setAction(TargetOpcode::G_FCONSTANT, Ty, Legal);
+  }
+
+  for (auto Ty : {s1, s8, s16})
+    setAction(TargetOpcode::G_CONSTANT, Ty, WidenScalar);
+
 
   setAction(G_BR, LLT::unsized(), Legal);
 
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-constant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-constant.mir
new file mode 100644 (file)
index 0000000..1cf0e68
--- /dev/null
@@ -0,0 +1,59 @@
+# RUN: llc -O0 -run-pass=legalize-mir -global-isel %s -o - 2>&1 | FileCheck %s
+
+--- |
+  target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+  target triple = "aarch64-apple-ios"
+  define void @test_constant() {
+  entry:
+    ret void
+  }
+  define void @test_fconstant() {
+  entry:
+    ret void
+  }
+...
+
+---
+name:            test_constant
+isSSA:           true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+body: |
+  bb.0.entry:
+    ; CHECK-LABEL: name: test_constant
+    ; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 0
+    ; CHECK: %0(1) = G_TRUNC s1 [[TMP]]
+    ; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 42
+    ; CHECK: %1(8) = G_TRUNC s8 [[TMP]]
+    ; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 65535
+    ; CHECK: %2(16) = G_TRUNC s16 [[TMP]]
+    ; CHECK: %3(32) = G_CONSTANT s32 -1
+    ; CHECK: %4(64) = G_CONSTANT s64 1
+
+    %0(1) = G_CONSTANT s1 0
+    %1(8) = G_CONSTANT s8 42
+    %2(16) = G_CONSTANT s16 65535
+    %3(32) = G_CONSTANT s32 -1
+    %4(64) = G_CONSTANT s64 1
+...
+
+---
+name:            test_fconstant
+isSSA:           true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body: |
+  bb.0.entry:
+    ; CHECK-LABEL: name: test_fconstant
+    ; CHECK: %0(32) = G_FCONSTANT s32  float 1.000000e+00
+    ; CHECK: %1(64) = G_FCONSTANT s64  double 2.000000e+00
+
+    %0(32) = G_FCONSTANT s32 float 1.0
+    %1(64) = G_FCONSTANT s64 double 2.0
+...