2017-01-06 00:48:28 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
2017-06-21 20:58:56 +08:00
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
|
2017-12-20 21:12:34 +08:00
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2 --check-prefix=AVX2-SLOW
|
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2,+fast-variable-shuffle | FileCheck %s --check-prefix=AVX --check-prefix=AVX2 --check-prefix=AVX2-FAST
|
2017-01-06 00:48:28 +08:00
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=AVX512 --check-prefix=AVX512F
|
2018-01-10 00:26:06 +08:00
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512VL
|
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512BW
|
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512BWVL
|
2018-01-31 00:01:41 +08:00
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512vbmi,+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512VBMIVL
|
2017-01-06 00:48:28 +08:00
|
|
|
|
|
|
|
; PR31551
|
|
|
|
; Pairs of shufflevector:trunc functions with functional equivalence.
|
|
|
|
; Ideally, the shuffles should be lowered to code with the same quality as the truncates.
|
|
|
|
|
|
|
|
define void @shuffle_v32i8_to_v16i8(<32 x i8>* %L, <16 x i8>* %S) nounwind {
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX-LABEL: shuffle_v32i8_to_v16i8:
|
|
|
|
; AVX: # %bb.0:
|
|
|
|
; AVX-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX-NEXT: vmovdqa 16(%rdi), %xmm1
|
|
|
|
; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX-NEXT: vmovdqa %xmm0, (%rsi)
|
|
|
|
; AVX-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512-LABEL: shuffle_v32i8_to_v16i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512-NEXT: vmovdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX512-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX512-NEXT: vmovdqa %xmm0, (%rsi)
|
|
|
|
; AVX512-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <32 x i8>, <32 x i8>* %L
|
|
|
|
%strided.vec = shufflevector <32 x i8> %vec, <32 x i8> undef, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
|
|
|
|
store <16 x i8> %strided.vec, <16 x i8>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @trunc_v16i16_to_v16i8(<32 x i8>* %L, <16 x i8>* %S) nounwind {
|
2018-11-19 01:59:28 +08:00
|
|
|
; AVX1-LABEL: trunc_v16i16_to_v16i8:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vmovaps (%rdi), %ymm0
|
|
|
|
; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0
|
|
|
|
; AVX1-NEXT: vmovdqa %xmm0, (%rsi)
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-LABEL: trunc_v16i16_to_v16i8:
|
|
|
|
; AVX2: # %bb.0:
|
|
|
|
; AVX2-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX2-NEXT: vpand {{.*}}(%rip), %ymm0, %ymm0
|
|
|
|
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
|
|
|
|
; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0
|
|
|
|
; AVX2-NEXT: vmovdqa %xmm0, (%rsi)
|
|
|
|
; AVX2-NEXT: vzeroupper
|
|
|
|
; AVX2-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v16i16_to_v16i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
2018-11-10 03:05:51 +08:00
|
|
|
; AVX512F-NEXT: vpmovzxwd {{.*#+}} zmm0 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero,mem[8],zero,mem[9],zero,mem[10],zero,mem[11],zero,mem[12],zero,mem[13],zero,mem[14],zero,mem[15],zero
|
2018-01-14 16:11:36 +08:00
|
|
|
; AVX512F-NEXT: vpmovdb %zmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512F-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v16i16_to_v16i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
2018-11-10 03:05:51 +08:00
|
|
|
; AVX512VL-NEXT: vpmovzxwd {{.*#+}} zmm0 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero,mem[8],zero,mem[9],zero,mem[10],zero,mem[11],zero,mem[12],zero,mem[13],zero,mem[14],zero,mem[15],zero
|
2018-01-14 16:11:36 +08:00
|
|
|
; AVX512VL-NEXT: vpmovdb %zmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v16i16_to_v16i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BW-NEXT: vpmovwb %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vmovdqa %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BW-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v16i16_to_v16i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
2017-08-01 01:35:44 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovdqa (%rdi), %ymm0
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovwb %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v16i16_to_v16i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VBMIVL-NEXT: vpmovwb %ymm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <32 x i8>, <32 x i8>* %L
|
|
|
|
%bc = bitcast <32 x i8> %vec to <16 x i16>
|
|
|
|
%strided.vec = trunc <16 x i16> %bc to <16 x i8>
|
|
|
|
store <16 x i8> %strided.vec, <16 x i8>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @shuffle_v16i16_to_v8i16(<16 x i16>* %L, <8 x i16>* %S) nounwind {
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX-LABEL: shuffle_v16i16_to_v8i16:
|
|
|
|
; AVX: # %bb.0:
|
|
|
|
; AVX-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX-NEXT: vmovdqa 16(%rdi), %xmm1
|
|
|
|
; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX-NEXT: vmovdqa %xmm0, (%rsi)
|
|
|
|
; AVX-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
2017-12-20 00:54:07 +08:00
|
|
|
; AVX512-LABEL: shuffle_v16i16_to_v8i16:
|
|
|
|
; AVX512: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-12-20 00:54:07 +08:00
|
|
|
; AVX512-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX512-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX512-NEXT: vmovdqa %xmm0, (%rsi)
|
|
|
|
; AVX512-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <16 x i16>, <16 x i16>* %L
|
|
|
|
%strided.vec = shufflevector <16 x i16> %vec, <16 x i16> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
|
|
|
|
store <8 x i16> %strided.vec, <8 x i16>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @trunc_v8i32_to_v8i16(<16 x i16>* %L, <8 x i16>* %S) nounwind {
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-LABEL: trunc_v8i32_to_v8i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX1: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX1-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX1-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX1-NEXT: vmovdqa %xmm0, (%rsi)
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-LABEL: trunc_v8i32_to_v8i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX2: # %bb.0:
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX2-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
|
|
|
|
; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-NEXT: vmovdqa %xmm0, (%rsi)
|
|
|
|
; AVX2-NEXT: vzeroupper
|
|
|
|
; AVX2-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v8i32_to_v8i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512F-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vmovdqa %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512F-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v8i32_to_v8i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VL-NEXT: vpmovdw %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v8i32_to_v8i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vmovdqa %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BW-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v8i32_to_v8i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BWVL-NEXT: vpmovdw %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v8i32_to_v8i16:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VBMIVL-NEXT: vpmovdw %ymm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <16 x i16>, <16 x i16>* %L
|
|
|
|
%bc = bitcast <16 x i16> %vec to <8 x i32>
|
|
|
|
%strided.vec = trunc <8 x i32> %bc to <8 x i16>
|
|
|
|
store <8 x i16> %strided.vec, <8 x i16>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @shuffle_v8i32_to_v4i32(<8 x i32>* %L, <4 x i32>* %S) nounwind {
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX-LABEL: shuffle_v8i32_to_v4i32:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX-NEXT: vmovaps %xmm0, (%rsi)
|
|
|
|
; AVX-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512-LABEL: shuffle_v8i32_to_v4i32:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX512-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512-NEXT: vmovaps %xmm0, (%rsi)
|
|
|
|
; AVX512-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <8 x i32>, <8 x i32>* %L
|
|
|
|
%strided.vec = shufflevector <8 x i32> %vec, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
|
|
|
|
store <4 x i32> %strided.vec, <4 x i32>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @trunc_v4i64_to_v4i32(<8 x i32>* %L, <4 x i32>* %S) nounwind {
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-LABEL: trunc_v4i64_to_v4i32:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX1: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX1-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-NEXT: vmovaps %xmm0, (%rsi)
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
2017-12-20 21:12:34 +08:00
|
|
|
; AVX2-SLOW-LABEL: trunc_v4i64_to_v4i32:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
|
|
|
; AVX2-SLOW-NEXT: vpermilps {{.*#+}} ymm0 = mem[0,2,2,3,4,6,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpermpd {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vmovaps %xmm0, (%rsi)
|
|
|
|
; AVX2-SLOW-NEXT: vzeroupper
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: trunc_v4i64_to_v4i32:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
|
|
|
; AVX2-FAST-NEXT: vmovaps {{.*#+}} ymm0 = [0,2,4,6,4,6,6,7]
|
|
|
|
; AVX2-FAST-NEXT: vpermps (%rdi), %ymm0, %ymm0
|
|
|
|
; AVX2-FAST-NEXT: vmovaps %xmm0, (%rsi)
|
|
|
|
; AVX2-FAST-NEXT: vzeroupper
|
|
|
|
; AVX2-FAST-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v4i64_to_v4i32:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512F-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vmovdqa %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512F-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v4i64_to_v4i32:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VL-NEXT: vpmovqd %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v4i64_to_v4i32:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vmovdqa %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BW-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v4i64_to_v4i32:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BWVL-NEXT: vpmovqd %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v4i64_to_v4i32:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VBMIVL-NEXT: vpmovqd %ymm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <8 x i32>, <8 x i32>* %L
|
|
|
|
%bc = bitcast <8 x i32> %vec to <4 x i64>
|
|
|
|
%strided.vec = trunc <4 x i64> %bc to <4 x i32>
|
|
|
|
store <4 x i32> %strided.vec, <4 x i32>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @shuffle_v32i8_to_v8i8(<32 x i8>* %L, <8 x i8>* %S) nounwind {
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX-LABEL: shuffle_v32i8_to_v8i8:
|
|
|
|
; AVX: # %bb.0:
|
|
|
|
; AVX-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX-NEXT: vmovdqa 16(%rdi), %xmm1
|
|
|
|
; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
|
|
|
; AVX-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: shuffle_v32i8_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512F-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX512F-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512F-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX512F-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: shuffle_v32i8_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512VL-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512VL-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512VL-NEXT: vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX512VL-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512VL-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX512VL-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
|
|
|
; AVX512VL-NEXT: vmovq %xmm0, (%rsi)
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: shuffle_v32i8_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512BW-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX512BW-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512BW-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX512BW-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: shuffle_v32i8_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512BWVL-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-12-20 00:54:07 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX512BWVL-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512BWVL-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512BWVL-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX512BWVL-NEXT: vpmovwb %xmm0, (%rsi)
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: shuffle_v32i8_to_v8i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa 16(%rdi), %xmm1
|
2018-01-31 00:01:41 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX512VBMIVL-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512VBMIVL-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX512VBMIVL-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX512VBMIVL-NEXT: vpmovwb %xmm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <32 x i8>, <32 x i8>* %L
|
|
|
|
%strided.vec = shufflevector <32 x i8> %vec, <32 x i8> undef, <8 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28>
|
|
|
|
store <8 x i8> %strided.vec, <8 x i8>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @trunc_v8i32_to_v8i8(<32 x i8>* %L, <8 x i8>* %S) nounwind {
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-LABEL: trunc_v8i32_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX1: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX1-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX1-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX1-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
|
|
|
; AVX1-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-LABEL: trunc_v8i32_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX2: # %bb.0:
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX2-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
|
|
|
|
; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
|
|
|
|
; AVX2-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX2-NEXT: vzeroupper
|
|
|
|
; AVX2-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v8i32_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512F-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
|
|
|
|
; AVX512F-NEXT: vmovq %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512F-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v8i32_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VL-NEXT: vpmovdb %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v8i32_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
|
|
|
|
; AVX512BW-NEXT: vmovq %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BW-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v8i32_to_v8i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BWVL-NEXT: vpmovdb %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v8i32_to_v8i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VBMIVL-NEXT: vpmovdb %ymm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <32 x i8>, <32 x i8>* %L
|
|
|
|
%bc = bitcast <32 x i8> %vec to <8 x i32>
|
|
|
|
%strided.vec = trunc <8 x i32> %bc to <8 x i8>
|
|
|
|
store <8 x i8> %strided.vec, <8 x i8>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
2018-05-22 17:47:42 +08:00
|
|
|
define <2 x i64> @trunc_v8i32_to_v8i8_return_v2i64(<8 x i32> %vec) nounwind {
|
|
|
|
; IR generated from:
|
|
|
|
; return (__m128i) {(long long)__builtin_convertvector((__v8si)__A, __v8qi), 0};
|
|
|
|
; AVX1-LABEL: trunc_v8i32_to_v8i8_return_v2i64:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-LABEL: trunc_v8i32_to_v8i8_return_v2i64:
|
|
|
|
; AVX2: # %bb.0:
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
|
|
|
|
; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-NEXT: vzeroupper
|
|
|
|
; AVX2-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v8i32_to_v8i8_return_v2i64:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v8i32_to_v8i8_return_v2i64:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v8i32_to_v8i8_return_v2i64:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v8i32_to_v8i8_return_v2i64:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v8i32_to_v8i8_return_v2i64:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated.vec = trunc <8 x i32> %vec to <8 x i8>
|
|
|
|
%bc = bitcast <8 x i8> %truncated.vec to i64
|
|
|
|
%result = insertelement <2 x i64> zeroinitializer, i64 %bc, i32 0
|
|
|
|
ret <2 x i64> %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define <16 x i8> @trunc_v8i32_to_v8i8_with_zext_return_v16i8(<8 x i32> %vec) nounwind {
|
|
|
|
; AVX1-LABEL: trunc_v8i32_to_v8i8_with_zext_return_v16i8:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-LABEL: trunc_v8i32_to_v8i8_with_zext_return_v16i8:
|
|
|
|
; AVX2: # %bb.0:
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
|
|
|
|
; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-NEXT: vzeroupper
|
|
|
|
; AVX2-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v8i32_to_v8i8_with_zext_return_v16i8:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v8i32_to_v8i8_with_zext_return_v16i8:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v8i32_to_v8i8_with_zext_return_v16i8:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v8i32_to_v8i8_with_zext_return_v16i8:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v8i32_to_v8i8_with_zext_return_v16i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated = trunc <8 x i32> %vec to <8 x i8>
|
|
|
|
%truncated.ext = zext <8 x i8> %truncated to <8 x i16>
|
|
|
|
%bc = bitcast <8 x i16> %truncated.ext to <16 x i8>
|
|
|
|
%result = shufflevector <16 x i8> %bc, <16 x i8> zeroinitializer, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
|
|
|
|
ret <16 x i8> %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define <16 x i8> @trunc_v8i32_to_v8i8_via_v8i16_return_v16i8(<8 x i32> %vec) nounwind {
|
|
|
|
; AVX1-LABEL: trunc_v8i32_to_v8i8_via_v8i16_return_v16i8:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-LABEL: trunc_v8i32_to_v8i8_via_v8i16_return_v16i8:
|
|
|
|
; AVX2: # %bb.0:
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
|
|
|
|
; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-NEXT: vzeroupper
|
|
|
|
; AVX2-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v8i32_to_v8i8_via_v8i16_return_v16i8:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v8i32_to_v8i8_via_v8i16_return_v16i8:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v8i32_to_v8i8_via_v8i16_return_v16i8:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v8i32_to_v8i8_via_v8i16_return_v16i8:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v8i32_to_v8i8_via_v8i16_return_v16i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated = trunc <8 x i32> %vec to <8 x i16>
|
|
|
|
%bc = bitcast <8 x i16> %truncated to <16 x i8>
|
|
|
|
%result = shufflevector <16 x i8> %bc, <16 x i8> zeroinitializer, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 17, i32 20, i32 24, i32 22, i32 31, i32 28, i32 28, i32 29>
|
|
|
|
ret <16 x i8> %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define <16 x i8> @trunc_v8i32_to_v8i8_return_v16i8(<8 x i32> %vec) nounwind {
|
|
|
|
; AVX1-LABEL: trunc_v8i32_to_v8i8_return_v16i8:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX1-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-LABEL: trunc_v8i32_to_v8i8_return_v16i8:
|
|
|
|
; AVX2: # %bb.0:
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
|
|
|
|
; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-NEXT: vzeroupper
|
|
|
|
; AVX2-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v8i32_to_v8i8_return_v16i8:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v8i32_to_v8i8_return_v16i8:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v8i32_to_v8i8_return_v16i8:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v8i32_to_v8i8_return_v16i8:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v8i32_to_v8i8_return_v16i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovdb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated = trunc <8 x i32> %vec to <8 x i8>
|
|
|
|
%result = shufflevector <8 x i8> %truncated, <8 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
|
|
|
ret <16 x i8> %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i64> @trunc_v4i64_to_v4i16_return_v2i64(<4 x i64> %vec) nounwind {
|
|
|
|
; IR generated from:
|
|
|
|
; return (__m128i) {(long long)__builtin_convertvector((__v4di)x, __v4hi), 0};
|
|
|
|
; AVX1-LABEL: trunc_v4i64_to_v4i16_return_v2i64:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-SLOW-LABEL: trunc_v4i64_to_v4i16_return_v2i64:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-SLOW-NEXT: vzeroupper
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: trunc_v4i64_to_v4i16_return_v2i64:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
|
|
|
; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm1 = [0,2,4,6,4,6,6,7]
|
|
|
|
; AVX2-FAST-NEXT: vpermd %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-FAST-NEXT: vzeroupper
|
|
|
|
; AVX2-FAST-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v4i64_to_v4i16_return_v2i64:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v4i64_to_v4i16_return_v2i64:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v4i64_to_v4i16_return_v2i64:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v4i64_to_v4i16_return_v2i64:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v4i64_to_v4i16_return_v2i64:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated = trunc <4 x i64> %vec to <4 x i16>
|
|
|
|
%bc = bitcast <4 x i16> %truncated to i64
|
|
|
|
%result = insertelement <2 x i64> zeroinitializer, i64 %bc, i32 0
|
|
|
|
ret <2 x i64> %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define <8 x i16> @trunc_v4i64_to_v4i16_with_zext_return_v8i16(<4 x i64> %vec) nounwind {
|
|
|
|
; AVX1-LABEL: trunc_v4i64_to_v4i16_with_zext_return_v8i16:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-SLOW-LABEL: trunc_v4i64_to_v4i16_with_zext_return_v8i16:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-SLOW-NEXT: vzeroupper
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: trunc_v4i64_to_v4i16_with_zext_return_v8i16:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
|
|
|
; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm1 = [0,2,4,6,4,6,6,7]
|
|
|
|
; AVX2-FAST-NEXT: vpermd %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-FAST-NEXT: vzeroupper
|
|
|
|
; AVX2-FAST-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v4i64_to_v4i16_with_zext_return_v8i16:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v4i64_to_v4i16_with_zext_return_v8i16:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v4i64_to_v4i16_with_zext_return_v8i16:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v4i64_to_v4i16_with_zext_return_v8i16:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v4i64_to_v4i16_with_zext_return_v8i16:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated = trunc <4 x i64> %vec to <4 x i16>
|
|
|
|
%truncated.ext = zext <4 x i16> %truncated to <4 x i32>
|
|
|
|
%bc = bitcast <4 x i32> %truncated.ext to <8 x i16>
|
|
|
|
%result = shufflevector <8 x i16> %bc, <8 x i16> zeroinitializer, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 1, i32 3, i32 5, i32 7>
|
|
|
|
ret <8 x i16> %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define <8 x i16> @trunc_v4i64_to_v4i16_via_v4i32_return_v8i16(<4 x i64> %vec) nounwind {
|
|
|
|
; AVX1-LABEL: trunc_v4i64_to_v4i16_via_v4i32_return_v8i16:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-SLOW-LABEL: trunc_v4i64_to_v4i16_via_v4i32_return_v8i16:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-SLOW-NEXT: vzeroupper
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: trunc_v4i64_to_v4i16_via_v4i32_return_v8i16:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
|
|
|
; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm1 = [0,2,4,6,4,6,6,7]
|
|
|
|
; AVX2-FAST-NEXT: vpermd %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-FAST-NEXT: vzeroupper
|
|
|
|
; AVX2-FAST-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v4i64_to_v4i16_via_v4i32_return_v8i16:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v4i64_to_v4i16_via_v4i32_return_v8i16:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v4i64_to_v4i16_via_v4i32_return_v8i16:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v4i64_to_v4i16_via_v4i32_return_v8i16:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v4i64_to_v4i16_via_v4i32_return_v8i16:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated = trunc <4 x i64> %vec to <4 x i32>
|
|
|
|
%bc = bitcast <4 x i32> %truncated to <8 x i16>
|
|
|
|
%result = shufflevector <8 x i16> %bc, <8 x i16> zeroinitializer, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 8, i32 undef, i32 13>
|
|
|
|
ret <8 x i16> %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define <8 x i16> @trunc_v4i64_to_v4i16_return_v8i16(<4 x i64> %vec) nounwind {
|
|
|
|
; AVX1-LABEL: trunc_v4i64_to_v4i16_return_v8i16:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-SLOW-LABEL: trunc_v4i64_to_v4i16_return_v8i16:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-SLOW-NEXT: vzeroupper
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: trunc_v4i64_to_v4i16_return_v8i16:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
|
|
|
; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm1 = [0,2,4,6,4,6,6,7]
|
|
|
|
; AVX2-FAST-NEXT: vpermd %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX2-FAST-NEXT: vzeroupper
|
|
|
|
; AVX2-FAST-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v4i64_to_v4i16_return_v8i16:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v4i64_to_v4i16_return_v8i16:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v4i64_to_v4i16_return_v8i16:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v4i64_to_v4i16_return_v8i16:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v4i64_to_v4i16_return_v8i16:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovqw %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated = trunc <4 x i64> %vec to <4 x i16>
|
|
|
|
%result = shufflevector <4 x i16> %truncated, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
|
|
ret <8 x i16> %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define <16 x i8> @trunc_v4i64_to_v4i8_return_v16i8(<4 x i64> %vec) nounwind {
|
|
|
|
; AVX1-LABEL: trunc_v4i64_to_v4i8_return_v16i8:
|
|
|
|
; AVX1: # %bb.0:
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
|
|
|
|
; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,xmm0[u],zero
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-SLOW-LABEL: trunc_v4i64_to_v4i8_return_v16i8:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,xmm0[u],zero
|
|
|
|
; AVX2-SLOW-NEXT: vzeroupper
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: trunc_v4i64_to_v4i8_return_v16i8:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
|
|
|
; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm1 = [0,2,4,6,4,6,6,7]
|
|
|
|
; AVX2-FAST-NEXT: vpermd %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,xmm0[u],zero
|
|
|
|
; AVX2-FAST-NEXT: vzeroupper
|
|
|
|
; AVX2-FAST-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v4i64_to_v4i8_return_v16i8:
|
|
|
|
; AVX512F: # %bb.0:
|
|
|
|
; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512F-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,xmm0[u],zero
|
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v4i64_to_v4i8_return_v16i8:
|
|
|
|
; AVX512VL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VL-NEXT: vpmovqb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v4i64_to_v4i8_return_v16i8:
|
|
|
|
; AVX512BW: # %bb.0:
|
|
|
|
; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0
|
|
|
|
; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,xmm0[u],zero
|
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v4i64_to_v4i8_return_v16i8:
|
|
|
|
; AVX512BWVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovqb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v4i64_to_v4i8_return_v16i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
2018-06-21 22:16:45 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovqb %ymm0, %xmm0
|
2018-05-22 17:47:42 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
|
|
|
%truncated = trunc <4 x i64> %vec to <4 x i8>
|
|
|
|
%result = shufflevector <4 x i8> %truncated, <4 x i8> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 4, i32 5, i32 6, i32 7, i32 5, i32 5, i32 undef, i32 7>
|
|
|
|
ret <16 x i8> %result
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:48:28 +08:00
|
|
|
define void @shuffle_v16i16_to_v4i16(<16 x i16>* %L, <4 x i16>* %S) nounwind {
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-LABEL: shuffle_v16i16_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX1: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = mem[0,2,2,3]
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX1-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = mem[0,2,2,3]
|
|
|
|
; AVX1-NEXT: vpshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
|
|
|
|
; AVX1-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
2017-12-20 21:12:34 +08:00
|
|
|
; AVX2-SLOW-LABEL: shuffle_v16i16_to_v4i16:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} xmm0 = mem[0,2,2,3]
|
2017-12-20 21:12:34 +08:00
|
|
|
; AVX2-SLOW-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} xmm1 = mem[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vpshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
|
2017-12-20 21:12:34 +08:00
|
|
|
; AVX2-SLOW-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: shuffle_v16i16_to_v4i16:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX2-FAST-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX2-FAST-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-12-20 21:12:34 +08:00
|
|
|
; AVX2-FAST-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,8,9,8,9,10,11,8,9,10,11,12,13,14,15]
|
|
|
|
; AVX2-FAST-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX2-FAST-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX2-FAST-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
|
|
|
; AVX2-FAST-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX2-FAST-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: shuffle_v16i16_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512F-NEXT: vpshufd {{.*#+}} xmm0 = mem[0,2,2,3]
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512F-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512F-NEXT: vpshufd {{.*#+}} xmm1 = mem[0,2,2,3]
|
|
|
|
; AVX512F-NEXT: vpshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
|
|
|
|
; AVX512F-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: shuffle_v16i16_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512VL-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX512VL-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512VL-NEXT: vpmovdw %xmm0, (%rsi)
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: shuffle_v16i16_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512BW-NEXT: vmovdqa 16(%rdi), %xmm1
|
2018-01-10 00:26:06 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,8,9,8,9,10,11,8,9,10,11,12,13,14,15]
|
|
|
|
; AVX512BW-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512BW-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512BW-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: shuffle_v16i16_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX512BWVL-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovdw %xmm0, (%rsi)
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: shuffle_v16i16_to_v4i16:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX512VBMIVL-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2018-01-31 00:01:41 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovdw %xmm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <16 x i16>, <16 x i16>* %L
|
|
|
|
%strided.vec = shufflevector <16 x i16> %vec, <16 x i16> undef, <4 x i32> <i32 0, i32 4, i32 8, i32 12>
|
|
|
|
store <4 x i16> %strided.vec, <4 x i16>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @trunc_v4i64_to_v4i16(<16 x i16>* %L, <4 x i16>* %S) nounwind {
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-LABEL: trunc_v4i64_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX1: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX1-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX1-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
2017-12-20 21:12:34 +08:00
|
|
|
; AVX2-SLOW-LABEL: trunc_v4i64_to_v4i16:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} ymm0 = mem[0,2,2,3,4,6,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX2-SLOW-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX2-SLOW-NEXT: vzeroupper
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: trunc_v4i64_to_v4i16:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
|
|
|
; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm0 = [0,2,4,6,4,6,6,7]
|
|
|
|
; AVX2-FAST-NEXT: vpermd (%rdi), %ymm0, %ymm0
|
|
|
|
; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX2-FAST-NEXT: vmovq %xmm0, (%rsi)
|
|
|
|
; AVX2-FAST-NEXT: vzeroupper
|
|
|
|
; AVX2-FAST-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v4i64_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512F-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX512F-NEXT: vmovq %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512F-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v4i64_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VL-NEXT: vpmovqw %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v4i64_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
|
|
|
|
; AVX512BW-NEXT: vmovq %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BW-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v4i64_to_v4i16:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BWVL-NEXT: vpmovqw %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v4i64_to_v4i16:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VBMIVL-NEXT: vpmovqw %ymm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <16 x i16>, <16 x i16>* %L
|
|
|
|
%bc = bitcast <16 x i16> %vec to <4 x i64>
|
|
|
|
%strided.vec = trunc <4 x i64> %bc to <4 x i16>
|
|
|
|
store <4 x i16> %strided.vec, <4 x i16>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @shuffle_v32i8_to_v4i8(<32 x i8>* %L, <4 x i8>* %S) nounwind {
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX-LABEL: shuffle_v32i8_to_v4i8:
|
|
|
|
; AVX: # %bb.0:
|
|
|
|
; AVX-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX-NEXT: vmovdqa 16(%rdi), %xmm1
|
|
|
|
; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = <0,8,u,u,u,u,u,u,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
|
|
|
|
; AVX-NEXT: vmovd %xmm0, (%rsi)
|
|
|
|
; AVX-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: shuffle_v32i8_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512F-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa {{.*#+}} xmm2 = <0,8,u,u,u,u,u,u,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX512F-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512F-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX512F-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: vmovd %xmm0, (%rsi)
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: shuffle_v32i8_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512VL-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX512VL-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512VL-NEXT: vpmovdb %xmm0, (%rsi)
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: shuffle_v32i8_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %xmm0
|
|
|
|
; AVX512BW-NEXT: vmovdqa 16(%rdi), %xmm1
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa {{.*#+}} xmm2 = <0,8,u,u,u,u,u,u,u,u,u,u,u,u,u,u>
|
|
|
|
; AVX512BW-NEXT: vpshufb %xmm2, %xmm1, %xmm1
|
|
|
|
; AVX512BW-NEXT: vpshufb %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX512BW-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovd %xmm0, (%rsi)
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: shuffle_v32i8_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX512BWVL-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-10-12 08:24:52 +08:00
|
|
|
; AVX512BWVL-NEXT: vpmovdb %xmm0, (%rsi)
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: shuffle_v32i8_to_v4i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX512VBMIVL-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2018-01-31 00:01:41 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vpmovdb %xmm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <32 x i8>, <32 x i8>* %L
|
|
|
|
%strided.vec = shufflevector <32 x i8> %vec, <32 x i8> undef, <4 x i32> <i32 0, i32 8, i32 16, i32 24>
|
|
|
|
store <4 x i8> %strided.vec, <4 x i8>* %S
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
define void @trunc_v4i64_to_v4i8(<32 x i8>* %L, <4 x i8>* %S) nounwind {
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-LABEL: trunc_v4i64_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX1: # %bb.0:
|
[x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.
I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.
For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.
Differential Revision: https://reviews.llvm.org/D54073
llvm-svn: 346595
2018-11-11 04:05:31 +08:00
|
|
|
; AVX1-NEXT: vmovaps (%rdi), %xmm0
|
|
|
|
; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],mem[0,2]
|
2017-06-21 20:58:56 +08:00
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u]
|
|
|
|
; AVX1-NEXT: vmovd %xmm0, (%rsi)
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
2017-12-20 21:12:34 +08:00
|
|
|
; AVX2-SLOW-LABEL: trunc_v4i64_to_v4i8:
|
|
|
|
; AVX2-SLOW: # %bb.0:
|
|
|
|
; AVX2-SLOW-NEXT: vpshufd {{.*#+}} ymm0 = mem[0,2,2,3,4,6,6,7]
|
|
|
|
; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
|
|
|
|
; AVX2-SLOW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u]
|
|
|
|
; AVX2-SLOW-NEXT: vmovd %xmm0, (%rsi)
|
|
|
|
; AVX2-SLOW-NEXT: vzeroupper
|
|
|
|
; AVX2-SLOW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-FAST-LABEL: trunc_v4i64_to_v4i8:
|
|
|
|
; AVX2-FAST: # %bb.0:
|
|
|
|
; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm0 = [0,2,4,6,4,6,6,7]
|
|
|
|
; AVX2-FAST-NEXT: vpermd (%rdi), %ymm0, %ymm0
|
|
|
|
; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u]
|
|
|
|
; AVX2-FAST-NEXT: vmovd %xmm0, (%rsi)
|
|
|
|
; AVX2-FAST-NEXT: vzeroupper
|
|
|
|
; AVX2-FAST-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
;
|
|
|
|
; AVX512F-LABEL: trunc_v4i64_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512F-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u]
|
|
|
|
; AVX512F-NEXT: vmovd %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512F-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: trunc_v4i64_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VL-NEXT: vpmovqb %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: trunc_v4i64_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u]
|
|
|
|
; AVX512BW-NEXT: vmovd %xmm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BW-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: trunc_v4i64_to_v4i8:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512BWVL-NEXT: vpmovqb %ymm0, (%rsi)
|
2017-03-03 17:03:24 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
2017-01-06 00:48:28 +08:00
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: trunc_v4i64_to_v4i8:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa (%rdi), %ymm0
|
|
|
|
; AVX512VBMIVL-NEXT: vpmovqb %ymm0, (%rsi)
|
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
2017-01-06 00:48:28 +08:00
|
|
|
%vec = load <32 x i8>, <32 x i8>* %L
|
|
|
|
%bc = bitcast <32 x i8> %vec to <4 x i64>
|
|
|
|
%strided.vec = trunc <4 x i64> %bc to <4 x i8>
|
|
|
|
store <4 x i8> %strided.vec, <4 x i8>* %S
|
|
|
|
ret void
|
|
|
|
}
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
|
|
|
|
; In this case not all elements are collected from the same source vector, so
|
|
|
|
; the resulting BUILD_VECTOR should not be combined to a truncate.
|
|
|
|
define <16 x i8> @negative(<32 x i8> %v, <32 x i8> %w) nounwind {
|
|
|
|
; AVX1-LABEL: negative:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX1: # %bb.0:
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm2 = xmm0[u,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
|
|
|
|
; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0
|
|
|
|
; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[u],zero,zero,zero,zero,zero,zero,zero,xmm0[0,2,4,6,8,10,12,14]
|
|
|
|
; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0
|
|
|
|
; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
|
|
|
|
; AVX1-NEXT: vpblendvb %xmm2, %xmm0, %xmm1, %xmm0
|
|
|
|
; AVX1-NEXT: vzeroupper
|
|
|
|
; AVX1-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX2-LABEL: negative:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX2: # %bb.0:
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[u,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,u,18,20,22,24,26,28,30,16,18,20,22,24,26,28,30]
|
|
|
|
; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
|
|
|
|
; AVX2-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,3,2,3]
|
2018-02-01 06:04:26 +08:00
|
|
|
; AVX2-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX2-NEXT: vzeroupper
|
|
|
|
; AVX2-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512F-LABEL: negative:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512F: # %bb.0:
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX512F-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[u,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,u,18,20,22,24,26,28,30,16,18,20,22,24,26,28,30]
|
|
|
|
; AVX512F-NEXT: vmovdqa {{.*#+}} ymm2 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
|
|
|
|
; AVX512F-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX512F-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,3,2,3]
|
2018-02-01 06:04:26 +08:00
|
|
|
; AVX512F-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX512F-NEXT: vzeroupper
|
|
|
|
; AVX512F-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512VL-LABEL: negative:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512VL: # %bb.0:
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX512VL-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[u,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,u,18,20,22,24,26,28,30,16,18,20,22,24,26,28,30]
|
|
|
|
; AVX512VL-NEXT: vmovdqa {{.*#+}} ymm2 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
|
|
|
|
; AVX512VL-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX512VL-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,3,2,3]
|
2018-02-01 06:04:26 +08:00
|
|
|
; AVX512VL-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX512VL-NEXT: vzeroupper
|
|
|
|
; AVX512VL-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BW-LABEL: negative:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BW: # %bb.0:
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX512BW-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[u,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,u,18,20,22,24,26,28,30,16,18,20,22,24,26,28,30]
|
|
|
|
; AVX512BW-NEXT: vmovdqa {{.*#+}} ymm2 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
|
|
|
|
; AVX512BW-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0
|
|
|
|
; AVX512BW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,3,2,3]
|
2018-02-01 06:04:26 +08:00
|
|
|
; AVX512BW-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX512BW-NEXT: vzeroupper
|
|
|
|
; AVX512BW-NEXT: retq
|
|
|
|
;
|
|
|
|
; AVX512BWVL-LABEL: negative:
|
2017-12-05 01:18:51 +08:00
|
|
|
; AVX512BWVL: # %bb.0:
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX512BWVL-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[u,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,u,18,20,22,24,26,28,30,16,18,20,22,24,26,28,30]
|
|
|
|
; AVX512BWVL-NEXT: movl $65537, %eax # imm = 0x10001
|
|
|
|
; AVX512BWVL-NEXT: kmovd %eax, %k1
|
|
|
|
; AVX512BWVL-NEXT: vmovdqu8 %ymm1, %ymm0 {%k1}
|
|
|
|
; AVX512BWVL-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,3,2,3]
|
2018-02-01 06:04:26 +08:00
|
|
|
; AVX512BWVL-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
; AVX512BWVL-NEXT: vzeroupper
|
|
|
|
; AVX512BWVL-NEXT: retq
|
2018-01-31 00:01:41 +08:00
|
|
|
;
|
|
|
|
; AVX512VBMIVL-LABEL: negative:
|
|
|
|
; AVX512VBMIVL: # %bb.0:
|
|
|
|
; AVX512VBMIVL-NEXT: vmovdqa {{.*#+}} ymm2 = [32,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,48,18,20,22,24,26,28,30,16,18,20,22,24,26,28,30]
|
|
|
|
; AVX512VBMIVL-NEXT: vpermt2b %ymm1, %ymm2, %ymm0
|
2018-02-01 06:04:26 +08:00
|
|
|
; AVX512VBMIVL-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0
|
2018-01-31 00:01:41 +08:00
|
|
|
; AVX512VBMIVL-NEXT: vzeroupper
|
|
|
|
; AVX512VBMIVL-NEXT: retq
|
DAGCombine: Combine BUILD_VECTOR to TRUNCATE
Summary:
Add a combine for creating a truncate to replace a build_vector composed of extracts with
indices that form a stride-2^N series.
Example:
v8i32 V = ...
v4i32 build_vector((extract_elt V, 0), (extract_elt V, 2), (extract_elt V, 4), (extract_elt V, 6))
-->
v4i32 truncate (bitcast V to v4i64)
Related discussion in llvm-dev about canonicalizing shuffles to
truncates in LLVM IR:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108936.html.
Reviewers: spatel, RKSimon, efriedma, igorb, craig.topper, wolfgangp, delena
Reviewed By: delena
Subscribers: guyblank, delena, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D34077
llvm-svn: 307036
2017-07-03 23:47:40 +08:00
|
|
|
%strided.vec = shufflevector <32 x i8> %v, <32 x i8> undef, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
|
|
|
|
%w0 = extractelement <32 x i8> %w, i32 0
|
|
|
|
%merged = insertelement <16 x i8> %strided.vec, i8 %w0, i32 0
|
|
|
|
ret <16 x i8> %merged
|
|
|
|
}
|