From adb6a3649e7ec5ff51da18771cb30c372462572d Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 23 Jul 2014 20:41:43 +0000 Subject: [PATCH] [X86,AArch64] Extend vcmp w/ unary op combine to work w/ more constants. The transform to constant fold unary operations with an AND across a vector comparison applies when the constant is not a splat of a scalar as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213800 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64ISelLowering.cpp | 6 +++--- lib/Target/X86/X86ISelLowering.cpp | 6 +++--- .../AArch64/arm64-setcc-int-to-fp-combine.ll | 20 +++++++++++++++++++ .../X86/x86-setcc-int-to-fp-combine.ll | 18 +++++++++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 9b8ff72dded..02470304372 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -6501,14 +6501,14 @@ static SDValue performVectorCompareAndMaskUnaryOpCombine(SDNode *N, VT.getSizeInBits() != N->getOperand(0)->getValueType(0).getSizeInBits()) return SDValue(); - // Now check that the other operand of the AND is a constant splat. We could + // Now check that the other operand of the AND is a constant. We could // make the transformation for non-constant splats as well, but it's unclear // that would be a benefit as it would not eliminate any operations, just // perform one more step in scalar code before moving to the vector unit. if (BuildVectorSDNode *BV = dyn_cast(N->getOperand(0)->getOperand(1))) { - // Bail out if the vector isn't a constant splat. - if (!BV->getConstantSplatNode()) + // Bail out if the vector isn't a constant. + if (!BV->isConstant()) return SDValue(); // Everything checks out. Build up the new and improved node. diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 95666a47da8..81889d0a745 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -21815,14 +21815,14 @@ static SDValue performVectorCompareAndMaskUnaryOpCombine(SDNode *N, VT.getSizeInBits() != N->getOperand(0)->getValueType(0).getSizeInBits()) return SDValue(); - // Now check that the other operand of the AND is a constant splat. We could + // Now check that the other operand of the AND is a constant. We could // make the transformation for non-constant splats as well, but it's unclear // that would be a benefit as it would not eliminate any operations, just // perform one more step in scalar code before moving to the vector unit. if (BuildVectorSDNode *BV = dyn_cast(N->getOperand(0)->getOperand(1))) { - // Bail out if the vector isn't a constant splat. - if (!BV->getConstantSplatNode()) + // Bail out if the vector isn't a constant. + if (!BV->isConstant()) return SDValue(); // Everything checks out. Build up the new and improved node. diff --git a/test/CodeGen/AArch64/arm64-setcc-int-to-fp-combine.ll b/test/CodeGen/AArch64/arm64-setcc-int-to-fp-combine.ll index 045c9cd9aeb..74ca61f57d7 100644 --- a/test/CodeGen/AArch64/arm64-setcc-int-to-fp-combine.ll +++ b/test/CodeGen/AArch64/arm64-setcc-int-to-fp-combine.ll @@ -25,3 +25,23 @@ define void @foo1(<4 x float> %val, <4 x float> %test, <4 x double>* %p) nounwin store <4 x double> %result, <4 x double>* %p ret void } + +; Fold explicit AND operations when the constant isn't a splat of a single +; scalar value like what the zext creates. +define <4 x float> @foo2(<4 x float> %val, <4 x float> %test) nounwind { +; CHECK-LABEL: lCPI2_0: +; CHECK-NEXT: .long 1065353216 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1065353216 +; CHECK-NEXT: .long 0 +; CHECK-LABEL: foo2: +; CHECK: adrp x8, lCPI2_0@PAGE +; CHECK: ldr q2, [x8, lCPI2_0@PAGEOFF] +; CHECK-NEXT: fcmeq.4s v0, v0, v1 +; CHECK-NEXT: and.16b v0, v0, v2 + %cmp = fcmp oeq <4 x float> %val, %test + %ext = zext <4 x i1> %cmp to <4 x i32> + %and = and <4 x i32> %ext, + %result = sitofp <4 x i32> %and to <4 x float> + ret <4 x float> %result +} diff --git a/test/CodeGen/X86/x86-setcc-int-to-fp-combine.ll b/test/CodeGen/X86/x86-setcc-int-to-fp-combine.ll index f737519bd15..4fe6c664df5 100644 --- a/test/CodeGen/X86/x86-setcc-int-to-fp-combine.ll +++ b/test/CodeGen/X86/x86-setcc-int-to-fp-combine.ll @@ -54,3 +54,21 @@ define void @foo2(<4 x float>* noalias %result) nounwind { store <4 x float> %val, <4 x float>* %result ret void } + +; Fold explicit AND operations when the constant isn't a splat of a single +; scalar value like what the zext creates. +define <4 x float> @foo3(<4 x float> %val, <4 x float> %test) nounwind { +; CHECK-LABEL: LCPI3_0: +; CHECK-NEXT: .long 1065353216 ## float 1.000000e+00 +; CHECK-NEXT: .long 0 ## float 0.000000e+00 +; CHECK-NEXT: .long 1065353216 ## float 1.000000e+00 +; CHECK-NEXT: .long 0 ## float 0.000000e+00 +; CHECK-LABEL: foo3: +; CHECK: cmpeqps %xmm1, %xmm0 +; CHECK-NEXT: andps LCPI3_0(%rip), %xmm0 + %cmp = fcmp oeq <4 x float> %val, %test + %ext = zext <4 x i1> %cmp to <4 x i32> + %and = and <4 x i32> %ext, + %result = sitofp <4 x i32> %and to <4 x float> + ret <4 x float> %result +}