diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index a3fb00af1ea..f211c7260f8 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -8445,16 +8445,25 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) const { unsigned Opc = EltVT == MVT::f32 ? X86ISD::CMPPS : X86ISD::CMPPD; bool Swap = false; + // SSE Condition code mapping: + // 0 - EQ + // 1 - LT + // 2 - LE + // 3 - UNORD + // 4 - NEQ + // 5 - NLT + // 6 - NLE + // 7 - ORD switch (SetCCOpcode) { default: break; case ISD::SETOEQ: case ISD::SETEQ: SSECC = 0; break; - case ISD::SETOGT: - case ISD::SETGT: Swap = true; // Fallthrough - case ISD::SETLT: - case ISD::SETOLT: SSECC = 1; break; case ISD::SETOGE: case ISD::SETGE: Swap = true; // Fallthrough + case ISD::SETLT: + case ISD::SETOLT: SSECC = 1; break; + case ISD::SETOGT: + case ISD::SETGT: Swap = true; // Fallthrough case ISD::SETLE: case ISD::SETOLE: SSECC = 2; break; case ISD::SETUO: SSECC = 3; break; @@ -8473,20 +8482,20 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) const { if (SSECC == 8) { if (SetCCOpcode == ISD::SETUEQ) { SDValue UNORD, EQ; - UNORD = DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(3, MVT::i8)); - EQ = DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(0, MVT::i8)); + UNORD = DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(3, MVT::i8)); + EQ = DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(0, MVT::i8)); return DAG.getNode(ISD::OR, dl, VT, UNORD, EQ); } else if (SetCCOpcode == ISD::SETONE) { SDValue ORD, NEQ; - ORD = DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(7, MVT::i8)); - NEQ = DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(4, MVT::i8)); + ORD = DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(7, MVT::i8)); + NEQ = DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(4, MVT::i8)); return DAG.getNode(ISD::AND, dl, VT, ORD, NEQ); } llvm_unreachable("Illegal FP comparison"); } // Handle all other FP comparisons here. - return DAG.getNode(Opc, dl, VT, Op0, Op1, DAG.getConstant(SSECC, MVT::i8)); + return DAG.getNode(Opc, dl, VT, Op1, Op0, DAG.getConstant(SSECC, MVT::i8)); } // Break 256-bit integer vector compare into smaller ones. diff --git a/test/CodeGen/X86/avx-blend.ll b/test/CodeGen/X86/avx-blend.ll index e025e26bde9..e3008d9e165 100644 --- a/test/CodeGen/X86/avx-blend.ll +++ b/test/CodeGen/X86/avx-blend.ll @@ -82,4 +82,23 @@ define <8 x i64> @vsel_i648(<8 x i64> %v1, <8 x i64> %v2) { ret <8 x i64> %vsel } +;; TEST blend + compares +; CHECK: A +define <2 x double> @A(<2 x double> %x, <2 x double> %y) { + ; CHECK: vcmpltpd + ; CHECK: vblendvpd + %max_is_x = fcmp oge <2 x double> %x, %y + %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y + ret <2 x double> %max +} + +; CHECK: B +define <2 x double> @B(<2 x double> %x, <2 x double> %y) { + ; CHECK: vcmplepd + ; CHECK: vblendvpd + %max_is_x = fcmp ogt <2 x double> %x, %y + %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y + ret <2 x double> %max +} + diff --git a/test/CodeGen/X86/sse41-blend.ll b/test/CodeGen/X86/sse41-blend.ll index 3c854ac6066..aba2c129e3a 100644 --- a/test/CodeGen/X86/sse41-blend.ll +++ b/test/CodeGen/X86/sse41-blend.ll @@ -44,4 +44,22 @@ define <16 x i8> @vsel_i8(<16 x i8> %v1, <16 x i8> %v2) { ret <16 x i8> %vsel } +;; TEST blend + compares +; CHECK: A +define <2 x double> @A(<2 x double> %x, <2 x double> %y) { + ; CHECK: cmpltpd + ; CHECK: blendvpd + %max_is_x = fcmp oge <2 x double> %x, %y + %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y + ret <2 x double> %max +} + +; CHECK: B +define <2 x double> @B(<2 x double> %x, <2 x double> %y) { + ; CHECK: cmplepd + ; CHECK: blendvpd + %max_is_x = fcmp ogt <2 x double> %x, %y + %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y + ret <2 x double> %max +}