[llvm] f347d78 - [AArch64][GlobalISel] Add AArch64::G_DUPLANE[X] opcodes for lane duplicates.

Amara Emerson via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 5 11:18:24 PST 2020


Author: Amara Emerson
Date: 2020-11-05T11:18:11-08:00
New Revision: f347d78cca9a6b218e98d562b0e066488279602e

URL: https://github.com/llvm/llvm-project/commit/f347d78cca9a6b218e98d562b0e066488279602e
DIFF: https://github.com/llvm/llvm-project/commit/f347d78cca9a6b218e98d562b0e066488279602e.diff

LOG: [AArch64][GlobalISel] Add AArch64::G_DUPLANE[X] opcodes for lane duplicates.

These were previously handled by pattern matching shuffles in the selector, but
adding a new opcode and making it equivalent to the AArch64duplane SDAG node
allows us to select more patterns, like lane indexed FMLAs (patch adding a test
for that will be committed later).

The pattern matching code has been simply moved to postlegalize lowering.

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

Added: 
    llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir

Modified: 
    llvm/lib/Target/AArch64/AArch64Combine.td
    llvm/lib/Target/AArch64/AArch64InstrGISel.td
    llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
    llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp

Removed: 
    llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-to-duplane.mir


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index 560e362b074b..7e7db2f5df0b 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -83,6 +83,15 @@ def vashr_vlshr_imm : GICombineRule<
   (apply [{ applyVAshrLshrImm(*${root}, MRI, ${matchinfo}); }])
 >;
 
+def form_duplane_matchdata :
+  GIDefMatchData<"std::pair<unsigned, int>">;
+def form_duplane : GICombineRule <
+  (defs root:$root, form_duplane_matchdata:$matchinfo),
+  (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
+          [{ return matchDupLane(*${root}, MRI, ${matchinfo}); }]),
+  (apply [{ applyDupLane(*${root}, MRI, B, ${matchinfo}); }])
+>;
+
 def adjust_icmp_imm_matchdata :
   GIDefMatchData<"std::pair<uint64_t, CmpInst::Predicate>">;
 def adjust_icmp_imm : GICombineRule <
@@ -108,7 +117,7 @@ def extractvecelt_pairwise_add : GICombineRule<
 def AArch64PostLegalizerLoweringHelper
     : GICombinerHelper<"AArch64GenPostLegalizerLoweringHelper",
                        [shuffle_vector_pseudos, vashr_vlshr_imm,
-                        icmp_lowering]> {
+                        icmp_lowering, form_duplane]> {
   let DisableRuleOption = "aarch64postlegalizerlowering-disable-rule";
 }
 

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrGISel.td b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
index 1bd9ce25125d..ec7817beaeb8 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
@@ -88,6 +88,29 @@ def G_DUP: AArch64GenericInstruction {
   let InOperandList = (ins type1:$lane);
   let hasSideEffects = 0;
 }
