From 18136471116532e630ce7626c7a660c5495514d8 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 23 Sep 2015 17:00:06 +0000 Subject: [PATCH] [x86] replace integer 'and' ops with packed SSE FP 'and' ops when operating on FP scalars Turn this: movd %xmm0, %eax movd %xmm1, %ecx andl %eax, %ecx movd %ecx, %xmm0 into this: andps %xmm1, %xmm0 This is related to, but does not solve: https://llvm.org/bugs/show_bug.cgi?id=22428 Differential Revision: http://reviews.llvm.org/D13065 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248395 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 18 ++++++++++++++++++ test/CodeGen/X86/fp-logic.ll | 15 ++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index fbead736ec0..a19ffcfbe54 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -24447,6 +24447,24 @@ static SDValue PerformAndCombine(SDNode *N, SelectionDAG &DAG, } } // BEXTR + // If both input operands are being cast from floating point types, + // try to convert this into a floating point logic node to avoid + // unnecessary moves from SSE to integer registers. + // FIXME: Split this into a helper function, so it can also be used with + // or/xor combining. + if (N0.getOpcode() == ISD::BITCAST && N1.getOpcode() == ISD::BITCAST && + ((Subtarget->hasSSE1() && VT == MVT::i32) || + (Subtarget->hasSSE2() && VT == MVT::i64))) { + SDValue N00 = N0.getOperand(0); + SDValue N10 = N1.getOperand(0); + EVT N00Type = N00.getValueType(); + EVT N10Type = N10.getValueType(); + if (N00Type.isFloatingPoint() && N10Type.isFloatingPoint()) { + SDValue FLogic = DAG.getNode(X86ISD::FAND, DL, N00Type, N00, N10); + return DAG.getBitcast(VT, FLogic); + } + } + return SDValue(); } diff --git a/test/CodeGen/X86/fp-logic.ll b/test/CodeGen/X86/fp-logic.ll index d047f7742c8..0b714ffe36f 100644 --- a/test/CodeGen/X86/fp-logic.ll +++ b/test/CodeGen/X86/fp-logic.ll @@ -142,9 +142,8 @@ define float @f8(float %x) { define i32 @f9(float %x, float %y) { ; CHECK-LABEL: f9: ; CHECK: # BB#0: -; CHECK-NEXT: movd %xmm0, %ecx -; CHECK-NEXT: movd %xmm1, %eax -; CHECK-NEXT: andl %ecx, %eax +; CHECK-NEXT: andps %xmm1, %xmm0 +; CHECK-NEXT: movd %xmm0, %eax ; CHECK-NEXT: retq %bc1 = bitcast float %x to i32 @@ -158,10 +157,7 @@ define i32 @f9(float %x, float %y) { define float @f10(float %x, float %y) { ; CHECK-LABEL: f10: ; CHECK: # BB#0: -; CHECK-NEXT: movd %xmm0, %eax -; CHECK-NEXT: movd %xmm1, %ecx -; CHECK-NEXT: andl %eax, %ecx -; CHECK-NEXT: movd %ecx, %xmm0 +; CHECK-NEXT: andps %xmm1, %xmm0 ; CHECK-NEXT: retq %bc1 = bitcast float %x to i32 @@ -208,10 +204,7 @@ define float @xor(float %x, float %y) { define double @doubles(double %x, double %y) { ; CHECK-LABEL: doubles: ; CHECK: # BB#0: -; CHECK-NEXT: movd %xmm0, %rax -; CHECK-NEXT: movd %xmm1, %rcx -; CHECK-NEXT: andq %rax, %rcx -; CHECK-NEXT: movd %rcx, %xmm0 +; CHECK-NEXT: andpd %xmm1, %xmm0 ; CHECK-NEXT: retq %bc1 = bitcast double %x to i64 -- 2.11.0