[llvm] r327626 - [InstSimplify] remove 'nsz' requirement for frem 0, X

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 15 07:04:31 PDT 2018


Author: spatel
Date: Thu Mar 15 07:04:31 2018
New Revision: 327626

URL: http://llvm.org/viewvc/llvm-project?rev=327626&view=rev
Log:
[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."

Modified:
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/test/Transforms/InstSimplify/fast-math.ll

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=327626&r1=327625&r2=327626&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Thu Mar 15 07:04:31 2018
@@ -4315,11 +4315,17 @@ static Value *SimplifyFRemInst(Value *Op
   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;
 }

Modified: llvm/trunk/test/Transforms/InstSimplify/fast-math.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/fast-math.ll?rev=327626&r1=327625&r2=327626&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/fast-math.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/fast-math.ll Thu Mar 15 07:04:31 2018
@@ -241,8 +241,7 @@ define <2 x double> @fdiv_zero_by_x_vec_
 
 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
 
 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




More information about the llvm-commits mailing list