+
+// Represents a lane duplicate operation.
+def G_DUPLANE8 : AArch64GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src, type1:$lane);
+  let hasSideEffects = 0;
+}
+def G_DUPLANE16 : AArch64GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src, type1:$lane);
+  let hasSideEffects = 0;
+}
+def G_DUPLANE32 : AArch64GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src, type1:$lane);
+  let hasSideEffects = 0;
+}
+def G_DUPLANE64 : AArch64GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src, type1:$lane);
+  let hasSideEffects = 0;
+}
+
 // Represents a trn1 instruction. Produced post-legalization from
 // G_SHUFFLE_VECTORs with appropriate masks.
 def G_TRN1 : AArch64GenericInstruction {
@@ -131,6 +154,10 @@ def : GINodeEquiv<G_UZP2, AArch64uzp2>;
 def : GINodeEquiv<G_ZIP1, AArch64zip1>;
 def : GINodeEquiv<G_ZIP2, AArch64zip2>;
 def : GINodeEquiv<G_DUP, AArch64dup>;
+def : GINodeEquiv<G_DUPLANE8, AArch64duplane8>;
+def : GINodeEquiv<G_DUPLANE16, AArch64duplane16>;
+def : GINodeEquiv<G_DUPLANE32, AArch64duplane32>;
+def : GINodeEquiv<G_DUPLANE64, AArch64duplane64>;
 def : GINodeEquiv<G_TRN1, AArch64trn1>;
 def : GINodeEquiv<G_TRN2, AArch64trn2>;
 def : GINodeEquiv<G_EXT, AArch64ext>;

diff  --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index f0333d18f3c1..1f2d256d72ca 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -136,8 +136,6 @@ class AArch64InstructionSelector : public InstructionSelector {
   bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
   bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
 
-  bool tryOptShuffleDupLane(MachineInstr &I, LLT DstTy, LLT SrcTy,
-                            ArrayRef<int> Mask, MachineRegisterInfo &MRI) const;
   bool selectShuffleVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
   bool selectExtractElt(MachineInstr &I, MachineRegisterInfo &MRI) const;
   bool selectConcatVectors(MachineInstr &I, MachineRegisterInfo &MRI) const;
@@ -4319,67 +4317,6 @@ MachineInstr *AArch64InstructionSelector::tryFoldIntegerCompare(
   return nullptr;
 }
 
-bool AArch64InstructionSelector::tryOptShuffleDupLane(
-    MachineInstr &I, LLT DstTy, LLT SrcTy, ArrayRef<int> Mask,
-    MachineRegisterInfo &MRI) const {
-  assert(I.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
-
-  // We assume that scalar->vector splats have been been handled in the
-  // post-legalizer combiner to G_DUP. However splats of a source vector's
-  // lane don't fit that pattern, detect it here:
-  //  %res = G_SHUFFLE_VECTOR %src:<n x ty>, undef, <n x i32> splat(lane-idx)
-  //    =>
-  //  %res = DUPv[N][Ty]lane %src, lane-idx
-  // FIXME: this case should be covered by re-implementing the perfect shuffle
-  // codegen mechanism.
-
-  auto LaneIdx = getSplatIndex(I);
-  if (!LaneIdx)
-    return false;
-
-  // The lane idx should be within the first source vector.
-  if (*LaneIdx >= SrcTy.getNumElements())
-    return false;
-
-  if (DstTy != SrcTy)
-    return false;
-
-  LLT ScalarTy = SrcTy.getElementType();
-  unsigned ScalarSize = ScalarTy.getSizeInBits();
-
-  unsigned Opc = 0;
-  switch (SrcTy.getNumElements()) {
-  case 2:
-    if (ScalarSize == 64)
-      Opc = AArch64::DUPv2i64lane;
-    break;
-  case 4:
-    if (ScalarSize == 32)
-      Opc = AArch64::DUPv4i32lane;
-    break;
-  case 8:
-    if (ScalarSize == 16)
-      Opc = AArch64::DUPv8i16lane;
-    break;
-  case 16:
-    if (ScalarSize == 8)
-      Opc = AArch64::DUPv16i8lane;
-    break;
-  default:
-    break;
-  }
-  if (!Opc)
-    return false;
-
-  MachineIRBuilder MIB(I);
-  auto Dup = MIB.buildInstr(Opc, {I.getOperand(0).getReg()},
-                            {I.getOperand(1).getReg()})
-                 .addImm(*LaneIdx);
-  constrainSelectedInstRegOperands(*Dup, TII, TRI, RBI);
-  I.eraseFromParent();
-  return true;
-}
-
 bool AArch64InstructionSelector::selectShuffleVector(
     MachineInstr &I, MachineRegisterInfo &MRI) const {
   const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
@@ -4401,9 +4338,6 @@ bool AArch64InstructionSelector::selectShuffleVector(
     return false;
   }
 
-  if (tryOptShuffleDupLane(I, DstTy, Src1Ty, Mask, MRI))
-    return true;
-
   unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
 
   SmallVector<Constant *, 64> CstIdxs;

diff  --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 9b433e0e90c6..645e85388490 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -550,6 +550,67 @@ bool applyAdjustICmpImmAndPred(
   return true;
 }
 
+bool matchDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
+                  std::pair<unsigned, int> &MatchInfo) {
+  assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+  Register Src1Reg = MI.getOperand(1).getReg();
+  const LLT SrcTy = MRI.getType(Src1Reg);
+  const LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+
+  auto LaneIdx = getSplatIndex(MI);
+  if (!LaneIdx)
+    return false;
+
+  // The lane idx should be within the first source vector.
+  if (*LaneIdx >= SrcTy.getNumElements())
+    return false;
+
+  if (DstTy != SrcTy)
+    return false;
+
+  LLT ScalarTy = SrcTy.getElementType();
+  unsigned ScalarSize = ScalarTy.getSizeInBits();
+
+  unsigned Opc = 0;
+  switch (SrcTy.getNumElements()) {
+  case 2:
+    if (ScalarSize == 64)
+      Opc = AArch64::G_DUPLANE64;
+    break;
+  case 4:
+    if (ScalarSize == 32)
+      Opc = AArch64::G_DUPLANE32;
+    break;
+  case 8:
+    if (ScalarSize == 16)
+      Opc = AArch64::G_DUPLANE16;
+    break;
+  case 16:
+    if (ScalarSize == 8)
+      Opc = AArch64::G_DUPLANE8;
+    break;
+  default:
+    break;
+  }
+  if (!Opc)
+    return false;
+
+  MatchInfo.first = Opc;
+  MatchInfo.second = *LaneIdx;
+  return true;
+}
+
+bool applyDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
+                  MachineIRBuilder &B, std::pair<unsigned, int> &MatchInfo) {
+  assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+  B.setInstrAndDebugLoc(MI);
+  auto Lane = B.buildConstant(LLT::scalar(64), MatchInfo.second);
+  B.buildInstr(MatchInfo.first, {MI.getOperand(0).getReg()},
+               {MI.getOperand(1).getReg(), Lane});
+  MI.eraseFromParent();
+  return true;
+}
+
 #define AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS
 #include "AArch64GenPostLegalizeGILowering.inc"
 #undef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir
new file mode 100644
index 000000000000..948eb9060565
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir
@@ -0,0 +1,120 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=aarch64 -run-pass=aarch64-postlegalizer-lowering -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=aarch64 -global-isel -start-before=aarch64-postlegalizer-lowering -stop-after=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=SELECTED
+
+---
+name:            duplane64
+alignment:       4
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $q0
+
+    ; CHECK-LABEL: name: duplane64
+    ; CHECK: liveins: $q0
+    ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
+    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+    ; CHECK: [[DUPLANE64_:%[0-9]+]]:_(<2 x s64>) = G_DUPLANE64 [[COPY]], [[C]](s64)
+    ; CHECK: $q0 = COPY [[DUPLANE64_]](<2 x s64>)
+    ; CHECK: RET_ReallyLR implicit $q0
+    ; SELECTED-LABEL: name: duplane64
+    ; SELECTED: liveins: $q0
+    ; SELECTED: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
+    ; SELECTED: [[DUPv2i64lane:%[0-9]+]]:fpr128 = DUPv2i64lane [[COPY]], 0
+    ; SELECTED: $q0 = COPY [[DUPv2i64lane]]
+    ; SELECTED: RET_ReallyLR implicit $q0
+    %1:_(<2 x s64>) = COPY $q0
+    %2:_(<2 x s64>) = G_IMPLICIT_DEF
+    %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0)
+    $q0 = COPY %4(<2 x s64>)
+    RET_ReallyLR implicit $q0
+
+...
+---
+name:            duplane32
+alignment:       4
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $q0
+
+    ; CHECK-LABEL: name: duplane32
+    ; CHECK: liveins: $q0
+    ; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
+    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+    ; CHECK: [[DUPLANE32_:%[0-9]+]]:_(<4 x s32>) = G_DUPLANE32 [[COPY]], [[C]](s64)
+    ; CHECK: $q0 = COPY [[DUPLANE32_]](<4 x s32>)
+    ; CHECK: RET_ReallyLR implicit $q0
+    ; SELECTED-LABEL: name: duplane32
+    ; SELECTED: liveins: $q0
+    ; SELECTED: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
+    ; SELECTED: [[DUPv4i32lane:%[0-9]+]]:fpr128 = DUPv4i32lane [[COPY]], 0
+    ; SELECTED: $q0 = COPY [[DUPv4i32lane]]
+    ; SELECTED: RET_ReallyLR implicit $q0
+    %1:_(<4 x s32>) = COPY $q0
+    %2:_(<4 x s32>) = G_IMPLICIT_DEF
+    %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0)
+    $q0 = COPY %4(<4 x s32>)
+    RET_ReallyLR implicit $q0
+
+...
+---
+name:            duplane16
+alignment:       4
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $q0
+
+    ; CHECK-LABEL: name: duplane16
+    ; CHECK: liveins: $q0
+    ; CHECK: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0
+    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+    ; CHECK: [[DUPLANE16_:%[0-9]+]]:_(<8 x s16>) = G_DUPLANE16 [[COPY]], [[C]](s64)
+    ; CHECK: $q0 = COPY [[DUPLANE16_]](<8 x s16>)
+    ; CHECK: RET_ReallyLR implicit $q0
+    ; SELECTED-LABEL: name: duplane16
+    ; SELECTED: liveins: $q0
+    ; SELECTED: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
+    ; SELECTED: [[DUPv8i16lane:%[0-9]+]]:fpr128 = DUPv8i16lane [[COPY]], 0
+    ; SELECTED: $q0 = COPY [[DUPv8i16lane]]
+    ; SELECTED: RET_ReallyLR implicit $q0
+    %1:_(<8 x s16>) = COPY $q0
+    %2:_(<8 x s16>) = G_IMPLICIT_DEF
+    %4:_(<8 x s16>) = G_SHUFFLE_VECTOR %1(<8 x s16>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0)
+    $q0 = COPY %4(<8 x s16>)
+    RET_ReallyLR implicit $q0
+
+...
+---
+name:            duplane8
+alignment:       4
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $q0
+
+    ; CHECK-LABEL: name: duplane8
+    ; CHECK: liveins: $q0
+    ; CHECK: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0
+    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+    ; CHECK: [[DUPLANE8_:%[0-9]+]]:_(<16 x s8>) = G_DUPLANE8 [[COPY]], [[C]](s64)
+    ; CHECK: $q0 = COPY [[DUPLANE8_]](<16 x s8>)
+    ; CHECK: RET_ReallyLR implicit $q0
+    ; SELECTED-LABEL: name: duplane8
+    ; SELECTED: liveins: $q0
+    ; SELECTED: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
+    ; SELECTED: [[DUPv16i8lane:%[0-9]+]]:fpr128 = DUPv16i8lane [[COPY]], 0
+    ; SELECTED: $q0 = COPY [[DUPv16i8lane]]
+    ; SELECTED: RET_ReallyLR implicit $q0
+    %1:_(<16 x s8>) = COPY $q0
+    %2:_(<16 x s8>) = G_IMPLICIT_DEF
+    %4:_(<16 x s8>) = G_SHUFFLE_VECTOR %1(<16 x s8>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+    $q0 = COPY %4(<16 x s8>)
+    RET_ReallyLR implicit $q0
+
+...

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-to-duplane.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-to-duplane.mir
deleted file mode 100644
index 5743c489fa20..000000000000
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-to-duplane.mir
+++ /dev/null
@@ -1,103 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=aarch64 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
-...
----
-name:            duplane_v16i8
-alignment:       4
-legalized:       true
-regBankSelected: true
-tracksRegLiveness: true
-liveins:
-  - { reg: '$q0' }
-body:             |
-  bb.1:
-    liveins: $q0
-
-    ; CHECK-LABEL: name: duplane_v16i8
-    ; CHECK: liveins: $q0
-    ; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
-    ; CHECK: [[DUPv16i8lane:%[0-9]+]]:fpr128 = DUPv16i8lane [[COPY]], 0
-    ; CHECK: $q0 = COPY [[DUPv16i8lane]]
-    ; CHECK: RET_ReallyLR implicit $q0
-    %0:fpr(<16 x s8>) = COPY $q0
-    %2:fpr(<16 x s8>) = G_IMPLICIT_DEF
-    %1:fpr(<16 x s8>) = G_SHUFFLE_VECTOR %0(<16 x s8>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-    $q0 = COPY %1(<16 x s8>)
-    RET_ReallyLR implicit $q0
-
-...
----
-name:            duplane_v8i16
-alignment:       4
-legalized:       true
-regBankSelected: true
-tracksRegLiveness: true
-liveins:
-  - { reg: '$q0' }
-body:             |
-  bb.1:
-    liveins: $q0
-
-    ; CHECK-LABEL: name: duplane_v8i16
-    ; CHECK: liveins: $q0
-    ; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
-    ; CHECK: [[DUPv8i16lane:%[0-9]+]]:fpr128 = DUPv8i16lane [[COPY]], 0
-    ; CHECK: $q0 = COPY [[DUPv8i16lane]]
-    ; CHECK: RET_ReallyLR implicit $q0
-    %0:fpr(<8 x s16>) = COPY $q0
-    %2:fpr(<8 x s16>) = G_IMPLICIT_DEF
-    %1:fpr(<8 x s16>) = G_SHUFFLE_VECTOR %0(<8 x s16>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0)
-    $q0 = COPY %1(<8 x s16>)
-    RET_ReallyLR implicit $q0
-
-...
----
-name:            duplane_v4f32
-alignment:       4
-legalized:       true
-regBankSelected: true
-tracksRegLiveness: true
-liveins:
-  - { reg: '$q0' }
-body:             |
-  bb.1:
-    liveins: $q0
-
-    ; CHECK-LABEL: name: duplane_v4f32
-    ; CHECK: liveins: $q0
-    ; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
-    ; CHECK: [[DUPv4i32lane:%[0-9]+]]:fpr128 = DUPv4i32lane [[COPY]], 0
-    ; CHECK: $q0 = COPY [[DUPv4i32lane]]
-    ; CHECK: RET_ReallyLR implicit $q0
-    %0:fpr(<4 x s32>) = COPY $q0
-    %2:fpr(<4 x s32>) = G_IMPLICIT_DEF
-    %1:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %2, shufflemask(0, 0, 0, 0)
-    $q0 = COPY %1(<4 x s32>)
-    RET_ReallyLR implicit $q0
-
-...
----
-name:            duplane_v2i64
-alignment:       4
-legalized:       true
-regBankSelected: true
-tracksRegLiveness: true
-liveins:
-  - { reg: '$q0' }
-body:             |
-  bb.1:
-    liveins: $q0
-
-    ; CHECK-LABEL: name: duplane_v2i64
-    ; CHECK: liveins: $q0
-    ; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
-    ; CHECK: [[DUPv2i64lane:%[0-9]+]]:fpr128 = DUPv2i64lane [[COPY]], 0
-    ; CHECK: $q0 = COPY [[DUPv2i64lane]]
-    ; CHECK: RET_ReallyLR implicit $q0
-    %0:fpr(<2 x s64>) = COPY $q0
-    %2:fpr(<2 x s64>) = G_IMPLICIT_DEF
-    %1:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(0, 0)
-    $q0 = COPY %1(<2 x s64>)
-    RET_ReallyLR implicit $q0
-
-...


        


More information about the llvm-commits mailing list