Index: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp @@ -19658,6 +19658,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: @@ -23077,8 +23093,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: llvm/trunk/test/CodeGen/X86/sse-minmax.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/sse-minmax.ll +++ llvm/trunk/test/CodeGen/X86/sse-minmax.ll @@ -989,3 +989,39 @@ %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-NEXT: maxps %xmm1, %xmm0 +; UNSAFE-NEXT: ret +define <2 x float> @test_maxps_illegal_v2f32(<2 x float> %x, <2 x float> %y) nounwind { + %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-NEXT: minps %xmm1, %xmm0 +; UNSAFE-NEXT: ret +define <2 x float> @test_minps_illegal_v2f32(<2 x float> %x, <2 x float> %y) nounwind { + %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-NEXT: maxps %xmm1, %xmm0 +; UNSAFE-NEXT: ret +define <3 x float> @test_maxps_illegal_v3f32(<3 x float> %x, <3 x float> %y) nounwind { + %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-NEXT: minps %xmm1, %xmm0 +; UNSAFE-NEXT: ret +define <3 x float> @test_minps_illegal_v3f32(<3 x float> %x, <3 x float> %y) nounwind { + %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 +}