]> granicus.if.org Git - llvm/commitdiff
[AArch64][GlobalISel] Add support for narrowScalar of G_ZEXT
authorAmara Emerson <aemerson@apple.com>
Wed, 21 Aug 2019 00:12:37 +0000 (00:12 +0000)
committerAmara Emerson <aemerson@apple.com>
Wed, 21 Aug 2019 00:12:37 +0000 (00:12 +0000)
We do this by merging the source with the high bits set to 0.

Differential Revision: https://reviews.llvm.org/D66181

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369480 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/GlobalISel/LegalizerHelper.cpp
lib/Target/AArch64/AArch64LegalizerInfo.cpp
lib/Target/X86/X86RegisterBankInfo.cpp
test/CodeGen/AArch64/GlobalISel/legalize-sext-128.mir [deleted file]
test/CodeGen/AArch64/GlobalISel/legalize-sext-zext-128.mir [new file with mode: 0644]
test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

index c5f23859783685c8985d0592107eca0722510b9d..26c25ba26d407211485a2a89a0132bdef6a6041a 100644 (file)
@@ -615,6 +615,24 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
     MI.eraseFromParent();
     return Legalized;
   }
+  case TargetOpcode::G_ZEXT: {
+    if (TypeIdx != 0)
+      return UnableToLegalize;
+
+    if (SizeOp0 % NarrowTy.getSizeInBits() != 0)
+      return UnableToLegalize;
+
+    // Generate a merge where the bottom bits are taken from the source, and
+    // zero everything else.
+    Register ZeroReg = MIRBuilder.buildConstant(NarrowTy, 0).getReg(0);
+    unsigned NumParts = SizeOp0 / NarrowTy.getSizeInBits();
+    SmallVector<Register, 4> Srcs = {MI.getOperand(1).getReg()};
+    for (unsigned Part = 1; Part < NumParts; ++Part)
+      Srcs.push_back(ZeroReg);
+    MIRBuilder.buildMerge(MI.getOperand(0).getReg(), Srcs);
+    MI.eraseFromParent();
+    return Legalized;
+  }
 
   case TargetOpcode::G_ADD: {
     // FIXME: add support for when SizeOp0 isn't an exact multiple of
index 3f8bce9b3b914da0042c17a2d8bdb09746aca46c..fcbd2c76f85dfc7e9a1d7e5eaa75fc8e2573f6be 100644 (file)
@@ -341,7 +341,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
     unsigned DstSize = Query.Types[0].getSizeInBits();
 
     if (DstSize == 128 && !Query.Types[0].isVector())
-      return false; // Extending to a scalar s128 is not legal.
+      return false; // Extending to a scalar s128 needs narrowing.
     
     // Make sure that we have something that will fit in a register, and
     // make sure it's a power of 2.
@@ -363,8 +363,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
 
     return true;
   };
-  getActionDefinitionsBuilder({G_ZEXT, G_ANYEXT}).legalIf(ExtLegalFunc);
-  getActionDefinitionsBuilder(G_SEXT)
+  getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
       .legalIf(ExtLegalFunc)
       .clampScalar(0, s64, s64); // Just for s128, others are handled above.
 
index 78fede3dcde21bc57ad95885d50992af7beaf7e9..daddf4231897dc0b7e4e8eaccdc0507a508459ba 100644 (file)
@@ -46,7 +46,9 @@ const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
   if (X86::GR8RegClass.hasSubClassEq(&RC) ||
       X86::GR16RegClass.hasSubClassEq(&RC) ||
       X86::GR32RegClass.hasSubClassEq(&RC) ||
-      X86::GR64RegClass.hasSubClassEq(&RC))
+      X86::GR64RegClass.hasSubClassEq(&RC) ||
+      X86::LOW32_ADDR_ACCESSRegClass.hasSubClassEq(&RC) ||
+      X86::LOW32_ADDR_ACCESS_RBPRegClass.hasSubClassEq(&RC))
     return getRegBank(X86::GPRRegBankID);
 
   if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-sext-128.mir b/test/CodeGen/AArch64/GlobalISel/legalize-sext-128.mir
