Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2090,8 +2090,13 @@ if (!TLI->isCondCodeLegal(SwappedCond, OpVT.getSimpleVT())) return SDValue(); return getSetCC(dl, VT, N2, N1, SwappedCond); - } else if (N2CFP && N2CFP->getValueAPF().isNaN()) { - // If an operand is known to be a nan, we can fold it. + } else if ((N2CFP && N2CFP->getValueAPF().isNaN()) || + (OpVT.isFloatingPoint() && (N1.isUndef() || N2.isUndef()))) { + // If an operand is known to be a nan (or undef that could be a nan), we can + // fold it. + // Choosing NaN for the undef will always make unordered comparison succeed + // and ordered comparison fails. + // Matches behavior in llvm::ConstantFoldCompareInstruction. switch (ISD::getUnorderedFlavor(Cond)) { default: llvm_unreachable("Unknown flavor!"); Index: test/CodeGen/AArch64/half.ll =================================================================== --- test/CodeGen/AArch64/half.ll +++ test/CodeGen/AArch64/half.ll @@ -96,24 +96,27 @@ ret void } -define i16 @test_fccmp(i1 %a) { +define i16 @test_fccmp(i1 %a, i16 %in) { ; CHECK-LABEL: test_fccmp: ; CHECK: // %bb.0: ; CHECK-NEXT: mov w8, #24576 +; CHECK-NEXT: fmov s0, w1 ; CHECK-NEXT: movk w8, #15974, lsl #16 ; CHECK-NEXT: mov w9, #16384 +; CHECK-NEXT: fcvt s0, h0 ; CHECK-NEXT: movk w9, #15428, lsl #16 -; CHECK-NEXT: fmov s0, w8 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: fmov s0, w9 +; CHECK-NEXT: fmov s1, w8 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: fmov s1, w9 ; CHECK-NEXT: cset w8, pl -; CHECK-NEXT: fccmp s0, s0, #8, pl +; CHECK-NEXT: fccmp s0, s1, #8, pl ; CHECK-NEXT: mov w9, #4 ; CHECK-NEXT: csinc w9, w9, wzr, mi ; CHECK-NEXT: add w0, w8, w9 ; CHECK-NEXT: ret - %cmp0 = fcmp ogt half 0xH3333, undef - %cmp1 = fcmp ogt half 0xH2222, undef + %f16 = bitcast i16 %in to half + %cmp0 = fcmp ogt half 0xH3333, %f16 + %cmp1 = fcmp ogt half 0xH2222, %f16 %x = select i1 %cmp0, i16 0, i16 1 %or = or i1 %cmp1, %cmp0 %y = select i1 %or, i16 4, i16 1 Index: test/CodeGen/ARM/fcmp-xo.ll =================================================================== --- test/CodeGen/ARM/fcmp-xo.ll +++ test/CodeGen/ARM/fcmp-xo.ll @@ -2,34 +2,35 @@ ; RUN: llc < %s -mtriple=thumbv7m-arm-none-eabi -mattr=+execute-only,+fp-armv8 | FileCheck %s --check-prefixes=CHECK,VMOVSR ; RUN: llc < %s -mtriple=thumbv7m-arm-none-eabi -mattr=+execute-only,+fp-armv8,+neon,+neonfp | FileCheck %s --check-prefixes=CHECK,NEON -define arm_aapcs_vfpcc float @foo0() local_unnamed_addr { +define arm_aapcs_vfpcc float @foo0(float %a0) local_unnamed_addr { ; CHECK-LABEL: foo0: ; CHECK: @ %bb.0: -; CHECK-NEXT: vmov.f32 s0, #5.000000e-01 -; CHECK-NEXT: vmov.f32 s2, #-5.000000e-01 ; CHECK-NEXT: vcmpe.f32 s0, #0 +; CHECK-NEXT: vmov.f32 s2, #5.000000e-01 ; CHECK-NEXT: vmrs APSR_nzcv, fpscr +; CHECK-NEXT: vmov.f32 s4, #-5.000000e-01 ; CHECK-NEXT: it mi -; CHECK-NEXT: vmovmi.f32 s0, s2 +; CHECK-NEXT: vmovmi.f32 s2, s4 +; CHECK-NEXT: vmov.f32 s0, s2 ; CHECK-NEXT: bx lr - %1 = fcmp nsz olt float undef, 0.000000e+00 + %1 = fcmp nsz olt float %a0, 0.000000e+00 %2 = select i1 %1, float -5.000000e-01, float 5.000000e-01 ret float %2 } -define arm_aapcs_vfpcc float @float1() local_unnamed_addr { +define arm_aapcs_vfpcc float @float1(float %a0) local_unnamed_addr { ; CHECK-LABEL: float1: ; CHECK: @ %bb.0: @ %.end -; CHECK-NEXT: vmov.f32 s0, #1.000000e+00 -; CHECK-NEXT: vmov.f32 s2, #5.000000e-01 -; CHECK-NEXT: vmov.f32 s4, #-5.000000e-01 -; CHECK-NEXT: vcmpe.f32 s0, s0 +; CHECK-NEXT: vmov.f32 s2, #1.000000e+00 +; CHECK-NEXT: vmov.f32 s4, #5.000000e-01 +; CHECK-NEXT: vmov.f32 s6, #-5.000000e-01 +; CHECK-NEXT: vcmpe.f32 s2, s0 ; CHECK-NEXT: vmrs APSR_nzcv, fpscr -; CHECK-NEXT: vselgt.f32 s0, s4, s2 +; CHECK-NEXT: vselgt.f32 s0, s6, s4 ; CHECK-NEXT: bx lr br i1 undef, label %.end, label %1 - %2 = fcmp nsz olt float undef, 1.000000e+00 + %2 = fcmp nsz olt float %a0, 1.000000e+00 %3 = select i1 %2, float -5.000000e-01, float 5.000000e-01 br label %.end @@ -38,62 +39,62 @@ ret float %4 } -define arm_aapcs_vfpcc float @float128() local_unnamed_addr { +define arm_aapcs_vfpcc float @float128(float %a0) local_unnamed_addr { ; VMOVSR-LABEL: float128: ; VMOVSR: @ %bb.0: ; VMOVSR-NEXT: mov.w r0, #1124073472 -; VMOVSR-NEXT: vmov.f32 s2, #5.000000e-01 -; VMOVSR-NEXT: vmov s0, r0 -; VMOVSR-NEXT: vmov.f32 s4, #-5.000000e-01 -; VMOVSR-NEXT: vcmpe.f32 s0, s0 +; VMOVSR-NEXT: vmov.f32 s4, #5.000000e-01 +; VMOVSR-NEXT: vmov s2, r0 +; VMOVSR-NEXT: vmov.f32 s6, #-5.000000e-01 +; VMOVSR-NEXT: vcmpe.f32 s2, s0 ; VMOVSR-NEXT: vmrs APSR_nzcv, fpscr -; VMOVSR-NEXT: vselgt.f32 s0, s4, s2 +; VMOVSR-NEXT: vselgt.f32 s0, s6, s4 ; VMOVSR-NEXT: bx lr ; ; NEON-LABEL: float128: ; NEON: @ %bb.0: -; NEON-NEXT: vmov.f32 s0, #5.000000e-01 ; NEON-NEXT: mov.w r0, #1124073472 -; NEON-NEXT: vmov d2, r0, r0 -; NEON-NEXT: vmov.f32 s2, #-5.000000e-01 -; NEON-NEXT: vcmpe.f32 s4, s0 +; NEON-NEXT: vmov.f32 s2, #5.000000e-01 +; NEON-NEXT: vmov d3, r0, r0 +; NEON-NEXT: vmov.f32 s4, #-5.000000e-01 +; NEON-NEXT: vcmpe.f32 s6, s0 ; NEON-NEXT: vmrs APSR_nzcv, fpscr -; NEON-NEXT: vselgt.f32 s0, s2, s0 +; NEON-NEXT: vselgt.f32 s0, s4, s2 ; NEON-NEXT: bx lr - %1 = fcmp nsz olt float undef, 128.000000e+00 + %1 = fcmp nsz olt float %a0, 128.000000e+00 %2 = select i1 %1, float -5.000000e-01, float 5.000000e-01 ret float %2 } -define arm_aapcs_vfpcc double @double1() local_unnamed_addr { +define arm_aapcs_vfpcc double @double1(double %a0) local_unnamed_addr { ; CHECK-LABEL: double1: ; CHECK: @ %bb.0: -; CHECK-NEXT: vmov.f64 d16, #5.000000e-01 ; CHECK-NEXT: vmov.f64 d18, #1.000000e+00 -; CHECK-NEXT: vcmpe.f64 d18, d16 +; CHECK-NEXT: vcmpe.f64 d18, d0 ; CHECK-NEXT: vmrs APSR_nzcv, fpscr +; CHECK-NEXT: vmov.f64 d16, #5.000000e-01 ; CHECK-NEXT: vmov.f64 d17, #-5.000000e-01 ; CHECK-NEXT: vselgt.f64 d0, d17, d16 ; CHECK-NEXT: bx lr - %1 = fcmp nsz olt double undef, 1.000000e+00 + %1 = fcmp nsz olt double %a0, 1.000000e+00 %2 = select i1 %1, double -5.000000e-01, double 5.000000e-01 ret double %2 } -define arm_aapcs_vfpcc double @double128() local_unnamed_addr { +define arm_aapcs_vfpcc double @double128(double %a0) local_unnamed_addr { ; CHECK-LABEL: double128: ; CHECK: @ %bb.0: -; CHECK-NEXT: vmov.f64 d16, #5.000000e-01 ; CHECK-NEXT: movs r0, #0 -; CHECK-NEXT: movt r0, #16480 ; CHECK-NEXT: movs r1, #0 +; CHECK-NEXT: movt r0, #16480 +; CHECK-NEXT: vmov.f64 d16, #5.000000e-01 ; CHECK-NEXT: vmov d18, r1, r0 -; CHECK-NEXT: vcmpe.f64 d18, d16 +; CHECK-NEXT: vcmpe.f64 d18, d0 ; CHECK-NEXT: vmrs APSR_nzcv, fpscr ; CHECK-NEXT: vmov.f64 d17, #-5.000000e-01 ; CHECK-NEXT: vselgt.f64 d0, d17, d16 ; CHECK-NEXT: bx lr - %1 = fcmp nsz olt double undef, 128.000000e+00 + %1 = fcmp nsz olt double %a0, 128.000000e+00 %2 = select i1 %1, double -5.000000e-01, double 5.000000e-01 ret double %2 } Index: test/CodeGen/ARM/fp16-instructions.ll =================================================================== --- test/CodeGen/ARM/fp16-instructions.ll +++ test/CodeGen/ARM/fp16-instructions.ll @@ -701,8 +701,8 @@ ; 34. VRINTZ ; 35. VSELEQ -define half @select_cc1() { - %1 = fcmp nsz oeq half undef, 0xH0001 +define half @select_cc1(half %a0) { + %1 = fcmp nsz oeq half %a0, 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 @@ -727,8 +727,8 @@ ; be encoded as an FP16 immediate need to be added here. ; ; 36. VSELGE -define half @select_cc_ge1() { - %1 = fcmp nsz oge half undef, 0xH0001 +define half @select_cc_ge1(half %a0) { + %1 = fcmp nsz oge half %a0, 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 @@ -748,8 +748,8 @@ ; CHECK-SOFTFP-FP16-T32-NEXT: vmovge.f32 s{{.}}, s{{.}} } -define half @select_cc_ge2() { - %1 = fcmp nsz ole half undef, 0xH0001 +define half @select_cc_ge2(half %a0) { + %1 = fcmp nsz ole half %a0, 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 @@ -769,8 +769,8 @@ ; CHECK-SOFTFP-FP16-T32-NEXT: vmovls.f32 s{{.}}, s{{.}} } -define half @select_cc_ge3() { - %1 = fcmp nsz ugt half undef, 0xH0001 +define half @select_cc_ge3(half %a0) { + %1 = fcmp nsz ugt half %a0, 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 @@ -790,8 +790,8 @@ ; CHECK-SOFTFP-FP16-T32-NEXT: vmovhi.f32 s{{.}}, s{{.}} } -define half @select_cc_ge4() { - %1 = fcmp nsz ult half undef, 0xH0001 +define half @select_cc_ge4(half %a0) { + %1 = fcmp nsz ult half %a0, 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 @@ -812,8 +812,8 @@ } ; 37. VSELGT -define half @select_cc_gt1() { - %1 = fcmp nsz ogt half undef, 0xH0001 +define half @select_cc_gt1(half %a0) { + %1 = fcmp nsz ogt half %a0, 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 @@ -833,8 +833,8 @@ ; CHECK-SOFTFP-FP16-T32-NEXT: vmovgt.f32 s{{.}}, s{{.}} } -define half @select_cc_gt2() { - %1 = fcmp nsz uge half undef, 0xH0001 +define half @select_cc_gt2(half %a0) { + %1 = fcmp nsz uge half %a0 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 @@ -854,8 +854,8 @@ ; CHECK-SOFTFP-FP16-T32-NEXT: vmovpl.f32 s{{.}}, s{{.}} } -define half @select_cc_gt3() { - %1 = fcmp nsz ule half undef, 0xH0001 +define half @select_cc_gt3(half %a0) { + %1 = fcmp nsz ule half %a0, 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 @@ -875,8 +875,8 @@ ; CHECK-SOFTFP-FP16-T32-NEXT: vmovle.f32 s{{.}}, s{{.}} } -define half @select_cc_gt4() { - %1 = fcmp nsz olt half undef, 0xH0001 +define half @select_cc_gt4(half %a0) { + %1 = fcmp nsz olt half %a0, 0xH0001 %2 = select i1 %1, half 0xHC000, half 0xH0002 ret half %2 Index: test/CodeGen/ARM/vcge.ll =================================================================== --- test/CodeGen/ARM/vcge.ll +++ test/CodeGen/ARM/vcge.ll @@ -279,9 +279,10 @@ ; Radar 8782191 ; Floating-point comparisons against zero produce results with integer ; elements, not floating-point elements. -define void @test_vclez_fp() nounwind optsize { +define void @test_vclez_fp(<4 x float>* %A) nounwind optsize { ; CHECK-LABEL: test_vclez_fp: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vld1.64 {d16, d17}, [r0] ; CHECK-NEXT: vcle.f32 q8, q8, #0 ; CHECK-NEXT: vmovn.i32 d16, q8 ; CHECK-NEXT: vmov.i8 d17, #0x1 @@ -289,7 +290,8 @@ ; CHECK-NEXT: vadd.i8 d16, d16, d17 ; CHECK-NEXT: vst1.8 {d16}, [r0] entry: - %0 = fcmp ole <4 x float> undef, zeroinitializer + %ld = load <4 x float>, <4 x float>* %A + %0 = fcmp ole <4 x float> %ld, zeroinitializer %1 = sext <4 x i1> %0 to <4 x i16> %2 = add <4 x i16> %1, zeroinitializer %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> Index: test/CodeGen/Hexagon/autohvx/build-vector-i32-type.ll =================================================================== --- test/CodeGen/Hexagon/autohvx/build-vector-i32-type.ll +++ test/CodeGen/Hexagon/autohvx/build-vector-i32-type.ll @@ -9,10 +9,10 @@ @g0 = global <16 x float> zeroinitializer, align 8 @g1 = global <16 x i32> zeroinitializer, align 8 -define void @fred(<16 x i16> %x) #0 { +define void @fred(<16 x i16> %x, <16 x float> %y) #0 { b0: %v1 = load <16 x float>, <16 x float>* @g0, align 8 - %v2 = fcmp olt <16 x float> undef, %v1 + %v2 = fcmp olt <16 x float> %y, %v1 %v3 = select <16 x i1> %v2, <16 x i16> %x, <16 x i16> zeroinitializer %v4 = sext <16 x i16> %v3 to <16 x i32> store <16 x i32> %v4, <16 x i32>* @g1, align 64 Index: test/CodeGen/Mips/2013-11-18-fp64-const0.ll =================================================================== --- test/CodeGen/Mips/2013-11-18-fp64-const0.ll +++ test/CodeGen/Mips/2013-11-18-fp64-const0.ll @@ -10,7 +10,7 @@ ; of BuildPairF64 instead of BuildPairF64_64. ; FIXME: A redundant mthc1 is currently emitted. -define void @autogen_SD3718491962() { +define void @autogen_SD3718491962(double %a0) { ; CHECK-FP32-LABEL: autogen_SD3718491962: ; CHECK-FP32: # %bb.0: # %BB ; CHECK-FP32-NEXT: lui $1, %hi($CPI0_0) @@ -19,10 +19,10 @@ ; CHECK-FP32-NEXT: mtc1 $zero, $f3 ; CHECK-FP32-NEXT: $BB0_1: # %CF88 ; CHECK-FP32-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-FP32-NEXT: c.ueq.d $f0, $f0 +; CHECK-FP32-NEXT: c.ueq.d $f12, $f0 ; CHECK-FP32-NEXT: addiu $1, $zero, 1 ; CHECK-FP32-NEXT: movf $1, $zero, $fcc0 -; CHECK-FP32-NEXT: c.olt.d $f0, $f2 +; CHECK-FP32-NEXT: c.olt.d $f12, $f2 ; CHECK-FP32-NEXT: addiu $2, $zero, 1 ; CHECK-FP32-NEXT: movt $2, $zero, $fcc0 ; CHECK-FP32-NEXT: and $1, $2, $1 @@ -40,10 +40,10 @@ ; CHECK-FP64-NEXT: mthc1 $zero, $f1 ; CHECK-FP64-NEXT: $BB0_1: # %CF88 ; CHECK-FP64-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-FP64-NEXT: c.ueq.d $f0, $f0 +; CHECK-FP64-NEXT: c.ueq.d $f12, $f0 ; CHECK-FP64-NEXT: addiu $1, $zero, 1 ; CHECK-FP64-NEXT: movf $1, $zero, $fcc0 -; CHECK-FP64-NEXT: c.olt.d $f0, $f1 +; CHECK-FP64-NEXT: c.olt.d $f12, $f1 ; CHECK-FP64-NEXT: addiu $2, $zero, 1 ; CHECK-FP64-NEXT: movt $2, $zero, $fcc0 ; CHECK-FP64-NEXT: and $1, $2, $1 @@ -53,8 +53,8 @@ ; CHECK-FP64-NEXT: jr $ra ; CHECK-FP64-NEXT: nop BB: - %Cmp = fcmp ule double 0.000000e+00, undef - %Cmp11 = fcmp ueq double 0xFDBD965CF1BB7FDA, undef + %Cmp = fcmp ule double 0.000000e+00, %a0 + %Cmp11 = fcmp ueq double 0xFDBD965CF1BB7FDA, %a0 br label %CF88 CF88: ; preds = %CF86 Index: test/CodeGen/SPARC/fp128.ll =================================================================== --- test/CodeGen/SPARC/fp128.ll +++ test/CodeGen/SPARC/fp128.ll @@ -73,10 +73,11 @@ ; SOFT: _Q_cmp ; SOFT: cmp -define i32 @f128_compare2() { +define i32 @f128_compare2(fp128* byval %f0) { entry: - %0 = fcmp ogt fp128 undef, 0xL00000000000000000000000000000000 - br i1 %0, label %"5", label %"7" + %0 = load fp128, fp128* %f0, align 8 + %1 = fcmp ogt fp128 %0, 0xL00000000000000000000000000000000 + br i1 %1, label %"5", label %"7" "5": ; preds = %entry ret i32 0 Index: test/CodeGen/SystemZ/DAGCombiner_illegal_BUILD_VECTOR.ll =================================================================== --- test/CodeGen/SystemZ/DAGCombiner_illegal_BUILD_VECTOR.ll +++ test/CodeGen/SystemZ/DAGCombiner_illegal_BUILD_VECTOR.ll @@ -5,7 +5,7 @@ ; BUILD_VECTOR node. -define void @pr32422() { +define void @pr32422(double %a0) { ; CHECK-LABEL: pr32422: ; CHECK: # %bb.0: # %BB ; CHECK-NEXT: .LBB0_1: # %CF @@ -23,7 +23,7 @@ br label %CF CF: ; preds = %CF, %BB - %Cmp40 = fcmp uno double 0xC663C682E9619F00, undef + %Cmp40 = fcmp uno double 0xC663C682E9619F00, %a0 br i1 %Cmp40, label %CF, label %CF353 CF353: ; preds = %CF