From 8f063d0c70dbd3aea79ae16a2d961bb133d2a17d Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 15 Mar 2018 14:04:31 +0000 Subject: [PATCH] [InstSimplify] remove 'nsz' requirement for frem 0, X MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit From the LangRef definition for frem: "The value produced is the floating-point remainder of the two operands. This is the same output as a libm ‘fmod‘ function, but without any possibility of setting errno. The remainder has the same sign as the dividend. This instruction is assumed to execute in the default floating-point environment." llvm-svn: 327626 --- llvm/lib/Analysis/InstructionSimplify.cpp | 16 +++++++++++----- llvm/test/Transforms/InstSimplify/fast-math.ll | 9 +++------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 2b8e23b..773c3ec 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4315,11 +4315,17 @@ static Value *SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF, if (isa(Op0) || isa(Op1)) return ConstantFP::getNaN(Op0->getType()); - // 0 % X -> 0 - // Requires that NaNs are off (X could be zero) and signed zeroes are - // ignored (X could be positive or negative, so the output sign is unknown). - if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op0, m_AnyZero())) - return Op0; + // Unlike fdiv, the result of frem always matches the sign of the dividend. + // The constant match may include undef elements in a vector, so return a full + // zero constant as the result. + if (FMF.noNaNs()) { + // 0 % X -> 0 + if (match(Op0, m_Zero())) + return ConstantFP::getNullValue(Op0->getType()); + // -0 % X -> -0 + if (match(Op0, m_NegZero())) + return ConstantFP::getNegativeZero(Op0->getType()); + } return nullptr; } diff --git a/llvm/test/Transforms/InstSimplify/fast-math.ll b/llvm/test/Transforms/InstSimplify/fast-math.ll index 8b7472f..bed39fb 100644 --- a/llvm/test/Transforms/InstSimplify/fast-math.ll +++ b/llvm/test/Transforms/InstSimplify/fast-math.ll @@ -241,8 +241,7 @@ define <2 x double> @fdiv_zero_by_x_vec_undef(<2 x double> %x) { define double @frem_zero_by_x(double %x) { ; CHECK-LABEL: @frem_zero_by_x( -; CHECK-NEXT: [[R:%.*]] = frem nnan double 0.000000e+00, [[X:%.*]] -; CHECK-NEXT: ret double [[R]] +; CHECK-NEXT: ret double 0.000000e+00 ; %r = frem nnan double 0.0, %x ret double %r @@ -253,8 +252,7 @@ define double @frem_zero_by_x(double %x) { define double @frem_negzero_by_x(double %x) { ; CHECK-LABEL: @frem_negzero_by_x( -; CHECK-NEXT: [[R:%.*]] = frem nnan double -0.000000e+00, [[X:%.*]] -; CHECK-NEXT: ret double [[R]] +; CHECK-NEXT: ret double -0.000000e+00 ; %r = frem nnan double -0.0, %x ret double %r @@ -262,8 +260,7 @@ define double @frem_negzero_by_x(double %x) { define <2 x double> @frem_negzero_by_x_vec_undef(<2 x double> %x) { ; CHECK-LABEL: @frem_negzero_by_x_vec_undef( -; CHECK-NEXT: [[R:%.*]] = frem nnan <2 x double> , [[X:%.*]] -; CHECK-NEXT: ret <2 x double> [[R]] +; CHECK-NEXT: ret <2 x double> ; %r = frem nnan <2 x double> , %x ret <2 x double> %r -- 2.7.4