}
-; In the following 3 tests, both zero mask bits of the immediate are set.
+; In the following 4 tests, both zero mask bits of the immediate are set.
define <4 x double> @perm2pd_0x88(<4 x double> %a0, <4 x double> %a1) {
%res = call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %a0, <4 x double> %a1, i8 136)
; CHECK-NEXT: ret <8 x i32> zeroinitializer
}
+define <4 x i64> @perm2i_0x88(<4 x i64> %a0, <4 x i64> %a1) {
+ %res = call <4 x i64> @llvm.x86.avx2.vperm2i128(<4 x i64> %a0, <4 x i64> %a1, i8 136)
+ ret <4 x i64> %res
+
+; CHECK-LABEL: @perm2i_0x88
+; CHECK-NEXT: ret <4 x i64> zeroinitializer
+}
+
; The other control bits are ignored when zero mask bits of the immediate are set.
ret <4 x double> %res
; CHECK-LABEL: @perm2pd_0x02
-; CHECK-NEXT: %1 = shufflevector <4 x double> %a0, <4 x double> %a1, <4 x i32> <i32 4, i32 5, i32 0, i32 1>
+; CHECK-NEXT: %1 = shufflevector <4 x double> %a1, <4 x double> %a0, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
; CHECK-NEXT: ret <4 x double> %1
}
ret <4 x double> %res
; CHECK-LABEL: @perm2pd_0x03
-; CHECK-NEXT: %1 = shufflevector <4 x double> %a0, <4 x double> %a1, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
+; CHECK-NEXT: %1 = shufflevector <4 x double> %a1, <4 x double> %a0, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
; CHECK-NEXT: ret <4 x double> %1
}
ret <4 x double> %res
; CHECK-LABEL: @perm2pd_0x12
-; CHECK-NEXT: %1 = shufflevector <4 x double> %a0, <4 x double> %a1, <4 x i32> <i32 4, i32 5, i32 2, i32 3>
+; CHECK-NEXT: %1 = shufflevector <4 x double> %a1, <4 x double> %a0, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
; CHECK-NEXT: ret <4 x double> %1
}
ret <4 x double> %res
; CHECK-LABEL: @perm2pd_0x13
-; CHECK-NEXT: %1 = shufflevector <4 x double> %a0, <4 x double> %a1, <4 x i32> <i32 6, i32 7, i32 2, i32 3>
+; CHECK-NEXT: %1 = shufflevector <4 x double> %a1, <4 x double> %a0, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
; CHECK-NEXT: ret <4 x double> %1
}
}
-; Confirm that when a single zero mask bit is set, we do nothing.
+; Confirm that the AVX2 version works the same.
+
+define <4 x i64> @perm2i_0x33(<4 x i64> %a0, <4 x i64> %a1) {
+ %res = call <4 x i64> @llvm.x86.avx2.vperm2i128(<4 x i64> %a0, <4 x i64> %a1, i8 51)
+ ret <4 x i64> %res
+
+; CHECK-LABEL: @perm2i_0x33
+; CHECK-NEXT: %1 = shufflevector <4 x i64> %a1, <4 x i64> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3>
+; CHECK-NEXT: ret <4 x i64> %1
+}
+
+
+; Confirm that when a single zero mask bit is set, we replace a source vector with zeros.
+
+define <4 x double> @perm2pd_0x81(<4 x double> %a0, <4 x double> %a1) {
+ %res = call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %a0, <4 x double> %a1, i8 129)
+ ret <4 x double> %res
+
+; CHECK-LABEL: @perm2pd_0x81
+; CHECK-NEXT: shufflevector <4 x double> %a0, <4 x double> <double 0.0{{.*}}<4 x i32> <i32 2, i32 3, i32 4, i32 5>
+; CHECK-NEXT: ret <4 x double>
+}
define <4 x double> @perm2pd_0x83(<4 x double> %a0, <4 x double> %a1) {
%res = call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %a0, <4 x double> %a1, i8 131)
ret <4 x double> %res
; CHECK-LABEL: @perm2pd_0x83
-; CHECK-NEXT: call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %a0, <4 x double> %a1, i8 -125)
+; CHECK-NEXT: shufflevector <4 x double> %a1, <4 x double> <double 0.0{{.*}}, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
; CHECK-NEXT: ret <4 x double>
}
+define <4 x double> @perm2pd_0x28(<4 x double> %a0, <4 x double> %a1) {
+ %res = call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %a0, <4 x double> %a1, i8 40)
+ ret <4 x double> %res
-; Confirm that when the other zero mask bit is set, we do nothing. Also confirm that an ignored bit has no effect.
+; CHECK-LABEL: @perm2pd_0x28
+; CHECK-NEXT: shufflevector <4 x double> <double 0.0{{.*}}, <4 x double> %a1, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; CHECK-NEXT: ret <4 x double>
+}
-define <4 x double> @perm2pd_0x48(<4 x double> %a0, <4 x double> %a1) {
- %res = call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %a0, <4 x double> %a1, i8 72)
+define <4 x double> @perm2pd_0x08(<4 x double> %a0, <4 x double> %a1) {
+ %res = call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %a0, <4 x double> %a1, i8 8)
ret <4 x double> %res
-; CHECK-LABEL: @perm2pd_0x48
-; CHECK-NEXT: call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %a0, <4 x double> %a1, i8 72)
+; CHECK-LABEL: @perm2pd_0x08
+; CHECK-NEXT: shufflevector <4 x double> <double 0.0{{.*}}, <4 x double> %a0, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
; CHECK-NEXT: ret <4 x double>
}
+; Check one more with the AVX2 version.
+
+define <4 x i64> @perm2i_0x28(<4 x i64> %a0, <4 x i64> %a1) {
+ %res = call <4 x i64> @llvm.x86.avx2.vperm2i128(<4 x i64> %a0, <4 x i64> %a1, i8 40)
+ ret <4 x i64> %res
+
+; CHECK-LABEL: @perm2i_0x28
+; CHECK-NEXT: shufflevector <4 x i64> <i64 0{{.*}}, <4 x i64> %a1, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; CHECK-NEXT: ret <4 x i64>
+}
+
declare <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double>, <4 x double>, i8) nounwind readnone
declare <8 x float> @llvm.x86.avx.vperm2f128.ps.256(<8 x float>, <8 x float>, i8) nounwind readnone
declare <8 x i32> @llvm.x86.avx.vperm2f128.si.256(<8 x i32>, <8 x i32>, i8) nounwind readnone
+declare <4 x i64> @llvm.x86.avx2.vperm2i128(<4 x i64>, <4 x i64>, i8) nounwind readnone