GlobalISel: Implement moreElementsVector for G_EXTRACT source

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354348 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 5fab415..8b9b4fd 100644
--- a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -2398,6 +2398,13 @@
     Observer.changedInstr(MI);
     return Legalized;
   }
+  case TargetOpcode::G_EXTRACT:
+    if (TypeIdx != 1)
+      return UnableToLegalize;
+    Observer.changingInstr(MI);
+    moreElementsVectorSrc(MI, MoreTy, 1);
+    Observer.changedInstr(MI);
+    return Legalized;
   default:
     return UnableToLegalize;
   }
diff --git a/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index 64ef92b..941f781 100644
--- a/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -533,6 +533,7 @@
         return (Ty0.getSizeInBits() % 16 == 0) &&
                (Ty1.getSizeInBits() % 16 == 0);
       })
+      .moreElementsIf(isSmallOddVector(1), oneMoreElement(1))
       .widenScalarIf(
           [=](const LegalityQuery &Query) {
             const LLT Ty1 = Query.Types[1];
diff --git a/test/CodeGen/AMDGPU/GlobalISel/legalize-extract.mir b/test/CodeGen/AMDGPU/GlobalISel/legalize-extract.mir
index 58ed38d..5931c69 100644
--- a/test/CodeGen/AMDGPU/GlobalISel/legalize-extract.mir
+++ b/test/CodeGen/AMDGPU/GlobalISel/legalize-extract.mir
@@ -467,11 +467,11 @@
     ; CHECK: [[DEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
     ; CHECK: [[TRUNC:%[0-9]+]]:_(<4 x s8>) = G_TRUNC [[DEF]](<4 x s32>)
     ; CHECK: [[EXTRACT:%[0-9]+]]:_(<3 x s8>) = G_EXTRACT [[TRUNC]](<4 x s8>), 0
-    ; CHECK: [[ANYEXT:%[0-9]+]]:_(<3 x s16>) = G_ANYEXT [[EXTRACT]](<3 x s8>)
-    ; CHECK: [[EXTRACT1:%[0-9]+]]:_(s16) = G_EXTRACT [[ANYEXT]](<3 x s16>), 32
-    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[EXTRACT1]](s16)
-    ; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC1]](s8)
-    ; CHECK: $vgpr0 = COPY [[ANYEXT1]](s32)
+    ; CHECK: [[DEF1:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF
+    ; CHECK: [[INSERT:%[0-9]+]]:_(<4 x s8>) = G_INSERT [[DEF1]], [[EXTRACT]](<3 x s8>), 0
+    ; CHECK: [[EXTRACT1:%[0-9]+]]:_(s8) = G_EXTRACT [[INSERT]](<4 x s8>), 16
+    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT1]](s8)
+    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
     %0:_(<3 x s8>) = G_IMPLICIT_DEF
     %1:_(s8) = G_EXTRACT %0, 16
     %2:_(s32) = G_ANYEXT %1
@@ -486,11 +486,11 @@
     ; CHECK: [[DEF:%[0-9]+]]:_(<6 x s32>) = G_IMPLICIT_DEF
     ; CHECK: [[TRUNC:%[0-9]+]]:_(<6 x s1>) = G_TRUNC [[DEF]](<6 x s32>)
     ; CHECK: [[EXTRACT:%[0-9]+]]:_(<5 x s1>) = G_EXTRACT [[TRUNC]](<6 x s1>), 0
-    ; CHECK: [[ANYEXT:%[0-9]+]]:_(<5 x s16>) = G_ANYEXT [[EXTRACT]](<5 x s1>)
-    ; CHECK: [[EXTRACT1:%[0-9]+]]:_(s16) = G_EXTRACT [[ANYEXT]](<5 x s16>), 64
-    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s1) = G_TRUNC [[EXTRACT1]](s16)
-    ; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC1]](s1)
-    ; CHECK: $vgpr0 = COPY [[ANYEXT1]](s32)
+    ; CHECK: [[DEF1:%[0-9]+]]:_(<6 x s1>) = G_IMPLICIT_DEF
+    ; CHECK: [[INSERT:%[0-9]+]]:_(<6 x s1>) = G_INSERT [[DEF1]], [[EXTRACT]](<5 x s1>), 0
+    ; CHECK: [[EXTRACT1:%[0-9]+]]:_(s1) = G_EXTRACT [[INSERT]](<6 x s1>), 4
+    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT1]](s1)
+    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
     %0:_(<5 x s1>) = G_IMPLICIT_DEF
     %1:_(s1) = G_EXTRACT %0, 4
     %2:_(s32) = G_ANYEXT %1
@@ -752,6 +752,23 @@
 ...
 
 ---
+name: extract_s16_v3s16_offset0
+body: |
+  bb.0:
+
+    ; CHECK-LABEL: name: extract_s16_v3s16_offset0
+    ; CHECK: [[DEF:%[0-9]+]]:_(<4 x s16>) = G_IMPLICIT_DEF
+    ; CHECK: [[EXTRACT:%[0-9]+]]:_(<3 x s16>) = G_EXTRACT [[DEF]](<4 x s16>), 0
+    ; CHECK: [[EXTRACT1:%[0-9]+]]:_(s16) = G_EXTRACT [[EXTRACT]](<3 x s16>), 0
+    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT1]](s16)
+    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
+    %0:_(<3 x s16>) = G_IMPLICIT_DEF
+    %1:_(s16) = G_EXTRACT %0, 0
+    %2:_(s32) = G_ANYEXT %1
+    $vgpr0 = COPY %2
+...
+
+---
 name: test_extract_s8_s64_offset16
 body: |
   bb.0:
@@ -816,3 +833,34 @@
     %2:_(s32) = G_ANYEXT %1
     $vgpr0 = COPY %2
 ...
+
+---
+name: extract_v2s16_v3s16_offset0
+body: |
+  bb.0:
+
+    ; CHECK-LABEL: name: extract_v2s16_v3s16_offset0
+    ; CHECK: [[DEF:%[0-9]+]]:_(<4 x s16>) = G_IMPLICIT_DEF
+    ; CHECK: [[EXTRACT:%[0-9]+]]:_(<3 x s16>) = G_EXTRACT [[DEF]](<4 x s16>), 0
+    ; CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s16>) = G_EXTRACT [[EXTRACT]](<3 x s16>), 0
+    ; CHECK: $vgpr0 = COPY [[EXTRACT1]](<2 x s16>)
+    %0:_(<3 x s16>) = G_IMPLICIT_DEF
+    %1:_(<2 x s16>) = G_EXTRACT %0, 0
+    $vgpr0 = COPY %1
+...
+
+---
+name: extract_v2s16_v5s16_offset0
+body: |
+  bb.0:
+
+    ; CHECK-LABEL: name: extract_v2s16_v5s16_offset0
+    ; CHECK: [[DEF:%[0-9]+]]:_(<6 x s32>) = G_IMPLICIT_DEF
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(<6 x s16>) = G_TRUNC [[DEF]](<6 x s32>)
+    ; CHECK: [[EXTRACT:%[0-9]+]]:_(<5 x s16>) = G_EXTRACT [[TRUNC]](<6 x s16>), 0
+    ; CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s16>) = G_EXTRACT [[EXTRACT]](<5 x s16>), 0
+    ; CHECK: $vgpr0 = COPY [[EXTRACT1]](<2 x s16>)
+    %0:_(<5 x s16>) = G_IMPLICIT_DEF
+    %1:_(<2 x s16>) = G_EXTRACT %0, 0
+    $vgpr0 = COPY %1
+...