deleted file mode 100644 (file)
index 7b26cea..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -march=aarch64 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
----
-name:            narrow_s128
-tracksRegLiveness: true
-body:             |
-  bb.1:
-    liveins: $x0, $x1
-
-    ; CHECK-LABEL: name: narrow_s128
-    ; CHECK: liveins: $x0, $x1
-    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
-    ; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
-    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
-    ; CHECK: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[COPY]], [[C]](s64)
-    ; CHECK: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[ASHR]](s64)
-    ; CHECK: G_STORE [[MV]](s128), [[COPY1]](p0) :: (store 16)
-    ; CHECK: RET_ReallyLR
-    %0:_(s64) = COPY $x0
-    %1:_(p0) = COPY $x1
-    %2:_(s128) = G_SEXT %0(s64)
-    G_STORE %2(s128), %1(p0) :: (store 16)
-    RET_ReallyLR
-
-...
diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-sext-zext-128.mir b/test/CodeGen/AArch64/GlobalISel/legalize-sext-zext-128.mir
new file mode 100644 (file)
index 0000000..d100167
--- /dev/null
@@ -0,0 +1,71 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -march=aarch64 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+---
+name:            narrow_sext_s128
+tracksRegLiveness: true
+body:             |
+  bb.1:
+    liveins: $x0, $x1
+
+    ; CHECK-LABEL: name: narrow_sext_s128
+    ; CHECK: liveins: $x0, $x1
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
+    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
+    ; CHECK: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[COPY]], [[C]](s64)
+    ; CHECK: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[ASHR]](s64)
+    ; CHECK: G_STORE [[MV]](s128), [[COPY1]](p0) :: (store 16)
+    ; CHECK: RET_ReallyLR
+    %0:_(s64) = COPY $x0
+    %1:_(p0) = COPY $x1
+    %2:_(s128) = G_SEXT %0(s64)
+    G_STORE %2(s128), %1(p0) :: (store 16)
+    RET_ReallyLR
+
+...
+---
+name:            narrow_zext_s128
+tracksRegLiveness: true
+body:             |
+  bb.1:
+    liveins: $x0, $x1
+
+    ; CHECK-LABEL: name: narrow_zext_s128
+    ; CHECK: liveins: $x0, $x1
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
+    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+    ; CHECK: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[C]](s64)
+    ; CHECK: G_STORE [[MV]](s128), [[COPY1]](p0) :: (store 16)
+    ; CHECK: RET_ReallyLR
+    %0:_(s64) = COPY $x0
+    %1:_(p0) = COPY $x1
+    %2:_(s128) = G_ZEXT %0(s64)
+    G_STORE %2(s128), %1(p0) :: (store 16)
+    RET_ReallyLR
+
+...
+---
+name:            narrow_zext_s192
+tracksRegLiveness: true
+body:             |
+  bb.1:
+    liveins: $x0, $x1
+
+    ; CHECK-LABEL: name: narrow_zext_s192
+    ; CHECK: liveins: $x0, $x1
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
+    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+    ; CHECK: [[MV:%[0-9]+]]:_(s192) = G_MERGE_VALUES [[COPY]](s64), [[C]](s64), [[C]](s64)
+    ; CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64), [[UV2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV]](s192)
+    ; CHECK: G_STORE [[UV]](s64), [[COPY1]](p0) :: (store 8)
+    ; CHECK: RET_ReallyLR
+    %0:_(s64) = COPY $x0
+    %1:_(p0) = COPY $x1
+    %2:_(s192) = G_ZEXT %0(s64)
+    %3:_(s64), %4:_(s64), %5:_(s64) = G_UNMERGE_VALUES %2(s192)
+    G_STORE %3, %1(p0) :: (store 8)
+    RET_ReallyLR
+
+...
index 72c22bc0511745e5eab67614380027fdc0389768..27b23a207876c92451e8ffacbb6d958aedc25f92 100644 (file)
 # DEBUG-NEXT: .. the first uncovered type index: 2, OK
 # DEBUG-NEXT: .. the first uncovered imm index: 0, OK
 # DEBUG-NEXT: G_SEXT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
+# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
 # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
 # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
 # DEBUG-NEXT: G_SEXT_INREG (opcode {{[0-9]+}}): 1 type index, 1 imm index