[llvm] r302410 - [GlobalISel][X86] G_MUL legalizer/selector support.

Igor Breger via llvm-commits llvm-commits at lists.llvm.org
Mon May 8 02:03:38 PDT 2017


Author: ibreger
Date: Mon May  8 04:03:37 2017
New Revision: 302410

URL: http://llvm.org/viewvc/llvm-project?rev=302410&view=rev
Log:
[GlobalISel][X86] G_MUL legalizer/selector support.

Summary:
G_MUL legalizer/selector/regbank support.
Use only Tablegen-erated instruction selection.
This patch dealing with legal operations only.

Reviewers: zvi, guyblank

Reviewed By: guyblank

Subscribers: krytarowski, rovka, kristof.beyls, llvm-commits

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

Added:
    llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v128.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v256.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v512.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/mul-scalar.ll
    llvm/trunk/test/CodeGen/X86/GlobalISel/mul-vec.ll
    llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX2.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX512.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-scalar.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-vec.mir
Modified:
    llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
    llvm/trunk/lib/Target/X86/X86LegalizerInfo.h
    llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir

Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=302410&r1=302409&r2=302410&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp Mon May  8 04:03:37 2017
@@ -34,6 +34,11 @@ X86LegalizerInfo::X86LegalizerInfo(const
   setLegalizerInfo64bit();
   setLegalizerInfoSSE1();
   setLegalizerInfoSSE2();
+  setLegalizerInfoSSE41();
+  setLegalizerInfoAVX2();
+  setLegalizerInfoAVX512();
+  setLegalizerInfoAVX512DQ();
+  setLegalizerInfoAVX512BW();
 
   computeTables();
 }
@@ -50,7 +55,7 @@ void X86LegalizerInfo::setLegalizerInfo3
   const LLT s32 = LLT::scalar(32);
   const LLT s64 = LLT::scalar(64);
 
-  for (unsigned BinOp : {G_ADD, G_SUB})
+  for (unsigned BinOp : {G_ADD, G_SUB, G_MUL})
     for (auto Ty : {s8, s16, s32})
       setAction({BinOp, Ty}, Legal);
 
@@ -94,7 +99,7 @@ void X86LegalizerInfo::setLegalizerInfo6
   const LLT s32 = LLT::scalar(32);
   const LLT s64 = LLT::scalar(64);
 
-  for (unsigned BinOp : {G_ADD, G_SUB})
+  for (unsigned BinOp : {G_ADD, G_SUB, G_MUL})
     for (auto Ty : {s8, s16, s32, s64})
       setAction({BinOp, Ty}, Legal);
 
@@ -149,6 +154,7 @@ void X86LegalizerInfo::setLegalizerInfoS
     return;
 
   const LLT s64 = LLT::scalar(64);
+  const LLT v8s16 = LLT::vector(8, 16);
   const LLT v4s32 = LLT::vector(4, 32);
   const LLT v2s64 = LLT::vector(2, 64);
 
@@ -159,4 +165,83 @@ void X86LegalizerInfo::setLegalizerInfoS
   for (unsigned BinOp : {G_ADD, G_SUB})
     for (auto Ty : {v4s32})
       setAction({BinOp, Ty}, Legal);
+
+  setAction({G_MUL, v8s16}, Legal);
+}
+
+void X86LegalizerInfo::setLegalizerInfoSSE41() {
+  if (!Subtarget.hasSSE41())
+    return;
+
+  const LLT v4s32 = LLT::vector(4, 32);
+
+  setAction({G_MUL, v4s32}, Legal);
+}
+
+void X86LegalizerInfo::setLegalizerInfoAVX2() {
+  if (!Subtarget.hasAVX2())
+    return;
+
+  const LLT v16s16 = LLT::vector(16, 16);
+  const LLT v8s32 = LLT::vector(8, 32);
+
+  for (auto Ty : {v16s16, v8s32})
+    setAction({G_MUL, Ty}, Legal);
+}
+
+void X86LegalizerInfo::setLegalizerInfoAVX512() {
+  if (!Subtarget.hasAVX512())
+    return;
+
+  const LLT v16s32 = LLT::vector(16, 32);
+
+  setAction({G_MUL, v16s32}, Legal);
+
+  /************ VLX *******************/
+  if (!Subtarget.hasVLX())
+    return;
+
+  const LLT v4s32 = LLT::vector(4, 32);
+  const LLT v8s32 = LLT::vector(8, 32);
+
+  for (auto Ty : {v4s32, v8s32})
+    setAction({G_MUL, Ty}, Legal);
+}
+
+void X86LegalizerInfo::setLegalizerInfoAVX512DQ() {
+  if (!(Subtarget.hasAVX512() && Subtarget.hasDQI()))
+    return;
+
+  const LLT v8s64 = LLT::vector(8, 64);
+
+  setAction({G_MUL, v8s64}, Legal);
+
+  /************ VLX *******************/
+  if (!Subtarget.hasVLX())
+    return;
+
+  const LLT v2s64 = LLT::vector(2, 64);
+  const LLT v4s64 = LLT::vector(4, 64);
+
+  for (auto Ty : {v2s64, v4s64})
+    setAction({G_MUL, Ty}, Legal);
+}
+
+void X86LegalizerInfo::setLegalizerInfoAVX512BW() {
+  if (!(Subtarget.hasAVX512() && Subtarget.hasBWI()))
+    return;
+
+  const LLT v32s16 = LLT::vector(32, 16);
+
+  setAction({G_MUL, v32s16}, Legal);
+
+  /************ VLX *******************/
+  if (!Subtarget.hasVLX())
+    return;
+
+  const LLT v8s16 = LLT::vector(8, 16);
+  const LLT v16s16 = LLT::vector(16, 16);
+
+  for (auto Ty : {v8s16, v16s16})
+    setAction({G_MUL, Ty}, Legal);
 }

Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.h?rev=302410&r1=302409&r2=302410&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.h Mon May  8 04:03:37 2017
@@ -38,6 +38,11 @@ private:
   void setLegalizerInfo64bit();
   void setLegalizerInfoSSE1();
   void setLegalizerInfoSSE2();
