summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Pettersson <bjorn.a.pettersson@ericsson.com>2019-08-16 13:16:38 +0000
committerBjorn Pettersson <bjorn.a.pettersson@ericsson.com>2019-08-16 13:16:38 +0000
commit6a75061e36fe1998e51ba9de2702f756b6ad5a8e (patch)
tree197b54a2436e082f5e53bbc48fe52d14edb5925c
parent8c2c5f5045b7a91c2a69fe232a11ce8bec9a5744 (diff)
downloadbcm5719-llvm-6a75061e36fe1998e51ba9de2702f756b6ad5a8e.tar.gz
bcm5719-llvm-6a75061e36fe1998e51ba9de2702f756b6ad5a8e.zip
[X86] Add test case for future MULFIX DAG combine folds. NFC
Add some test cases displaying the lack of DAG combine folds for SMULFIX/UMULFIX/SMULFIXSAT when either multiplicand is undef or zero. It seems like widening vector legalization for X86 can introduce fixed point multiplication of undef values. So that is one way that such operations could appear during ISel. Multiplication with zero is probably more unlikely, and could potentially be handled by InstCombine. But I do not think it would hurt to do such folds in DAGCombiner. This patch only adds the test case. The folds will be added in a follow up patch. llvm-svn: 369102
-rw-r--r--llvm/test/CodeGen/X86/mulfix_combine.ll206
1 files changed, 206 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/X86/mulfix_combine.ll b/llvm/test/CodeGen/X86/mulfix_combine.ll
new file mode 100644
index 00000000000..652f94f8829
--- /dev/null
+++ b/llvm/test/CodeGen/X86/mulfix_combine.ll
@@ -0,0 +1,206 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-linux -o - | FileCheck %s
+
+declare i32 @llvm.smul.fix.i32(i32, i32, i32 immarg)
+declare i32 @llvm.umul.fix.i32(i32, i32, i32 immarg)
+declare i32 @llvm.smul.fix.sat.i32(i32, i32, i32 immarg)
+
+declare <4 x i32> @llvm.smul.fix.v4i32(<4 x i32>, <4 x i32>, i32 immarg)
+declare <4 x i32> @llvm.umul.fix.v4i32(<4 x i32>, <4 x i32>, i32 immarg)
+declare <4 x i32> @llvm.smul.fix.sat.v4i32(<4 x i32>, <4 x i32>, i32 immarg)
+
+define i32 @smulfix_undef(i32 %y) nounwind {
+; CHECK-LABEL: smulfix_undef:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: shrdl $2, %eax, %eax
+; CHECK-NEXT: retq
+ %tmp = call i32 @llvm.smul.fix.i32(i32 undef, i32 %y, i32 2)
+ ret i32 %tmp
+}
+
+define i32 @smulfix_zero(i32 %y) nounwind {
+; CHECK-LABEL: smulfix_zero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: shrdl $2, %eax, %eax
+; CHECK-NEXT: retq
+ %tmp = call i32 @llvm.smul.fix.i32(i32 0, i32 %y, i32 2)
+ ret i32 %tmp
+}
+
+define i32 @umulfix_undef(i32 %y) nounwind {
+; CHECK-LABEL: umulfix_undef:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: shrdl $2, %eax, %eax
+; CHECK-NEXT: retq
+ %tmp = call i32 @llvm.umul.fix.i32(i32 undef, i32 %y, i32 2)
+ ret i32 %tmp
+}
+
+define i32 @umulfix_zero(i32 %y) nounwind {
+; CHECK-LABEL: umulfix_zero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: shrdl $2, %eax, %eax
+; CHECK-NEXT: retq
+ %tmp = call i32 @llvm.umul.fix.i32(i32 0, i32 %y, i32 2)
+ ret i32 %tmp
+}
+
+define i32 @smulfixsat_undef(i32 %y) nounwind {
+; CHECK-LABEL: smulfixsat_undef:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: shrdl $2, %eax, %eax
+; CHECK-NEXT: movl $1, %ecx
+; CHECK-NEXT: negl %ecx
+; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; CHECK-NEXT: cmovlel %eax, %ecx
+; CHECK-NEXT: movl $-2, %eax
+; CHECK-NEXT: negl %eax
+; CHECK-NEXT: movl $-2147483648, %eax # imm = 0x80000000
+; CHECK-NEXT: cmovgel %ecx, %eax
+; CHECK-NEXT: retq
+ %tmp = call i32 @llvm.smul.fix.sat.i32(i32 undef, i32 %y, i32 2)
+ ret i32 %tmp
+}
+
+define i32 @smulfixsat_zero(i32 %y) nounwind {
+; CHECK-LABEL: smulfixsat_zero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: shrdl $2, %eax, %eax
+; CHECK-NEXT: movl $1, %ecx
+; CHECK-NEXT: negl %ecx
+; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; CHECK-NEXT: cmovlel %eax, %ecx
+; CHECK-NEXT: movl $-2, %eax
+; CHECK-NEXT: negl %eax
+; CHECK-NEXT: movl $-2147483648, %eax # imm = 0x80000000
+; CHECK-NEXT: cmovgel %ecx, %eax
+; CHECK-NEXT: retq
+ %tmp = call i32 @llvm.smul.fix.sat.i32(i32 0, i32 %y, i32 2)
+ ret i32 %tmp
+}
+
+define <4 x i32> @vec_smulfix_undef(<4 x i32> %y) nounwind {
+; CHECK-LABEL: vec_smulfix_undef:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
+; CHECK-NEXT: pxor %xmm2, %xmm2
+; CHECK-NEXT: pcmpgtd %xmm0, %xmm2
+; CHECK-NEXT: pand %xmm0, %xmm2
+; CHECK-NEXT: pmuludq %xmm0, %xmm0
+; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3]
+; CHECK-NEXT: pmuludq %xmm0, %xmm1
+; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
+; CHECK-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; CHECK-NEXT: psubd %xmm2, %xmm0
+; CHECK-NEXT: pslld $30, %xmm0
+; CHECK-NEXT: retq
+ %tmp = call <4 x i32> @llvm.smul.fix.v4i32(<4 x i32> undef, <4 x i32> %y, i32 2)
+ ret <4 x i32> %tmp
+}
+
+define <4 x i32> @vec_smulfix_zero(<4 x i32> %y) nounwind {
+; CHECK-LABEL: vec_smulfix_zero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pxor %xmm1, %xmm1
+; CHECK-NEXT: pxor %xmm2, %xmm2
+; CHECK-NEXT: pmuludq %xmm0, %xmm2
+; CHECK-NEXT: pshufd {{.*#+}} xmm3 = xmm2[0,2,2,3]
+; CHECK-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,1,3,3]
+; CHECK-NEXT: pmuludq %xmm1, %xmm4
+; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm4[0,2,2,3]
+; CHECK-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1]
+; CHECK-NEXT: psrld $2, %xmm3
+; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm2[1,3,2,3]
+; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm4[1,3,2,3]
+; CHECK-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; CHECK-NEXT: pslld $30, %xmm0
+; CHECK-NEXT: por %xmm3, %xmm0
+; CHECK-NEXT: retq
+ %tmp = call <4 x i32> @llvm.smul.fix.v4i32(<4 x i32> <i32 0, i32 0, i32 0, i32 0>, <4 x i32> %y, i32 2)
+ ret <4 x i32> %tmp
+}
+
+define <4 x i32> @vec_umulfix_undef(<4 x i32> %y) nounwind {
+; CHECK-LABEL: vec_umulfix_undef:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
+; CHECK-NEXT: pmuludq %xmm0, %xmm0
+; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3]
+; CHECK-NEXT: pmuludq %xmm0, %xmm1
+; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
+; CHECK-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; CHECK-NEXT: pslld $30, %xmm0
+; CHECK-NEXT: retq
+ %tmp = call <4 x i32> @llvm.umul.fix.v4i32(<4 x i32> undef, <4 x i32> %y, i32 2)
+ ret <4 x i32> %tmp
+}
+
+define <4 x i32> @vec_umulfix_zero(<4 x i32> %y) nounwind {
+; CHECK-LABEL: vec_umulfix_zero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pxor %xmm1, %xmm1
+; CHECK-NEXT: pxor %xmm2, %xmm2
+; CHECK-NEXT: pmuludq %xmm0, %xmm2
+; CHECK-NEXT: pshufd {{.*#+}} xmm3 = xmm2[0,2,2,3]
+; CHECK-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,1,3,3]
+; CHECK-NEXT: pmuludq %xmm1, %xmm4
+; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm4[0,2,2,3]
+; CHECK-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1]
+; CHECK-NEXT: psrld $2, %xmm3
+; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm2[1,3,2,3]
+; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm4[1,3,2,3]
+; CHECK-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; CHECK-NEXT: pslld $30, %xmm0
+; CHECK-NEXT: por %xmm3, %xmm0
+; CHECK-NEXT: retq
+ %tmp = call <4 x i32> @llvm.umul.fix.v4i32(<4 x i32> <i32 0, i32 0, i32 0, i32 0>, <4 x i32> %y, i32 2)
+ ret <4 x i32> %tmp
+}
+
+define <4 x i32> @vec_smulfixsat_undef(<4 x i32> %y) nounwind {
+; CHECK-LABEL: vec_smulfixsat_undef:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: shrdl $2, %eax, %eax
+; CHECK-NEXT: movl $1, %ecx
+; CHECK-NEXT: negl %ecx
+; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; CHECK-NEXT: cmovlel %eax, %ecx
+; CHECK-NEXT: movl $-2, %eax
+; CHECK-NEXT: negl %eax
+; CHECK-NEXT: movl $-2147483648, %eax # imm = 0x80000000
+; CHECK-NEXT: cmovgel %ecx, %eax
+; CHECK-NEXT: movd %eax, %xmm0
+; CHECK-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0,0,1,1]
+; CHECK-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0,0]
+; CHECK-NEXT: retq
+ %tmp = call <4 x i32> @llvm.smul.fix.sat.v4i32(<4 x i32> undef, <4 x i32> %y, i32 2)
+ ret <4 x i32> %tmp
+}
+
+define <4 x i32> @vec_smulfixsat_zero(<4 x i32> %y) nounwind {
+; CHECK-LABEL: vec_smulfixsat_zero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: shrdl $2, %eax, %eax
+; CHECK-NEXT: movl $1, %ecx
+; CHECK-NEXT: negl %ecx
+; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; CHECK-NEXT: cmovlel %eax, %ecx
+; CHECK-NEXT: movl $-2, %eax
+; CHECK-NEXT: negl %eax
+; CHECK-NEXT: movl $-2147483648, %eax # imm = 0x80000000
+; CHECK-NEXT: cmovgel %ecx, %eax
+; CHECK-NEXT: movd %eax, %xmm0
+; CHECK-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0,0,1,1]
+; CHECK-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0,0]
+; CHECK-NEXT: retq
+ %tmp = call <4 x i32> @llvm.smul.fix.sat.v4i32(<4 x i32> <i32 0, i32 0, i32 0, i32 0>, <4 x i32> %y, i32 2)
+ ret <4 x i32> %tmp
+}
OpenPOWER on IntegriCloud