Index: llvm/test/tools/llvm-reduce/remove-operands-fp.ll =================================================================== --- llvm/test/tools/llvm-reduce/remove-operands-fp.ll +++ llvm/test/tools/llvm-reduce/remove-operands-fp.ll @@ -6,7 +6,10 @@ ; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=operands-zero --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: FileCheck --check-prefixes=CHECK,ZERO %s < %t -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=operands-nan --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck --check-prefixes=CHECK,NAN %s < %t + +; RUN: llvm-reduce --abort-on-invalid-reduction --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: FileCheck --check-prefixes=CHECK,ZERO %s < %t ; CHECK-INTERESTINGNESS: = fadd float % @@ -53,6 +56,20 @@ ; ZERO: %fadd10 = fadd <2 x float> zeroinitializer, zeroinitializer ; ZERO: %fadd11 = fadd <2 x float> zeroinitializer, zeroinitializer + +; NAN: %fadd0 = fadd float %arg0, 0x7FF8000000000000 +; NAN: %fadd1 = fadd float 0x7FF8000000000000, 0x7FF8000000000000 +; NAN: %fadd2 = fadd float 0x7FF8000000000000, 0.000000e+00 +; NAN: %fadd3 = fadd float 0x7FF8000000000000, 1.000000e+00 +; NAN: %fadd4 = fadd float 0x7FF8000000000000, 0x7FF8000000000000 +; NAN: %fadd5 = fadd float 0x7FF8000000000000, 0x7FF8000000000000 +; NAN: %fadd6 = fadd <2 x float> %arg2, +; NAN: %fadd7 = fadd <2 x float> , +; NAN: %fadd8 = fadd <2 x float> , zeroinitializer +; NAN: %fadd9 = fadd <2 x float> , +; NAN: %fadd10 = fadd <2 x float> , +; NAN: %fadd11 = fadd <2 x float> , + define void @foo(float %arg0, float %arg1, <2 x float> %arg2, <2 x float> %arg3) { bb0: %fadd0 = fadd float %arg0, %arg1 Index: llvm/tools/llvm-reduce/DeltaManager.cpp =================================================================== --- llvm/tools/llvm-reduce/DeltaManager.cpp +++ llvm/tools/llvm-reduce/DeltaManager.cpp @@ -66,6 +66,7 @@ DELTA_PASS("simplify-instructions", simplifyInstructionsDeltaPass) \ DELTA_PASS("operands-zero", reduceOperandsZeroDeltaPass) \ DELTA_PASS("operands-one", reduceOperandsOneDeltaPass) \ + DELTA_PASS("operands-nan", reduceOperandsNaNDeltaPass) \ DELTA_PASS("operands-to-args", reduceOperandsToArgsDeltaPass) \ DELTA_PASS("operands-skip", reduceOperandsSkipDeltaPass) \ DELTA_PASS("operand-bundles", reduceOperandBundesDeltaPass) \ Index: llvm/tools/llvm-reduce/deltas/ReduceOperands.h =================================================================== --- llvm/tools/llvm-reduce/deltas/ReduceOperands.h +++ llvm/tools/llvm-reduce/deltas/ReduceOperands.h @@ -14,6 +14,7 @@ namespace llvm { void reduceOperandsOneDeltaPass(TestRunner &Test); void reduceOperandsZeroDeltaPass(TestRunner &Test); +void reduceOperandsNaNDeltaPass(TestRunner &Test); } // namespace llvm #endif Index: llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp =================================================================== --- llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp +++ llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp @@ -105,3 +105,29 @@ extractOperandsFromModule(O, Program, ReduceValue); }); } + +void llvm::reduceOperandsNaNDeltaPass(TestRunner &Test) { + errs() << "*** Reducing Operands to NaN...\n"; + auto ReduceValue = [](Use &Op) -> Value * { + Type *Ty = Op->getType(); + if (!Ty->isFPOrFPVectorTy()) + return nullptr; + + // Prefer 0.0 or 1.0 over NaN. + // + // TODO: Preferring NaN may make more sense because FP operations are more + // universally foldable. + if (match(Op.get(), m_NaN()) || isZeroOrOneFP(Op.get())) + return nullptr; + + if (VectorType *VT = dyn_cast(Ty)) { + return ConstantVector::getSplat(VT->getElementCount(), + ConstantFP::getQNaN(VT->getElementType())); + } + + return ConstantFP::getQNaN(Ty); + }; + runDeltaPass(Test, [ReduceValue](Oracle &O, Module &Program) { + extractOperandsFromModule(O, Program, ReduceValue); + }); +}