Index: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp @@ -24447,6 +24447,24 @@ } } // 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(); } Index: llvm/trunk/test/CodeGen/X86/fp-logic.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/fp-logic.ll +++ llvm/trunk/test/CodeGen/X86/fp-logic.ll @@ -142,9 +142,8 @@ 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 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 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