]> granicus.if.org Git - clang/commitdiff
CGBuiltin: Use frem instruction rather than libcall to implement fmod
authorJan Vesely <jan.vesely@rutgers.edu>
Fri, 26 Sep 2014 01:19:41 +0000 (01:19 +0000)
committerJan Vesely <jan.vesely@rutgers.edu>
Fri, 26 Sep 2014 01:19:41 +0000 (01:19 +0000)
AFAICT the semantics of frem match libm's fmod.

Signed-off-by: Jan Vesely <jan.vesely@rutgers.edu>
Reviewed-by: Tom Stellard <tom@stellard.net>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218488 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBuiltin.cpp
test/CodeGen/builtins.c

index 69ad762d18e4d538f90eb48cbe14c6f60d622df7..9238aae88cd693c23ce084c30f02a25ad1bfd334 100644 (file)
@@ -241,6 +241,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
 
     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:
index 451ed07c738895d333d169deccf06bebe9a98382..6dd749a90bdfa5badf252ee5c3957b949e28794c 100644 (file)
@@ -197,6 +197,22 @@ void test_float_builtins(float F, double D, long double LD) {
   // CHECK: and i1
 }
 
+// CHECK-LABEL: define void @test_float_builtin_ops
+void test_float_builtin_ops(float F, double D, long double LD) {
+  volatile float resf;
+  volatile double resd;
+  volatile long double resld;
+
+  resf = __builtin_fmodf(F,F);
+  // CHECK: frem float
+
+  resd = __builtin_fmod(D,D);
+  // CHECK: frem double
+
+  resld = __builtin_fmodl(LD,LD);
+  // CHECK: frem x86_fp80
+}
+
 // CHECK-LABEL: define void @test_builtin_longjmp
 void test_builtin_longjmp(void **buffer) {
   // CHECK: [[BITCAST:%.*]] = bitcast