Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -19415,6 +19415,22 @@ switch (N->getOpcode()) { default: llvm_unreachable("Do not know how to custom type legalize this operation!"); + // We might have generated v2f32 FMIN/FMAX operations. Widen them to v4f32. + case X86ISD::FMINC: + case X86ISD::FMIN: + case X86ISD::FMAXC: + case X86ISD::FMAX: { + EVT VT = N->getValueType(0); + if (VT != MVT::v2f32) + llvm_unreachable("Unexpected type (!= v2f32) on FMIN/FMAX."); + SDValue UNDEF = DAG.getUNDEF(VT); + SDValue LHS = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f32, + N->getOperand(0), UNDEF); + SDValue RHS = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f32, + N->getOperand(1), UNDEF); + Results.push_back(DAG.getNode(N->getOpcode(), dl, MVT::v4f32, LHS, RHS)); + return; + } case ISD::SIGN_EXTEND_INREG: case ISD::ADDC: case ISD::ADDE: @@ -22800,8 +22816,9 @@ // instructions match the semantics of the common C idiom xhasSSE2() || (Subtarget->hasSSE1() && VT.getScalarType() == MVT::f32))) { ISD::CondCode CC = cast(Cond.getOperand(2))->get(); Index: test/CodeGen/X86/sse-minmax.ll =================================================================== --- test/CodeGen/X86/sse-minmax.ll +++ test/CodeGen/X86/sse-minmax.ll @@ -937,3 +937,35 @@ %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y ret <4 x float> %min } + +; UNSAFE-LABEL: test_maxps_illegal_v2f32: +; UNSAFE: maxps +define <2 x float> @test_maxps_illegal_v2f32(<2 x float> %x, <2 x float> %y) { + %max_is_x = fcmp oge <2 x float> %x, %y + %max = select <2 x i1> %max_is_x, <2 x float> %x, <2 x float> %y + ret <2 x float> %max +} + +; UNSAFE-LABEL: test_minps_illegal_v2f32: +; UNSAFE: minps +define <2 x float> @test_minps_illegal_v2f32(<2 x float> %x, <2 x float> %y) { + %min_is_x = fcmp ole <2 x float> %x, %y + %min = select <2 x i1> %min_is_x, <2 x float> %x, <2 x float> %y + ret <2 x float> %min +} + +; UNSAFE-LABEL: test_maxps_illegal_v3f32: +; UNSAFE: maxps +define <3 x float> @test_maxps_illegal_v3f32(<3 x float> %x, <3 x float> %y) { + %max_is_x = fcmp oge <3 x float> %x, %y + %max = select <3 x i1> %max_is_x, <3 x float> %x, <3 x float> %y + ret <3 x float> %max +} + +; UNSAFE-LABEL: test_minps_illegal_v3f32: +; UNSAFE: minps +define <3 x float> @test_minps_illegal_v3f32(<3 x float> %x, <3 x float> %y) { + %min_is_x = fcmp ole <3 x float> %x, %y + %min = select <3 x i1> %min_is_x, <3 x float> %x, <3 x float> %y + ret <3 x float> %min +}