From 261075590b2bde348922b402bf982c33fb6475a8 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 9 Jun 2022 11:07:31 -0400 Subject: [PATCH] llvm-reduce: Handle reducing FP values to nan Prefer 0/1 over NaN, but it may make more sense to invert this as FP operations with nan inputs can universally be folded into something else. --- llvm/test/tools/llvm-reduce/remove-operands-fp.ll | 19 ++++++++++++++++- llvm/tools/llvm-reduce/DeltaManager.cpp | 1 + llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp | 26 +++++++++++++++++++++++ llvm/tools/llvm-reduce/deltas/ReduceOperands.h | 1 + 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/llvm/test/tools/llvm-reduce/remove-operands-fp.ll b/llvm/test/tools/llvm-reduce/remove-operands-fp.ll index 3e42ba5..e3ea033 100644 --- a/llvm/test/tools/llvm-reduce/remove-operands-fp.ll +++ b/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 diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp index 7a86997..49dd8f1 100644 --- a/llvm/tools/llvm-reduce/DeltaManager.cpp +++ b/llvm/tools/llvm-reduce/DeltaManager.cpp @@ -66,6 +66,7 @@ static cl::opt 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) \ diff --git a/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp b/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp index 9c713f5..d008a39 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp @@ -105,3 +105,29 @@ void llvm::reduceOperandsZeroDeltaPass(TestRunner &Test) { 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); + }); +} diff --git a/llvm/tools/llvm-reduce/deltas/ReduceOperands.h b/llvm/tools/llvm-reduce/deltas/ReduceOperands.h index 9fc3728c..034f49b 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceOperands.h +++ b/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 -- 2.7.4