diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 35239b79f188..94f3d8c60269 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -37745,27 +37745,27 @@ static SDValue lowerX86FPLogicOp(SDNode *N, SelectionDAG &DAG, const X86Subtarget &Subtarget) { MVT VT = N->getSimpleValueType(0); // If we have integer vector types available, use the integer opcodes. - if ((VT.isVector() || VT == MVT::f128) && Subtarget.hasSSE2()) { - SDLoc dl(N); + if (!VT.isVector() || !Subtarget.hasSSE2()) + return SDValue(); - unsigned IntBits = std::min(VT.getScalarSizeInBits(), 64U); - MVT IntSVT = MVT::getIntegerVT(IntBits); - MVT IntVT = MVT::getVectorVT(IntSVT, VT.getSizeInBits() / IntBits); + SDLoc dl(N); - SDValue Op0 = DAG.getBitcast(IntVT, N->getOperand(0)); - SDValue Op1 = DAG.getBitcast(IntVT, N->getOperand(1)); - unsigned IntOpcode; - switch (N->getOpcode()) { - default: llvm_unreachable("Unexpected FP logic op"); - case X86ISD::FOR: IntOpcode = ISD::OR; break; - case X86ISD::FXOR: IntOpcode = ISD::XOR; break; - case X86ISD::FAND: IntOpcode = ISD::AND; break; - case X86ISD::FANDN: IntOpcode = X86ISD::ANDNP; break; - } - SDValue IntOp = DAG.getNode(IntOpcode, dl, IntVT, Op0, Op1); - return DAG.getBitcast(VT, IntOp); + unsigned IntBits = VT.getScalarSizeInBits(); + MVT IntSVT = MVT::getIntegerVT(IntBits); + MVT IntVT = MVT::getVectorVT(IntSVT, VT.getSizeInBits() / IntBits); + + SDValue Op0 = DAG.getBitcast(IntVT, N->getOperand(0)); + SDValue Op1 = DAG.getBitcast(IntVT, N->getOperand(1)); + unsigned IntOpcode; + switch (N->getOpcode()) { + default: llvm_unreachable("Unexpected FP logic op"); + case X86ISD::FOR: IntOpcode = ISD::OR; break; + case X86ISD::FXOR: IntOpcode = ISD::XOR; break; + case X86ISD::FAND: IntOpcode = ISD::AND; break; + case X86ISD::FANDN: IntOpcode = X86ISD::ANDNP; break; } - return SDValue(); + SDValue IntOp = DAG.getNode(IntOpcode, dl, IntVT, Op0, Op1); + return DAG.getBitcast(VT, IntOp); } diff --git a/llvm/lib/Target/X86/X86InstrVecCompiler.td b/llvm/lib/Target/X86/X86InstrVecCompiler.td index 0aeed51dde5c..c417dc99b84d 100644 --- a/llvm/lib/Target/X86/X86InstrVecCompiler.td +++ b/llvm/lib/Target/X86/X86InstrVecCompiler.td @@ -466,8 +466,6 @@ def : Pat<(loadf128 addr:$src), (VMOVUPSZ128rm addr:$src)>; } -// With SSE2 the DAG combiner converts fp logic ops to integer logic ops to -// reduce patterns. let Predicates = [UseSSE1] in { // andps is shorter than andpd or pand. andps is SSE and andpd/pand are in SSE2 def : Pat<(f128 (X86fand VR128:$src1, (memopf128 addr:$src2))), @@ -489,4 +487,23 @@ def : Pat<(f128 (X86fxor VR128:$src1, VR128:$src2)), (XORPSrr VR128:$src1, VR128:$src2)>; } +let Predicates = [HasAVX] in { +// andps is shorter than andpd or pand. andps is SSE and andpd/pand are in SSE2 +def : Pat<(f128 (X86fand VR128:$src1, (loadf128 addr:$src2))), + (VANDPSrm VR128:$src1, f128mem:$src2)>; +def : Pat<(f128 (X86fand VR128:$src1, VR128:$src2)), + (VANDPSrr VR128:$src1, VR128:$src2)>; + +def : Pat<(f128 (X86for VR128:$src1, (loadf128 addr:$src2))), + (VORPSrm VR128:$src1, f128mem:$src2)>; + +def : Pat<(f128 (X86for VR128:$src1, VR128:$src2)), + (VORPSrr VR128:$src1, VR128:$src2)>; + +def : Pat<(f128 (X86fxor VR128:$src1, (loadf128 addr:$src2))), + (VXORPSrm VR128:$src1, f128mem:$src2)>; + +def : Pat<(f128 (X86fxor VR128:$src1, VR128:$src2)), + (VXORPSrr VR128:$src1, VR128:$src2)>; +}