r319619 - [CodeGen] fix mapping from fmod calls to frem instruction

Sanjay Patel via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 2 09:52:00 PST 2017


Author: spatel
Date: Sat Dec  2 09:52:00 2017
New Revision: 319619

URL: http://llvm.org/viewvc/llvm-project?rev=319619&view=rev
Log:
[CodeGen] fix mapping from fmod calls to frem instruction

Similar to D40044 and discussed in D40594.

Modified:
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/test/CodeGen/math-builtins.c
    cfe/trunk/test/CodeGen/math-libcalls.c

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=319619&r1=319618&r2=319619&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Sat Dec  2 09:52:00 2017
@@ -854,12 +854,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(
                                                Result.Val.getFloat()));
   }
 
-  // Math builtins have the same semantics as their math library twins.
-  // There are LLVM math intrinsics corresponding to math library functions
-  // except the intrinsic will never set errno while the math library might.
-  // Thus, we can transform math library and builtin calls to their
-  // semantically-equivalent LLVM intrinsic counterparts if the call is marked
-  // 'const' (it is known to never set errno).
+  // There are LLVM math intrinsics/instructions corresponding to math library
+  // functions except the LLVM op will never set errno while the math library
+  // might. Also, math builtins have the same semantics as their math library
+  // twins. Thus, we can transform math library and builtin calls to their
+  // LLVM counterparts if the call is marked 'const' (known to never set errno).
   if (FD->hasAttr<ConstAttr>()) {
     switch (BuiltinID) {
     case Builtin::BIceil:
@@ -942,6 +941,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(
     case Builtin::BI__builtin_fminl:
       return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum));
 
+    // fmod() is a special-case. It maps to the frem instruction rather than an
+    // LLVM intrinsic.
+    case Builtin::BIfmod:
+    case Builtin::BIfmodf:
+    case Builtin::BIfmodl:
+    case Builtin::BI__builtin_fmod:
+    case Builtin::BI__builtin_fmodf:
+    case Builtin::BI__builtin_fmodl: {
+      Value *Arg1 = EmitScalarExpr(E->getArg(0));
+      Value *Arg2 = EmitScalarExpr(E->getArg(1));
+      return RValue::get(Builder.CreateFRem(Arg1, Arg2, "fmod"));
+    }
+
     case Builtin::BIlog:
     case Builtin::BIlogf:
     case Builtin::BIlogl:
@@ -1067,14 +1079,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(
 
     return RValue::get(Result);
   }
-  case Builtin::BI__builtin_fmod:
-  case Builtin::BI__builtin_fmodf:
-  case Builtin::BI__builtin_fmodl: {
-    Value *Arg1 = EmitScalarExpr(E->getArg(0));
-    Value *Arg2 = EmitScalarExpr(E->getArg(1));
-    Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod");
-    return RValue::get(Result);
-  }
   case Builtin::BI__builtin_conj:
   case Builtin::BI__builtin_conjf:
   case Builtin::BI__builtin_conjl: {

Modified: cfe/trunk/test/CodeGen/math-builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/math-builtins.c?rev=319619&r1=319618&r2=319619&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/math-builtins.c (original)
+++ cfe/trunk/test/CodeGen/math-builtins.c Sat Dec  2 09:52:00 2017
@@ -6,12 +6,21 @@
 // Test attributes and codegen of math builtins.
 
 void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
+  f = __builtin_fmod(f,f);    f = __builtin_fmodf(f,f);   f =  __builtin_fmodl(f,f);
+
+// NO__ERRNO: frem double
+// NO__ERRNO: frem float
+// NO__ERRNO: frem x86_fp80
+// HAS_ERRNO: declare double @fmod(double, double) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
   __builtin_atan2(f,f);    __builtin_atan2f(f,f) ;  __builtin_atan2l(f, f);
 
 // NO__ERRNO: declare double @atan2(double, double) [[READNONE:#[0-9]+]]
 // NO__ERRNO: declare float @atan2f(float, float) [[READNONE]]
 // NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[READNONE]]
-// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @atan2f(float, float) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOT_READNONE]]
 
@@ -33,13 +42,6 @@ void foo(double *d, float f, float *fp,
 // HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]]
 // HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]]
 
-  __builtin_fmod(f,f);     __builtin_fmodf(f,f);    __builtin_fmodl(f,f);
-
-// NO__ERRNO-NOT: .fmod
-// NO__ERRNO-NOT: @fmod
-// HAS_ERRNO-NOT: .fmod
-// HAS_ERRNO-NOT: @fmod
-
   __builtin_frexp(f,i);    __builtin_frexpf(f,i);   __builtin_frexpl(f,i);
 
 // NO__ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE:#[0-9]+]]

Modified: cfe/trunk/test/CodeGen/math-libcalls.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/math-libcalls.c?rev=319619&r1=319618&r2=319619&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/math-libcalls.c (original)
+++ cfe/trunk/test/CodeGen/math-libcalls.c Sat Dec  2 09:52:00 2017
@@ -6,12 +6,21 @@
 // Test attributes and builtin codegen of math library calls.
 
 void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
+  f = fmod(f,f);     f = fmodf(f,f);    f = fmodl(f,f);
+
+// NO__ERRNO: frem double
+// NO__ERRNO: frem float
+// NO__ERRNO: frem x86_fp80
+// HAS_ERRNO: declare double @fmod(double, double) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
   atan2(f,f);    atan2f(f,f) ;  atan2l(f, f);
 
 // NO__ERRNO: declare double @atan2(double, double) [[READNONE:#[0-9]+]]
 // NO__ERRNO: declare float @atan2f(float, float) [[READNONE]]
 // NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[READNONE]]
-// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @atan2f(float, float) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOT_READNONE]]
 
@@ -33,15 +42,6 @@ void foo(double *d, float f, float *fp,
 // HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]]
 // HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]]
 
-  fmod(f,f);     fmodf(f,f);    fmodl(f,f);
-
-// NO__ERRNO: declare double @fmod(double, double) [[READNONE]]
-// NO__ERRNO: declare float @fmodf(float, float) [[READNONE]]
-// NO__ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[READNONE]]
-// HAS_ERRNO: declare double @fmod(double, double) [[NOT_READNONE]]
-// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]]
-// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]]
-
   frexp(f,i);    frexpf(f,i);   frexpl(f,i);
 
 // NO__ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE:#[0-9]+]]




More information about the cfe-commits mailing list