+  void setLegalizerInfoSSE41();
+  void setLegalizerInfoAVX2();
+  void setLegalizerInfoAVX512();
+  void setLegalizerInfoAVX512DQ();
+  void setLegalizerInfoAVX512BW();
 };
 } // namespace llvm
 #endif

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir Mon May  8 04:03:37 2017
@@ -0,0 +1,115 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
+
+--- |
+  define i16 @test_mul_i16(i16 %arg1, i16 %arg2) {
+    %ret = mul i16 %arg1, %arg2
+    ret i16 %ret
+  }
+
+  define i32 @test_mul_i32(i32 %arg1, i32 %arg2) {
+    %ret = mul i32 %arg1, %arg2
+    ret i32 %ret
+  }
+
+  define i64 @test_mul_i64(i64 %arg1, i64 %arg2) {
+    %ret = mul i64 %arg1, %arg2
+    ret i64 %ret
+  }
+
+...
+---
+name:            test_mul_i16
+# CHECK-LABEL: name:  test_mul_i16
+alignment:       4
+legalized:       false
+regBankSelected: false
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: _ }
+# CHECK-NEXT:   - { id: 1, class: _ }
+# CHECK-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# CHECK:      body:             |
+# CHECK-NEXT:   bb.0 (%ir-block.0):
+# CHECK-NEXT:     %0(s16) = COPY %edi
+# CHECK-NEXT:     %1(s16) = COPY %esi
+# CHECK-NEXT:     %2(s16) = G_MUL %0, %1
+# CHECK-NEXT:     %ax = COPY %2(s16)
+# CHECK-NEXT:     RET 0, implicit %ax
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %edi, %esi
+
+    %0(s16) = COPY %edi
+    %1(s16) = COPY %esi
+    %2(s16) = G_MUL %0, %1
+    %ax = COPY %2(s16)
+    RET 0, implicit %ax
+
+...
+---
+name:            test_mul_i32
+# CHECK-LABEL: name:  test_mul_i32
+alignment:       4
+legalized:       false
+regBankSelected: false
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: _ }
+# CHECK-NEXT:   - { id: 1, class: _ }
+# CHECK-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# CHECK:      body:             |
+# CHECK-NEXT:   bb.0 (%ir-block.0):
+# CHECK-NEXT:     %0(s32) = COPY %edi
+# CHECK-NEXT:     %1(s32) = COPY %esi
+# CHECK-NEXT:     %2(s32) = G_MUL %0, %1
+# CHECK-NEXT:     %eax = COPY %2(s32)
+# CHECK-NEXT:     RET 0, implicit %eax
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %edi, %esi
+
+    %0(s32) = COPY %edi
+    %1(s32) = COPY %esi
+    %2(s32) = G_MUL %0, %1
+    %eax = COPY %2(s32)
+    RET 0, implicit %eax
+
+...
+---
+name:            test_mul_i64
+# CHECK-LABEL: name:  test_mul_i64
+alignment:       4
+legalized:       false
+regBankSelected: false
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: _ }
+# CHECK-NEXT:   - { id: 1, class: _ }
+# CHECK-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# CHECK:      body:             |
+# CHECK-NEXT:   bb.0 (%ir-block.0):
+# CHECK-NEXT:     %0(s64) = COPY %rdi
+# CHECK-NEXT:     %1(s64) = COPY %rsi
+# CHECK-NEXT:     %2(s64) = G_MUL %0, %1
+# CHECK-NEXT:     %rax = COPY %2(s64)
+# CHECK-NEXT:     RET 0, implicit %rax
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %rdi, %rsi
+
+    %0(s64) = COPY %rdi
+    %1(s64) = COPY %rsi
+    %2(s64) = G_MUL %0, %1
+    %rax = COPY %2(s64)
+    RET 0, implicit %rax
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v128.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v128.mir?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v128.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v128.mir Mon May  8 04:03:37 2017
@@ -0,0 +1,111 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL
+--- |
+  define <8 x i16> @test_mul_v8i16(<8 x i16> %arg1, <8 x i16> %arg2) #0 {
+    %ret = mul <8 x i16> %arg1, %arg2
+    ret <8 x i16> %ret
+  }
+
+  define <4 x i32> @test_mul_v4i32(<4 x i32> %arg1, <4 x i32> %arg2) #0 {
+    %ret = mul <4 x i32> %arg1, %arg2
+    ret <4 x i32> %ret
+  }
+
+  define <2 x i64> @test_mul_v2i64(<2 x i64> %arg1, <2 x i64> %arg2) #1 {
+    %ret = mul <2 x i64> %arg1, %arg2
+    ret <2 x i64> %ret
+  }
+
+  attributes #0 = { "target-features"="+sse4.1" }
+  attributes #1 = { "target-features"="+sse4.1,+avx512vl,+avx512f,+avx512dq" }
+
+...
+---
+name:            test_mul_v8i16
+# ALL-LABEL: name:  test_mul_v8i16
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<8 x s16>) = COPY %xmm0
+# ALL-NEXT:     %1(<8 x s16>) = COPY %xmm1
+# ALL-NEXT:     %2(<8 x s16>) = G_MUL %0, %1
+# ALL-NEXT:     %xmm0 = COPY %2(<8 x s16>)
+# ALL-NEXT:     RET 0, implicit %xmm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<8 x s16>) = COPY %xmm0
+    %1(<8 x s16>) = COPY %xmm1
+    %2(<8 x s16>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<8 x s16>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v4i32
+# ALL-LABEL: name:  test_mul_v4i32
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<4 x s32>) = COPY %xmm0
+# ALL-NEXT:     %1(<4 x s32>) = COPY %xmm1
+# ALL-NEXT:     %2(<4 x s32>) = G_MUL %0, %1
+# ALL-NEXT:     %xmm0 = COPY %2(<4 x s32>)
+# ALL-NEXT:     RET 0, implicit %xmm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<4 x s32>) = COPY %xmm0
+    %1(<4 x s32>) = COPY %xmm1
+    %2(<4 x s32>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<4 x s32>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v2i64
+# ALL-LABEL: name:  test_mul_v2i64
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<2 x s64>) = COPY %xmm0
+# ALL-NEXT:     %1(<2 x s64>) = COPY %xmm1
+# ALL-NEXT:     %2(<2 x s64>) = G_MUL %0, %1
+# ALL-NEXT:     %xmm0 = COPY %2(<2 x s64>)
+# ALL-NEXT:     RET 0, implicit %xmm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<2 x s64>) = COPY %xmm0
+    %1(<2 x s64>) = COPY %xmm1
+    %2(<2 x s64>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<2 x s64>)
+    RET 0, implicit %xmm0
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v256.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v256.mir?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v256.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v256.mir Mon May  8 04:03:37 2017
@@ -0,0 +1,111 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL
+--- |
+  define <16 x i16> @test_mul_v16i16(<16 x i16> %arg1, <16 x i16> %arg2) #0 {
+    %ret = mul <16 x i16> %arg1, %arg2
+    ret <16 x i16> %ret
+  }
+
+  define <8 x i32> @test_mul_v8i32(<8 x i32> %arg1, <8 x i32> %arg2) #0 {
+    %ret = mul <8 x i32> %arg1, %arg2
+    ret <8 x i32> %ret
+  }
+
+  define <4 x i64> @test_mul_v4i64(<4 x i64> %arg1, <4 x i64> %arg2) #1 {
+    %ret = mul <4 x i64> %arg1, %arg2
+    ret <4 x i64> %ret
+  }
+
+  attributes #0 = { "target-features"="+avx2" }
+  attributes #1 = { "target-features"="+avx2,+avx512vl,+avx512f,+avx512dq" }
+
+...
+---
+name:            test_mul_v16i16
+# ALL-LABEL: name:  test_mul_v16i16
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<16 x s16>) = COPY %ymm0
+# ALL-NEXT:     %1(<16 x s16>) = COPY %ymm1
+# ALL-NEXT:     %2(<16 x s16>) = G_MUL %0, %1
+# ALL-NEXT:     %ymm0 = COPY %2(<16 x s16>)
+# ALL-NEXT:     RET 0, implicit %ymm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %ymm0, %ymm1
+
+    %0(<16 x s16>) = COPY %ymm0
+    %1(<16 x s16>) = COPY %ymm1
+    %2(<16 x s16>) = G_MUL %0, %1
+    %ymm0 = COPY %2(<16 x s16>)
+    RET 0, implicit %ymm0
+
+...
+---
+name:            test_mul_v8i32
+# ALL-LABEL: name:  test_mul_v8i32
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<8 x s32>) = COPY %ymm0
+# ALL-NEXT:     %1(<8 x s32>) = COPY %ymm1
+# ALL-NEXT:     %2(<8 x s32>) = G_MUL %0, %1
+# ALL-NEXT:     %ymm0 = COPY %2(<8 x s32>)
+# ALL-NEXT:     RET 0, implicit %ymm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %ymm0, %ymm1
+
+    %0(<8 x s32>) = COPY %ymm0
+    %1(<8 x s32>) = COPY %ymm1
+    %2(<8 x s32>) = G_MUL %0, %1
+    %ymm0 = COPY %2(<8 x s32>)
+    RET 0, implicit %ymm0
+
+...
+---
+name:            test_mul_v4i64
+# ALL-LABEL: name:  test_mul_v4i64
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<4 x s64>) = COPY %ymm0
+# ALL-NEXT:     %1(<4 x s64>) = COPY %ymm1
+# ALL-NEXT:     %2(<4 x s64>) = G_MUL %0, %1
+# ALL-NEXT:     %ymm0 = COPY %2(<4 x s64>)
+# ALL-NEXT:     RET 0, implicit %ymm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %ymm0, %ymm1
+
+    %0(<4 x s64>) = COPY %ymm0
+    %1(<4 x s64>) = COPY %ymm1
+    %2(<4 x s64>) = G_MUL %0, %1
+    %ymm0 = COPY %2(<4 x s64>)
+    RET 0, implicit %ymm0
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v512.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v512.mir?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v512.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-mul-v512.mir Mon May  8 04:03:37 2017
@@ -0,0 +1,113 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL
+
+--- |
+  define <32 x i16> @test_mul_v32i16(<32 x i16> %arg1, <32 x i16> %arg2) #0 {
+    %ret = mul <32 x i16> %arg1, %arg2
+    ret <32 x i16> %ret
+  }
+
+  define <16 x i32> @test_mul_v16i32(<16 x i32> %arg1, <16 x i32> %arg2) #1 {
+    %ret = mul <16 x i32> %arg1, %arg2
+    ret <16 x i32> %ret
+  }
+
+  define <8 x i64> @test_mul_v8i64(<8 x i64> %arg1, <8 x i64> %arg2) #2 {
+    %ret = mul <8 x i64> %arg1, %arg2
+    ret <8 x i64> %ret
+  }
+
+  attributes #0 = { "target-features"="+avx512f,+avx512bw" }
+  attributes #1 = { "target-features"="+avx512f" }
+  attributes #2 = { "target-features"="+avx512f,+avx512dq" }
+
+...
+---
+name:            test_mul_v32i16
+# ALL-LABEL: name:  test_mul_v32i16
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<32 x s16>) = COPY %zmm0
+# ALL-NEXT:     %1(<32 x s16>) = COPY %zmm1
+# ALL-NEXT:     %2(<32 x s16>) = G_MUL %0, %1
+# ALL-NEXT:     %zmm0 = COPY %2(<32 x s16>)
+# ALL-NEXT:     RET 0, implicit %zmm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %zmm0, %zmm1
+
+    %0(<32 x s16>) = COPY %zmm0
+    %1(<32 x s16>) = COPY %zmm1
+    %2(<32 x s16>) = G_MUL %0, %1
+    %zmm0 = COPY %2(<32 x s16>)
+    RET 0, implicit %zmm0
+
+...
+---
+name:            test_mul_v16i32
+# ALL-LABEL: name:  test_mul_v16i32
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<16 x s32>) = COPY %zmm0
+# ALL-NEXT:     %1(<16 x s32>) = COPY %zmm1
+# ALL-NEXT:     %2(<16 x s32>) = G_MUL %0, %1
+# ALL-NEXT:     %zmm0 = COPY %2(<16 x s32>)
+# ALL-NEXT:     RET 0, implicit %zmm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %zmm0, %zmm1
+
+    %0(<16 x s32>) = COPY %zmm0
+    %1(<16 x s32>) = COPY %zmm1
+    %2(<16 x s32>) = G_MUL %0, %1
+    %zmm0 = COPY %2(<16 x s32>)
+    RET 0, implicit %zmm0
+
+...
+---
+name:            test_mul_v8i64
+# ALL-LABEL: name:  test_mul_v8i64
+alignment:       4
+legalized:       false
+regBankSelected: false
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: _ }
+# ALL-NEXT:   - { id: 1, class: _ }
+# ALL-NEXT:   - { id: 2, class: _ }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+# ALL:          %0(<8 x s64>) = COPY %zmm0
+# ALL-NEXT:     %1(<8 x s64>) = COPY %zmm1
+# ALL-NEXT:     %2(<8 x s64>) = G_MUL %0, %1
+# ALL-NEXT:     %zmm0 = COPY %2(<8 x s64>)
+# ALL-NEXT:     RET 0, implicit %zmm0
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %zmm0, %zmm1
+
+    %0(<8 x s64>) = COPY %zmm0
+    %1(<8 x s64>) = COPY %zmm1
+    %2(<8 x s64>) = G_MUL %0, %1
+    %zmm0 = COPY %2(<8 x s64>)
+    RET 0, implicit %zmm0
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/mul-scalar.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/mul-scalar.ll?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/mul-scalar.ll (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/mul-scalar.ll Mon May  8 04:03:37 2017
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
+
+;TODO: instruction selection not supported yet
+;define i8 @test_mul_i8(i8 %arg1, i8 %arg2) {
+;  %ret = mul i8 %arg1, %arg2
+;  ret i8 %ret
+;}
+
+define i16 @test_mul_i16(i16 %arg1, i16 %arg2) {
+; X64-LABEL: test_mul_i16:
+; X64:       # BB#0:
+; X64-NEXT:    imulw %di, %si
+; X64-NEXT:    movl %esi, %eax
+; X64-NEXT:    retq
+  %ret = mul i16 %arg1, %arg2
+  ret i16 %ret
+}
+
+define i32 @test_mul_i32(i32 %arg1, i32 %arg2) {
+; X64-LABEL: test_mul_i32:
+; X64:       # BB#0:
+; X64-NEXT:    imull %edi, %esi
+; X64-NEXT:    movl %esi, %eax
+; X64-NEXT:    retq
+  %ret = mul i32 %arg1, %arg2
+  ret i32 %ret
+}
+
+define i64 @test_mul_i64(i64 %arg1, i64 %arg2) {
+; X64-LABEL: test_mul_i64:
+; X64:       # BB#0:
+; X64-NEXT:    imulq %rdi, %rsi
+; X64-NEXT:    movq %rsi, %rax
+; X64-NEXT:    retq
+  %ret = mul i64 %arg1, %arg2
+  ret i64 %ret
+}
+

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/mul-vec.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/mul-vec.ll?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/mul-vec.ll (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/mul-vec.ll Mon May  8 04:03:37 2017
@@ -0,0 +1,84 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -mcpu=skx -global-isel < %s -o - | FileCheck %s --check-prefix=SKX
+
+define <8 x i16> @test_mul_v8i16(<8 x i16> %arg1, <8 x i16> %arg2) {
+; SKX-LABEL: test_mul_v8i16:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmullw %xmm1, %xmm0, %xmm0
+; SKX-NEXT:    retq
+  %ret = mul <8 x i16> %arg1, %arg2
+  ret <8 x i16> %ret
+}
+
+define <4 x i32> @test_mul_v4i32(<4 x i32> %arg1, <4 x i32> %arg2) {
+; SKX-LABEL: test_mul_v4i32:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
+; SKX-NEXT:    retq
+  %ret = mul <4 x i32> %arg1, %arg2
+  ret <4 x i32> %ret
+}
+
+define <2 x i64> @test_mul_v2i64(<2 x i64> %arg1, <2 x i64> %arg2) {
+; SKX-LABEL: test_mul_v2i64:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmullq %xmm1, %xmm0, %xmm0
+; SKX-NEXT:    retq
+  %ret = mul <2 x i64> %arg1, %arg2
+  ret <2 x i64> %ret
+}
+
+define <16 x i16> @test_mul_v16i16(<16 x i16> %arg1, <16 x i16> %arg2) {
+; SKX-LABEL: test_mul_v16i16:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmullw %ymm1, %ymm0, %ymm0
+; SKX-NEXT:    retq
+  %ret = mul <16 x i16> %arg1, %arg2
+  ret <16 x i16> %ret
+}
+
+define <8 x i32> @test_mul_v8i32(<8 x i32> %arg1, <8 x i32> %arg2) {
+; SKX-LABEL: test_mul_v8i32:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmulld %ymm1, %ymm0, %ymm0
+; SKX-NEXT:    retq
+  %ret = mul <8 x i32> %arg1, %arg2
+  ret <8 x i32> %ret
+}
+
+define <4 x i64> @test_mul_v4i64(<4 x i64> %arg1, <4 x i64> %arg2) {
+; SKX-LABEL: test_mul_v4i64:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmullq %ymm1, %ymm0, %ymm0
+; SKX-NEXT:    retq
+  %ret = mul <4 x i64> %arg1, %arg2
+  ret <4 x i64> %ret
+}
+
+define <32 x i16> @test_mul_v32i16(<32 x i16> %arg1, <32 x i16> %arg2) {
+; SKX-LABEL: test_mul_v32i16:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmullw %zmm1, %zmm0, %zmm0
+; SKX-NEXT:    retq
+  %ret = mul <32 x i16> %arg1, %arg2
+  ret <32 x i16> %ret
+}
+
+define <16 x i32> @test_mul_v16i32(<16 x i32> %arg1, <16 x i32> %arg2) {
+; SKX-LABEL: test_mul_v16i32:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmulld %zmm1, %zmm0, %zmm0
+; SKX-NEXT:    retq
+  %ret = mul <16 x i32> %arg1, %arg2
+  ret <16 x i32> %ret
+}
+
+define <8 x i64> @test_mul_v8i64(<8 x i64> %arg1, <8 x i64> %arg2) {
+; SKX-LABEL: test_mul_v8i64:
+; SKX:       # BB#0:
+; SKX-NEXT:    vpmullq %zmm1, %zmm0, %zmm0
+; SKX-NEXT:    retq
+  %ret = mul <8 x i64> %arg1, %arg2
+  ret <8 x i64> %ret
+}
+

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX2.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX2.mir?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX2.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX2.mir Mon May  8 04:03:37 2017
@@ -0,0 +1,31 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx2 --global-isel                       -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
+# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx2 --global-isel -regbankselect-greedy -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
+
+--- |
+  define void @test_mul_vec256() {
+    ret void
+  }
+...
+---
+name:            test_mul_vec256
+alignment:       4
+legalized:       true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+# CHECK-LABEL: name:            test_mul_vec256
+# CHECK: registers:
+# CHECK:  - { id: 0, class: vecr }
+# CHECK:  - { id: 1, class: vecr }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+
+    %0(<8 x s32>) = IMPLICIT_DEF
+    %1(<8 x s32>) = G_MUL %0, %0
+    RET 0
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX512.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX512.mir?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX512.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-AVX512.mir Mon May  8 04:03:37 2017
@@ -0,0 +1,33 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -global-isel                       -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
+# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -global-isel -regbankselect-greedy -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
+
+--- |
+
+  define void @test_mul_vec512() {
+    ret void
+  }
+
+...
+---
+name:            test_mul_vec512
+alignment:       4
+legalized:       true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+# CHECK-LABEL: name:            test_mul_vec512
+# CHECK: registers:
+# CHECK:  - { id: 0, class: vecr }
+# CHECK:  - { id: 1, class: vecr }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+
+    %0(<16 x s32>) = IMPLICIT_DEF
+    %1(<16 x s32>) = G_MUL %0, %0
+    RET 0
+
+...

Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir?rev=302410&r1=302409&r2=302410&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir Mon May  8 04:03:37 2017
@@ -27,6 +27,10 @@
     ret i64 %ret
   }
 
+  define void @test_mul_gpr() {
+    ret void
+  }
+
   define float @test_add_float(float %arg1, float %arg2) {
     %ret = fadd float %arg1, %arg2
     ret float %ret
@@ -220,6 +224,45 @@ body:             |
 
 ...
 ---
+name:            test_mul_gpr
+alignment:       4
+legalized:       true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+# CHECK-LABEL: name:            test_mul_gpr
+# CHECK: registers:
+# CHECK:  - { id: 0, class: gpr }
+# CHECK:  - { id: 1, class: gpr }
+# CHECK:  - { id: 2, class: gpr }
+# CHECK:  - { id: 3, class: gpr }
+# CHECK:  - { id: 4, class: gpr }
+# CHECK:  - { id: 5, class: gpr }
+# CHECK:  - { id: 6, class: gpr }
+# CHECK:  - { id: 7, class: gpr }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
+  - { id: 6, class: _ }
+  - { id: 7, class: _ }  
+body:             |
+  bb.1 (%ir-block.0):
+    
+    %0(s64) = IMPLICIT_DEF
+    %1(s32) = IMPLICIT_DEF
+    %2(s16) = IMPLICIT_DEF
+    %3(s8)  = IMPLICIT_DEF
+    %4(s64) = G_MUL %0, %0
+    %5(s32) = G_MUL %1, %1
+    %6(s16) = G_MUL %2, %2
+    %7(s8)  = G_MUL %3, %3
+    RET 0
+...
+---
 name:            test_add_float
 alignment:       4
 legalized:       true

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-scalar.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-scalar.mir?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-scalar.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-scalar.mir Mon May  8 04:03:37 2017
@@ -0,0 +1,112 @@
+# RUN: llc -mtriple=x86_64-linux-gnu                                  -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=ALL 
+
+--- |
+  define i16 @test_mul_i16(i16 %arg1, i16 %arg2) {
+    %ret = mul i16 %arg1, %arg2
+    ret i16 %ret
+  }
+
+  define i32 @test_mul_i32(i32 %arg1, i32 %arg2) {
+    %ret = mul i32 %arg1, %arg2
+    ret i32 %ret
+  }
+
+  define i64 @test_mul_i64(i64 %arg1, i64 %arg2) {
+    %ret = mul i64 %arg1, %arg2
+    ret i64 %ret
+  }
+
+...
+---
+name:            test_mul_i16
+# ALL-LABEL: name:  test_mul_i16
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr16 }
+# ALL-NEXT:   - { id: 1, class: gr16 }
+# ALL-NEXT:   - { id: 2, class: gr16 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+# ALL:      body:             |
+# ALL:          %0 = COPY %di
+# ALL-NEXT:     %1 = COPY %si
+# ALL-NEXT:     %2 = IMUL16rr %0, %1, implicit-def %eflags
+# ALL-NEXT:     %ax = COPY %2
+# ALL-NEXT:     RET 0, implicit %ax
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %edi, %esi
+
+    %0(s16) = COPY %edi
+    %1(s16) = COPY %esi
+    %2(s16) = G_MUL %0, %1
+    %ax = COPY %2(s16)
+    RET 0, implicit %ax
+
+...
+---
+name:            test_mul_i32
+# ALL-LABEL: name:  test_mul_i32
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr32 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+# ALL:      body:             |
+# ALL:          %0 = COPY %edi
+# ALL-NEXT:     %1 = COPY %esi
+# ALL-NEXT:     %2 = IMUL32rr %0, %1, implicit-def %eflags
+# ALL-NEXT:     %eax = COPY %2
+# ALL-NEXT:     RET 0, implicit %eax
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %edi, %esi
+
+    %0(s32) = COPY %edi
+    %1(s32) = COPY %esi
+    %2(s32) = G_MUL %0, %1
+    %eax = COPY %2(s32)
+    RET 0, implicit %eax
+
+...
+---
+name:            test_mul_i64
+# ALL-LABEL: name:  test_mul_i64
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr64 }
+# ALL-NEXT:   - { id: 1, class: gr64 }
+# ALL-NEXT:   - { id: 2, class: gr64 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+# ALL:      body:             |
+# ALL:          %0 = COPY %rdi
+# ALL-NEXT:     %1 = COPY %rsi
+# ALL-NEXT:     %2 = IMUL64rr %0, %1, implicit-def %eflags
+# ALL-NEXT:     %rax = COPY %2
+# ALL-NEXT:     RET 0, implicit %rax
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %rdi, %rsi
+
+    %0(s64) = COPY %rdi
+    %1(s64) = COPY %rsi
+    %2(s64) = G_MUL %0, %1
+    %rax = COPY %2(s64)
+    RET 0, implicit %rax
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-vec.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-vec.mir?rev=302410&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-vec.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-mul-vec.mir Mon May  8 04:03:37 2017
@@ -0,0 +1,480 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+
+--- |
+  define <8 x i16> @test_mul_v8i16(<8 x i16> %arg1, <8 x i16> %arg2) #0 {
+    %ret = mul <8 x i16> %arg1, %arg2
+    ret <8 x i16> %ret
+  }
+
+  define <8 x i16> @test_mul_v8i16_avx(<8 x i16> %arg1, <8 x i16> %arg2) #1 {
+    %ret = mul <8 x i16> %arg1, %arg2
+    ret <8 x i16> %ret
+  }
+
+  define <8 x i16> @test_mul_v8i16_avx512bwvl(<8 x i16> %arg1, <8 x i16> %arg2) #2 {
+    %ret = mul <8 x i16> %arg1, %arg2
+    ret <8 x i16> %ret
+  }
+
+  define <4 x i32> @test_mul_v4i32(<4 x i32> %arg1, <4 x i32> %arg2) #3 {
+    %ret = mul <4 x i32> %arg1, %arg2
+    ret <4 x i32> %ret
+  }
+
+  define <4 x i32> @test_mul_v4i32_avx(<4 x i32> %arg1, <4 x i32> %arg2) #1 {
+    %ret = mul <4 x i32> %arg1, %arg2
+    ret <4 x i32> %ret
+  }
+
+  define <4 x i32> @test_mul_v4i32_avx512vl(<4 x i32> %arg1, <4 x i32> %arg2) #4 {
+    %ret = mul <4 x i32> %arg1, %arg2
+    ret <4 x i32> %ret
+  }
+
+  define <2 x i64> @test_mul_v2i64(<2 x i64> %arg1, <2 x i64> %arg2) #5 {
+    %ret = mul <2 x i64> %arg1, %arg2
+    ret <2 x i64> %ret
+  }
+
+  define <16 x i16> @test_mul_v16i16(<16 x i16> %arg1, <16 x i16> %arg2) #6 {
+    %ret = mul <16 x i16> %arg1, %arg2
+    ret <16 x i16> %ret
+  }
+
+  define <16 x i16> @test_mul_v16i16_avx512bwvl(<16 x i16> %arg1, <16 x i16> %arg2) #2 {
+    %ret = mul <16 x i16> %arg1, %arg2
+    ret <16 x i16> %ret
+  }
+
+  define <8 x i32> @test_mul_v8i32(<8 x i32> %arg1, <8 x i32> %arg2) #6 {
+    %ret = mul <8 x i32> %arg1, %arg2
+    ret <8 x i32> %ret
+  }
+
+  define <8 x i32> @test_mul_v8i32_avx512vl(<8 x i32> %arg1, <8 x i32> %arg2) #4 {
+    %ret = mul <8 x i32> %arg1, %arg2
+    ret <8 x i32> %ret
+  }
+
+  define <4 x i64> @test_mul_v4i64(<4 x i64> %arg1, <4 x i64> %arg2) #5 {
+    %ret = mul <4 x i64> %arg1, %arg2
+    ret <4 x i64> %ret
+  }
+
+  define <32 x i16> @test_mul_v32i16(<32 x i16> %arg1, <32 x i16> %arg2) #7 {
+    %ret = mul <32 x i16> %arg1, %arg2
+    ret <32 x i16> %ret
+  }
+
+  define <16 x i32> @test_mul_v16i32(<16 x i32> %arg1, <16 x i32> %arg2) #8 {
+    %ret = mul <16 x i32> %arg1, %arg2
+    ret <16 x i32> %ret
+  }
+
+  define <8 x i64> @test_mul_v8i64(<8 x i64> %arg1, <8 x i64> %arg2) #9 {
+    %ret = mul <8 x i64> %arg1, %arg2
+    ret <8 x i64> %ret
+  }
+
+  attributes #0 = { "target-features"="+sse2" }
+  attributes #1 = { "target-features"="+avx" }
+  attributes #2 = { "target-features"="+avx512vl,+avx512f,+avx512bw" }
+  attributes #3 = { "target-features"="+sse4.1" }
+  attributes #4 = { "target-features"="+avx512vl,+avx512f" }
+  attributes #5 = { "target-features"="+avx2,+avx512vl,+avx512f,+avx512dq" }
+  attributes #6 = { "target-features"="+avx2" }
+  attributes #7 = { "target-features"="+avx512f,+avx512bw" }
+  attributes #8 = { "target-features"="+avx512f" }
+  attributes #9 = { "target-features"="+avx512f,+avx512dq" }
+
+...
+---
+name:            test_mul_v8i16
+# CHECK-LABEL: name:  test_mul_v8i16
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr128 }
+# CHECK-NEXT:   - { id: 1, class: vr128 }
+# CHECK-NEXT:   - { id: 2, class: vr128 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = PMULLWrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<8 x s16>) = COPY %xmm0
+    %1(<8 x s16>) = COPY %xmm1
+    %2(<8 x s16>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<8 x s16>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v8i16_avx
+# CHECK-LABEL: name:  test_mul_v8i16_avx
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr128 }
+# CHECK-NEXT:   - { id: 1, class: vr128 }
+# CHECK-NEXT:   - { id: 2, class: vr128 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLWrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<8 x s16>) = COPY %xmm0
+    %1(<8 x s16>) = COPY %xmm1
+    %2(<8 x s16>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<8 x s16>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v8i16_avx512bwvl
+# CHECK-LABEL: name:  test_mul_v8i16_avx512bwvl
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr128x }
+# CHECK-NEXT:   - { id: 1, class: vr128x }
+# CHECK-NEXT:   - { id: 2, class: vr128x }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLWZ128rr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<8 x s16>) = COPY %xmm0
+    %1(<8 x s16>) = COPY %xmm1
+    %2(<8 x s16>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<8 x s16>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v4i32
+# CHECK-LABEL: name:  test_mul_v4i32
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr128 }
+# CHECK-NEXT:   - { id: 1, class: vr128 }
+# CHECK-NEXT:   - { id: 2, class: vr128 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = PMULLDrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<4 x s32>) = COPY %xmm0
+    %1(<4 x s32>) = COPY %xmm1
+    %2(<4 x s32>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<4 x s32>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v4i32_avx
+# CHECK-LABEL: name:  test_mul_v4i32_avx
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr128 }
+# CHECK-NEXT:   - { id: 1, class: vr128 }
+# CHECK-NEXT:   - { id: 2, class: vr128 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLDrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<4 x s32>) = COPY %xmm0
+    %1(<4 x s32>) = COPY %xmm1
+    %2(<4 x s32>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<4 x s32>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v4i32_avx512vl
+# CHECK-LABEL: name:  test_mul_v4i32_avx512vl
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr128x }
+# CHECK-NEXT:   - { id: 1, class: vr128x }
+# CHECK-NEXT:   - { id: 2, class: vr128x }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLDZ128rr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<4 x s32>) = COPY %xmm0
+    %1(<4 x s32>) = COPY %xmm1
+    %2(<4 x s32>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<4 x s32>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v2i64
+# CHECK-LABEL: name:  test_mul_v2i64
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr128x }
+# CHECK-NEXT:   - { id: 1, class: vr128x }
+# CHECK-NEXT:   - { id: 2, class: vr128x }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLQZ128rr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %xmm0, %xmm1
+
+    %0(<2 x s64>) = COPY %xmm0
+    %1(<2 x s64>) = COPY %xmm1
+    %2(<2 x s64>) = G_MUL %0, %1
+    %xmm0 = COPY %2(<2 x s64>)
+    RET 0, implicit %xmm0
+
+...
+---
+name:            test_mul_v16i16
+# CHECK-LABEL: name:  test_mul_v16i16
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr256 }
+# CHECK-NEXT:   - { id: 1, class: vr256 }
+# CHECK-NEXT:   - { id: 2, class: vr256 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLWYrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %ymm0, %ymm1
+
+    %0(<16 x s16>) = COPY %ymm0
+    %1(<16 x s16>) = COPY %ymm1
+    %2(<16 x s16>) = G_MUL %0, %1
+    %ymm0 = COPY %2(<16 x s16>)
+    RET 0, implicit %ymm0
+
+...
+---
+name:            test_mul_v16i16_avx512bwvl
+# CHECK-LABEL: name:  test_mul_v16i16_avx512bwvl
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr256x }
+# CHECK-NEXT:   - { id: 1, class: vr256x }
+# CHECK-NEXT:   - { id: 2, class: vr256x }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLWZ256rr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %ymm0, %ymm1
+
+    %0(<16 x s16>) = COPY %ymm0
+    %1(<16 x s16>) = COPY %ymm1
+    %2(<16 x s16>) = G_MUL %0, %1
+    %ymm0 = COPY %2(<16 x s16>)
+    RET 0, implicit %ymm0
+
+...
+---
+name:            test_mul_v8i32
+# CHECK-LABEL: name:  test_mul_v8i32
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr256 }
+# CHECK-NEXT:   - { id: 1, class: vr256 }
+# CHECK-NEXT:   - { id: 2, class: vr256 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLDYrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %ymm0, %ymm1
+
+    %0(<8 x s32>) = COPY %ymm0
+    %1(<8 x s32>) = COPY %ymm1
+    %2(<8 x s32>) = G_MUL %0, %1
+    %ymm0 = COPY %2(<8 x s32>)
+    RET 0, implicit %ymm0
+
+...
+---
+name:            test_mul_v8i32_avx512vl
+# CHECK-LABEL: name:  test_mul_v8i32_avx512vl
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr256x }
+# CHECK-NEXT:   - { id: 1, class: vr256x }
+# CHECK-NEXT:   - { id: 2, class: vr256x }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLDZ256rr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %ymm0, %ymm1
+
+    %0(<8 x s32>) = COPY %ymm0
+    %1(<8 x s32>) = COPY %ymm1
+    %2(<8 x s32>) = G_MUL %0, %1
+    %ymm0 = COPY %2(<8 x s32>)
+    RET 0, implicit %ymm0
+
+...
+---
+name:            test_mul_v4i64
+# CHECK-LABEL: name:  test_mul_v4i64
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr256x }
+# CHECK-NEXT:   - { id: 1, class: vr256x }
+# CHECK-NEXT:   - { id: 2, class: vr256x }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLQZ256rr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %ymm0, %ymm1
+
+    %0(<4 x s64>) = COPY %ymm0
+    %1(<4 x s64>) = COPY %ymm1
+    %2(<4 x s64>) = G_MUL %0, %1
+    %ymm0 = COPY %2(<4 x s64>)
+    RET 0, implicit %ymm0
+
+...
+---
+name:            test_mul_v32i16
+# CHECK-LABEL: name:  test_mul_v32i16
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr512 }
+# CHECK-NEXT:   - { id: 1, class: vr512 }
+# CHECK-NEXT:   - { id: 2, class: vr512 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLWZrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %zmm0, %zmm1
+
+    %0(<32 x s16>) = COPY %zmm0
+    %1(<32 x s16>) = COPY %zmm1
+    %2(<32 x s16>) = G_MUL %0, %1
+    %zmm0 = COPY %2(<32 x s16>)
+    RET 0, implicit %zmm0
+
+...
+---
+name:            test_mul_v16i32
+# CHECK-LABEL: name:  test_mul_v16i32
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr512 }
+# CHECK-NEXT:   - { id: 1, class: vr512 }
+# CHECK-NEXT:   - { id: 2, class: vr512 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLDZrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %zmm0, %zmm1
+
+    %0(<16 x s32>) = COPY %zmm0
+    %1(<16 x s32>) = COPY %zmm1
+    %2(<16 x s32>) = G_MUL %0, %1
+    %zmm0 = COPY %2(<16 x s32>)
+    RET 0, implicit %zmm0
+
+...
+---
+name:            test_mul_v8i64
+# CHECK-LABEL: name:  test_mul_v8i64
+alignment:       4
+legalized:       true
+regBankSelected: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: vr512 }
+# CHECK-NEXT:   - { id: 1, class: vr512 }
+# CHECK-NEXT:   - { id: 2, class: vr512 }
+registers:
+  - { id: 0, class: vecr }
+  - { id: 1, class: vecr }
+  - { id: 2, class: vecr }
+# CHECK:          %2 = VPMULLQZrr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %zmm0, %zmm1
+
+    %0(<8 x s64>) = COPY %zmm0
+    %1(<8 x s64>) = COPY %zmm1
+    %2(<8 x s64>) = G_MUL %0, %1
+    %zmm0 = COPY %2(<8 x s64>)
+    RET 0, implicit %zmm0
+
+...




More information about the llvm-commits mailing list