[cfe-commits] [PATCH] CodeGen: Expand creal and cimag into complex field loads

Meador Inge meadori at codesourcery.com
Thu Dec 13 19:36:53 PST 2012


PR 14529 was opened because neither Clang or LLVM was expanding
calls to creal* or cimag* into instructions that just load the
respective complex field.  After some discussion, it was not
considered realistic to do this in LLVM because of the platform
specific way complex types are expanded.  Thus a way to solve
this in Clang was pursued.  GCC does a similar expansion.

This patch adds the feature to Clang by making the creal* and
cimag* functions library builtins and modifying the builtin code
generator to look for the new builtin types.

OK?

---
 include/clang/Basic/Builtins.def |    8 +++++++
 lib/CodeGen/CGBuiltin.cpp        |   10 +++++++--
 test/CodeGen/libcalls-complex.c  |   46 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 test/CodeGen/libcalls-complex.c

diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index d48eadc..d485cbd 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -833,6 +833,14 @@ LIBBUILTIN(ceil, "dd", "fc", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(ceill, "LdLd", "fc", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(ceilf, "ff", "fc", "math.h", ALL_LANGUAGES)
 
+LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cimagl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
 LIBBUILTIN(copysign, "ddd", "fc", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(copysignl, "LdLdLd", "fc", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(copysignf, "fff", "fc", "math.h", ALL_LANGUAGES)
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index a1a6ef6..d2824e9 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -244,14 +244,20 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
   }
   case Builtin::BI__builtin_creal:
   case Builtin::BI__builtin_crealf:
-  case Builtin::BI__builtin_creall: {
+  case Builtin::BI__builtin_creall:
+  case Builtin::BIcreal:
+  case Builtin::BIcrealf:
+  case Builtin::BIcreall: {
     ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
     return RValue::get(ComplexVal.first);
   }
 
   case Builtin::BI__builtin_cimag:
   case Builtin::BI__builtin_cimagf:
-  case Builtin::BI__builtin_cimagl: {
+  case Builtin::BI__builtin_cimagl:
+  case Builtin::BIcimag:
+  case Builtin::BIcimagf:
+  case Builtin::BIcimagl: {
     ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
     return RValue::get(ComplexVal.second);
   }
diff --git a/test/CodeGen/libcalls-complex.c b/test/CodeGen/libcalls-complex.c
new file mode 100644
index 0000000..7bcfa60
--- /dev/null
+++ b/test/CodeGen/libcalls-complex.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fno-builtin -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix YES %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix NO %s
+
+extern float crealf(float _Complex);
+extern double creal(double _Complex);
+extern long double creall(long double _Complex);
+
+extern float cimagf(float _Complex);
+extern double cimag(double _Complex);
+extern long double cimagl(long double _Complex);
+
+double test_creal(double _Complex z) {
+  return creal(z);
+  // CHECK-NO-NOT: call double @creal
+  // CHECK-YES: call double @creal
+}
+
+long double test_creall(double _Complex z) {
+  return creall(z);
+  // CHECK-NO-NOT: call x86_fp80 @creall
+  // CHECK-YES: call x86_fp80 @creall
+}
+
+float test_crealf(double _Complex z) {
+  return crealf(z);
+  // CHECK-NO-NOT: call float @crealf
+  // CHECK-YES: call float @crealf
+}
+
+double test_cimag(double _Complex z) {
+  return cimag(z);
+  // CHECK-NO-NOT: call double @cimag
+  // CHECK-YES: call double @cimag
+}
+
+long double test_cimagl(double _Complex z) {
+  return cimagl(z);
+  // CHECK-NO-NOT: call x86_fp80 @cimagl
+  // CHECK-YES: call x86_fp80 @cimagl
+}
+
+float test_cimagf(double _Complex z) {
+  return cimagf(z);
+  // CHECK-NO-NOT: call float @cimagf
+  // CHECK-YES: call float @cimagf
+}
-- 
1.7.10.2 (Apple Git-33)




More information about the cfe-commits mailing list