summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-03-15 14:04:31 +0000
committerSanjay Patel <spatel@rotateright.com>2018-03-15 14:04:31 +0000
commit8f063d0c70dbd3aea79ae16a2d961bb133d2a17d (patch)
tree0a86524d3ee562dec890f5e1bd4a87eea97bc955
parent107052ff9ded599519445833d755628703027801 (diff)
downloadbcm5719-llvm-8f063d0c70dbd3aea79ae16a2d961bb133d2a17d.tar.gz
bcm5719-llvm-8f063d0c70dbd3aea79ae16a2d961bb133d2a17d.zip
[InstSimplify] remove 'nsz' requirement for frem 0, X
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
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp16
-rw-r--r--llvm/test/Transforms/InstSimplify/fast-math.ll9
2 files changed, 14 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 2b8e23b9569..773c3ec0f6e 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<UndefValue>(Op0) || isa<UndefValue>(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 8b7472f2878..bed39fbc836 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> <double undef, double -0.000000e+00>, [[X:%.*]]
-; CHECK-NEXT: ret <2 x double> [[R]]
+; CHECK-NEXT: ret <2 x double> <double -0.000000e+00, double -0.000000e+00>
;
%r = frem nnan <2 x double> <double undef, double -0.0>, %x
ret <2 x double> %r
OpenPOWER on IntegriCloud